🎉 Celebrating 25 Years of GameDev.net! 🎉

Not many can claim 25 years on the Internet! Join us in celebrating this milestone. Learn more about our history, and thank you for being a part of our community!

CreateUninitializedScriptObject and postponing calling the constructor

Started by
3 comments, last by WitchLord 6 years, 2 months ago

I have specific need to initialize a script object but postpone calling constructor before I do some additional work. I want to do this because constructor may call some methods and use variables that may not be yet initialized, because they're set from outside the script. What will be set depends on some meta info etc. so I basically want to do some work and then call the usual constructor.

I found that CreateUninitializedScriptObject does exactly what I need and looks like it works well, but I don't know how should I then call the constructor so it only executes what's in constructor's body and not create a new object? The factory function I retrieved would create new object when called right? Also how does that work with inheritance? If I'm using CreateUninitializedScriptObject on a Foo object and inheritance hierarchy is Foo < Bar < Baz, how can I make sure all constructors are called? Is it even possible when creating uninitialized object? In Serializable addon it's only used to restore object and it says there that calling constructor may have some side-effects, but it does not explicitly say it would create second object instance. 

So is it possible to call and how it behaves then? And if so - how do I retrieve the type for calling it, as I assume it would be different than factory func? 


Where are we and when are we and who are we?
How many people in how many places at how many times?
Advertisement

No, it wouldn't be possible to call the script class' constructor on the instance returned by CreateUnitializedScriptObject. 

CreateUnitializedScriptObject allocates the memory for all the members, so they can then have their values set by the serialization. 

Calling the constructor on the instance would cause these memory allocations to leak, since the constructor is not expecting them.

 

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

Makes sense, I was thinking maybe it's possible to call "method body" part of the constructor, so assuming that memory is initialized and it won't happen twice, just execute whatever script user provided in the ctor. Sometimes it may have some additional initialize stuff that should happen even if the object is deserialized (like kick off some timer maybe?) - if this skips constructor there is a chance it will fill the object with proper values, but something will not be triggered properly. 

This probably also means there are some edge cases where Serialize addon won't work fully with the object. I can't think of any reasonable case like this, but something in lines with:


class Foo
{
   float lifetime;

   Foo(float lifetime_)
   {
      lifetime = lifetime_;
      setTimeout(lifetime, "doDie");
   }

   void doDie()
   {
      deleteMe();
   }
}

My case is slightly different, it's about initializing from templates rather than by using the class directly, but it has a lot in common with serialization/deserialization. One solution that comes to mind that could work for both, my case and serialization, would be to have some designated init() method that's known to work properly for both situations. Then object initialized with constructor would call init() as would object which has been deserialized. And having a rule that constructor should really only initialize the members.

Another one, that would allow keeping constructors untouched, would be to have a special "post serialize" callback in the script and allow script to know when it was deserialized to properly "resume" object. 

Anyway thanks for explanation! I think from the documentation it wasn't clear if there is some way to call just the body of the constructor without it constructing another instance, now I know there isn't. Maybe worth stating that "constructor should not be called" as this will result in a wrong behaviour and there is no way to execute the body of the method itself, so there is no single reason to ever call ctor when using this way of initialization.


Where are we and when are we and who are we?
How many people in how many places at how many times?

Well, the constructor is not even available to be called from the application (it cannot be enumerated unless you do some tricky stuff to obtain it by iterating through the bytecode of the factory function, or customize the library to expose it). 

AngelCode.com - game development and more - Reference DB - game developer references
AngelScript - free scripting library - BMFont - free bitmap font generator - Tower - free puzzle game

This topic is closed to new replies.

Advertisement