I have a problem creating the new orxObject instance without using the config.
I'm calling orxObject_Create() adding some structures to it and everything is fine. But when I try to pick the object with orxObject_Pick(), object is never picked.
So I debugged the orxObject_CreateFromConfig() and have noticed that at the end, it set the orxOBJECT_KU32_FLAG_2D as new flag for the object. So I've tried to set the orxOBJECT_KU32_FLAG_2D value (because it is private) flag to my object and everything is working right, now.
My question is, what is this flag doing? Can I somehow set it using API without using some internal constants (orxOBJECT_KU32_FLAG_2D)?
Thank You
Comments
Out of curiosity, why do you prefer to use the non _FromConfig version? If you link additional structures to it, you'll be responsible for not only unlinking them but also deleting them (and handling object hierarchies gets also a bit more annoying than simply using a ChildList).
That being said, it's not a bad practice, I was just curious.
I'm using non-_FromConfig() version because sometimes I have some predefined "graphic"s and I don't know which one will be used by the given objects. So I'm dynamically creating the object and all the structures need. Maybe I could define some default object in config and use it as a "template" in the code.
I didn't know that I'm responsible also for unlinking and deleting them. I was under impression that when the structure is linked, it will be managed by the object.
edit: Could you point me to some source which could explain better when the structure needs to be managed explicitly and when not?
When an orxGRAPHIC is created from within an orxObject_CreateFromConfig() call, it means the orxObject code is also in charge of deleting that orxGRAPHIC when not needed.
If you manually create an orxGRAPHIC, even if you link it to an orxOBJECT, you'll still be in charge of its deletion (note that the unlink will be done automatically, however the orxGRAPHIC will still exist).
From the top of my head, the only place where this rule can be bent is in when you transfer object ownership (orxObject_SetOwner()). An orxOBJECT which owns other orxOBJECTs will delete them upon its own deletion.
Small example:
Note that when using the config property key ChildList, created sub-objets will both be parth of the 3D hierarchy of the parent at well as being owned by it. Example:
Config:
Code:
As a side note, if you're doing something like:
You can do something equivalent using the config but that won't require any bookkeeping on your side:
Config:
You can then have, in code:
Cheers,
iarwain
Are the object created with orxObject_CreateFromConfig() also automatically managed (I don't need to explicitly delete then if don't need to manage their lifetime)?
That make sense.
Ok
So when doing something like: Then if "O" is managed, and is destroyed, I would need to destroy the "G" explicitly. On other hand, if I would use I wouldn't need to destroy "G", or would I?
But when I modify the "Graphic" value in the config and then somewhere else I would try to create "O" object, it will have the associated graphics set in PushSection()/PopSection(), am I right? Could I somehow cancel the changes made to config in the last PushSection()/PopSection() operation?
Thanks
If you issued the create call yourself (no matter if it's from config or plain), you're responsible of issuing the delete one as well. If you want to keep them forever, it's possible, but it's your decision.
orx will collect every allocated resources when shutting down in the end.
There are two exceptions to this (for objects only):
- change of ownership (as illustrated earlier in this thread)
- explicit LifeTime set on the object (either through config or by calling orxObject_SetLifeTime())
The life time can be seen as a delayed delete.
Lemme know if this doesn't answer your question as I'm not 100% sure what you mean by "need to manage their lifetime".
When "O" is deleted (you have to call it yourself as you're the one who created it, unless you change its owner or if there's a LifeTime involved), G will still exist as you're the one who created it.
All is built on a symmetry model: the code which created something is responsible to delete it as well. Both Create() and CreateFromConfig() behave the same way with respect to ownership, so the above example will end up with the graphic still existing after "O" is deleted.
You're totally correct. That's why you'd use O as a template here, not as a fully ready object.
If you want to create a template from an existing section within altering the section, you have a couple of ways to do it:
- Backup the value before changing it, then restore it:
- Create a new section inheriting from the model, this way you won't alter the model at all:
Ok, understand.
Understood.
One more question
The second method could possibly solve the problem I have described above. But I would need to delete the "Template" section after the object creation to drop all changes to the "Template". Am I right?
Are these two, orxGraphic_Delete(orxGRAPHIC *_pstGraphic) and orxStructure_Delete (void *_pStructure), equivalent when using orxGRAPHIC as argument? Or is there some difference?
My pleasure!
Yes, you're right: you can always use orxObject_SetLifeTime(obj, orxFLOAT_0) in all cases.
There isn't any real caveat unless you expect your object to be deleted right away: with a lifetime set to 0, the object will get deleted next time it's updated, which could either be in the current frame or the next one, depending where in the frame processing you are currently at.
The other thing to keep in mind is that an object will only get deleted when its LifeTime is <= 0 if it's enabled. If the object is disabled, it'll only get deleted when it's re-enabled again.
You can always call both SetLifeTime(orxFLOAT_0) and Enable(orxTRUE) to cover 100% cases.
There isn't any direct mechanism to restore previous values (beside calling orxConfig_Reload() that would reload things from disk but still miss any subsequent runtime changes), however you can generalize the backup by storing all the values for all the keys in the section (there are functions that allow one to go through them). However, as you already know, I wouldn't recommend this approach as the inheritance-based one is much easier and yields better performance.
You're entirely right: orxConfig_ClearSection("Template") is what you need. The section would be recreated by the next call to orxConfig_PushSection() or orxConfig_SetParent().
There is a difference. Basically, if a structure is created by one API, it needs to be deleted by the same API. In your case, calling orxStructure_Delete on the graphic would only delete the base part of it but not the graphic-related part (for example if graphic created a texture, that texture would be dangling).
In the future I could add more "virtual" functions to structures (right now I only track the update one), but for now you need to call the same API for creation and deletion. You can get the type of a structure (orxStructure_GetID()) if you need to implement a switch/case to create a "generic" deletion method.
Note: orxStructure_GetID() is not to be confused with orxStrucure_GetGUID() which retrieves a GUID that can act as a "safe pointer".
If this helps any, I have never found any real need for a delete function during any game situation. Perhaps others might, But so far, every situation setting a lifetime of 0 has been the safest and best way to remove an object entirely.
and the last question
The event you should look for is the one with orxEVENT_TYPE_OBJECT type and orxOBJECT_EVENT_DELETE id. You can take a look here for some more info:
https://forum.orx-project.org/discussion/6762#Comment_6764
Also, you can compile it on linux and run your code on valgrind, it will show you all the memory errors your program has (including memory leaks).
Also I don't think that valgrind will report any leaks, because AFAIK memory would be clean-up before the process exit (by the orx).
I don't really know if you can watch for a particular struct being destroyed, maybe something on the profiller can help you with that.
If I had to implement it, I would add a global counter of objects I created and one of objects destroyed (using the event handler I mentioned), then I would create a function to log those info and bind it to a clock with a 5 seconds timer and check the data.
So I was referring to the memory leaks on orx boundary. And as it looks orx is managing all the stuff (structures, objects, ...) and should now which objects, structures etc are still referenced upon exit. So the information should be there.
I Appreciate the info you provided, but I would rather used some solution integrated in orx
edit: I should rather use term resource leak rather than memory leak to avoid confusion.
In the meantime, if you want to check for "leaked" structures, in your exit function you can go through all the collections, they should all be empty. Something like:
Another ones are the bult-in structures.
For now, the only option would be to check for orxObject_GetLifeTime() == orxFLOAT_0 to rule out those false positives, and discard their owned children as well, or, more likely, to start with the current object and go back up looping with orxObject_GetOwner() till you either reach orxNULL (leak) or an object with a lifetime == orxFLOAT_0 (false positive).
Not the cleanest approach but for now that should work.
I'm cleaning all my objects in the update function (not the timer udate, but the one specified in orx_Execute()) when I'm going to quit the application. Then it looks like the next frame is still executed so it also clean up object awaiting for deletion. But it still founds some built-in objects. If they could be marked somehow as internal, I could then test for this flag and rule them out. Are there some flag for this purpose already?
I do think your solution is more robust.
There can be some extra structures (such as the root frame, which is internally created) or the one that have been required to remain in memory (attribute KeepInCache).
Marking those could be an option, you can open an issue on bitbucket for this and assign it to me if you will.
All of this IIRC are destoryed *after* my exit() routine. I've created the ticket #69 for it.
Thanks for your help
Well, I guess the easiest would be for me to add a switch for orx to generate a resource leak log then, what do you think?
The thing is that, when checking within orx, I can check in many different places, where all the internally created structures have already been removed.
Yes, that would be better. I have also stated it in the ticket I created.