forwarding orxObject_Enable to all children

hey,
when I "preload" level of a game I create all needed objects and then disable then.

once the level should be played the desired objects will be enabled.
I have several objects that are defined using child lists. So if I create a object I would also like all the children to be disabled.


for this purpose I added to the end of the function orxObject_Enable the following:
/* also enable/disable all children */
  orxOBJECT *pstChild = orxObject_GetChild(_pstObject);
  while (pstChild != orxNULL)
  {
    orxObject_Enable(pstChild, _bEnable);
    pstChild = orxObject_GetSibling(pstChild);
  }
or is there a better way of iterating over all childs?

I'm writing this post because I would like to get this change included upstream.
so let me know what you think about it and if including it into orx would be ok.

Tobi

Comments

  • edited June 2011
    Mmh, with this code you will only have the first level children, not the whole hierarchy. :)

    As for having it in the default orxObject_Enable() function, I'd rather not, for two reasons:
    - this can be a very expensive call as it's complexity would be at best O(N x Mlog(M)), with N the total number of objects and M the number of objects in your hierarchy.
    - that means that orxObject_Enable() won't be doing anymore what the function's name advertise. orxObject_* functions only alter the current object, never regarding its hierarchy.

    I think the place for such a function would be in a mid-level layer, such as Scroll for example (actually I already have a bunch of such wrappers spreading on an object's hierarchy in Scroll for SetAnim, SetColor, etc...).

    In your particular case, maybe the cost isn't too much of a concern but if it is, you can try different strategies.
    One would be to listen to the orxOBJECT_EVENT_CREATE received during the call to orxObject_CreateFromConfig() on the parent, then disable those objects and store them in a list that you'd use for activating them later on.

    What do you think?
  • edited June 2011
    I think I only have hiearchies with a depth of 1. I'm wondering, why it wouldn't recursively walk through any kind of hiearchy, though?

    ok you're right about being consistent. as the other methods don't apply to the whole hierarchy this shouldn't either.

    btw, why does an object not store direct references to it's children, but rather search through all the objects?
  • edited June 2011
    tdomhan wrote:
    I think I only have hiearchies with a depth of 1. I'm wondering, why it wouldn't recursively walk through any kind of hiearchy, though?

    You're only calling orxObject_GetSibling() on the children of the 1st depth. You need to call orxObject_GetChild() on them to go one level deeper.
    ok you're right about being consistent. as the other methods don't apply to the whole hierarchy this shouldn't either.

    btw, why does an object not store direct references to it's children, but rather search through all the objects?

    When I added that feature, I didn't think it'd turn to be as useful (and used) as it is and I didn't want to "waste" 8 additional bytes per object.
    I'll reconsider that very soon and will probably change it. :)
  • edited June 2011
    iarwain wrote:
    tdomhan wrote:
    I think I only have hiearchies with a depth of 1. I'm wondering, why it wouldn't recursively walk through any kind of hiearchy, though?

    You're only calling orxObject_GetSibling() on the children of the 1st depth. You need to call orxObject_GetChild() on them to go one level deeper.
    mhh orxObject_Enable will be called for all each child. the child in turn query for it's own children and call orxObject_Enable on them. this will go on until there are objects having no further children. or what am I missing here? :)
    ok you're right about being consistent. as the other methods don't apply to the whole hierarchy this shouldn't either.

    btw, why does an object not store direct references to it's children, but rather search through all the objects?

    When I added that feature, I didn't think it'd turn to be as useful (and used) as it is and I didn't want to "waste" 8 additional bytes per object.
    I'll reconsider that very soon and will probably change it.
    :)
    ok that would be quite useful :D
  • edited June 2011
    tdomhan wrote:
    mhh orxObject_Enable will be called for all each child. the child in turn query for it's own children and call orxObject_Enable on them. this will go on until there are objects having no further children. or what am I missing here? :)

    My bad, I read too fast. ^^
    I thought that was the implementation of the hierarchical version (something like orxObject_EnableHierarchy() which would then call the current version of orxObject_Enable() on its children). Well, then adding the recursion to the existing complexity makes it even slightly less efficient. ;)
    ok that would be quite useful :D

    Will do before the end of the week. :)
  • edited June 2011
    Done! =)
  • edited June 2011
    I read the code you changed in orxObject.c .
    It will be easier and faster to get the children of an Object when the create from config
    but when I add an parent to an Object in the code(or in the runtime), object would not be got when I get children in the new parent object by calling orxObject_GetChild();

    is it possible to add this feature, it is important to my game...

    and hope this could work in orxObject_SetOwner

    if (orxStructure_GetID(_pOwner) == orxSTRUCTURE_ID_OBJECT){
    orxOBJECT* pTempObj = orxOBJECT(_pOwner);
    if (pTempObj->pstChild == NULL){
    //add it and set the test flag
    pTempObj->pstChild = _pstObject;
    }else{
    //find a null silbiling
    while(pTempObj->pstSibling){
    pTempObj = pTempObj->pstSibling;
    }
    pTempObj->pstSibling = _pstObject;
    }
    }
  • edited June 2011
    Mmh, I thought I already explained that part to you, but I might be mistaking and it might be someone else, and even if it were the case, it's still good for everyone to know, so here we go again. =)

    There's some confusion due to names here, the orxObject_SetParent() is for frame hierarchy parenting, which is not the same at all than having a ChildList or accessing children with orxObject_GetChild()/_GetSibling().
    You can actually have an object A that has a child B but is not its parent in the sense of orxObject_SetParent(). B can have a camera C as frame parent. I totally agree that the names are very confusing but I'm not sure which one to use and if it's not too late to fix it.

    Also what is your intent with using orxObject_SetOwner()?
    I added that as a simple way to link spawners and objects. You can use it for your own purpose but there's no automated behavior linked to it (except for the spawner/object relationship). There's no hierarchy either. I'm not sure what you are using it for, just being curious here. :)

    All in all, when you do a orxObject_SetParent() in code, there's no easy way to retrieve its parent later on, due to how the frame are linked with other structures: a parent can be something else than an object and there's no mandatory 1-to-1 relationship between a frame and an object.

    This can be changed in the future, but as long as it's like this you can't have an easy orxObject_GetParent().
    The only way to code one for now would be to get your object's frame, get its parent, go through all the objects, get their frames till you find the matching one. If you find it, it's your parent. If not, your parent might be a camera or a spawner, for example.

    So, to sum it up, the important part is that orxObject_SetParent() and orxObject_GetChild()/_GetSibling() are *not* linked.

    I'd recommend storing the hierarchy in your own object structure that you then feed to orx with orxObject_SetUserData().
  • edited June 2011
    yes you have explained to me. and I have reviewed your reply. I understood the concepts under orxObject_SetParent and orxObject_SetOwner. the later one now is only used for link spawner and object
    well in my game I need to change one or more objects contained in a parent object. for example, when I touch the object, some objects will be changed form one to another. and when they are removed, they will be removed with their parent object.
    therefore, I require to set parent object in runtime.
    I know it could be realized out of the game engine, but I feel it is more complicated and it will be used frequently.
    I think orxObject_SetParent could remain unchanged while set owner will be attached to more features. like the code I posted, you could judge whether the structure is orxSTRUCTURE_ID_OBJECT, then add object to pstChild.
    when set an object to a parent, the code is like:
    orxOBJECT_SetParent(pstObject); //set the frame hierachy
    orxOBJECT_SetOwner(pstObject);

    if it changed like this, what problems would have? may be some parts of the game engine are not considered by me.

    thanks for your patience.
  • edited June 2011
    mmh one problem it will have is two child objects may have the same name.
    for example:
    at first it has a child object loaded from config and named A
    while I add an object which also create from section A to the same parent in the runtime.
  • edited June 2011
    Your proposal sounds legimitate to me and I'm not sure to understand what the problem you mentioned actually is.

    So as to clear everything up and so that I can understand what you need fully before implementing it, right now you simply want to replace objects on-the-fly in an object's children list so that the new object would be automatically deleted when the parent is deleted or did I miss something?
  • edited June 2011
    I have noticed your changes in svn.
    Thanks for your work about setting new owner.

    with the changes, I believe one of bugs in my game will be easy to solve.
  • edited June 2011
    Ahah, you're faster than me, I planned on posting here during lunch time. :)

    Glad it helps, let me know if you have any trouble with it as I didn't extensively test it.
  • edited June 2011
    so is there a way of setting the frame hierarchy somehow in the config files?

    becaue orxObject_SetParent is exactly what I could need.

    and yeah the naming is causing some confusion. at least for me. ;)
  • edited June 2011
    Well, ChildList will both set frame hierarchy and object ownership.

    ParentCamera also set the frame hierarchy with Camera parent of the created object/camera.

    Lastly, the Spawner config property UseSelfAsParent will create a frame hierarchy with all the spawned objects as children of the spawner.

    In the case of the spawner, ownership will also be done (in a similar way than with ChildList on objects) but can be negated with the property CleanOnDelete=false.

    To sum it up, you can't have the frame hierarchy without the ownership in config (but you can have the opposite to some extent). Is that what you need? :)
Sign In or Register to comment.