Advertisement

Is per-ref-object user data possible?

Started by September 05, 2014 04:48 AM
3 comments, last by WitchLord 10 years, 2 months ago

Am I correct in assuming that the asIObjectType user data is per-type and not per-object? Is it possible to somehow register per-object user data?

I register all my application (ref) types as nocount ones like so:

RegisterObjectType("MyObj", 0, asOBJ_REF | asOBJ_NOCOUNT);

Sometimes users run into object lifetime issues where the underlying C++ object (e.g. a MyObj instance) has gone away, but a script is still holding on to a handle to it and attempting to call (C++) member functions through that (now-stale) pointer crashes the application. If I had some way to append a user data to every instance of a script handle to an application-registered ref object.. I might be able to do some debug checking to ensure that the handle isn't a stale one.

Have you heard of any users doing something similar? Do you have any suggestions for managing object lifetimes when the ref types can't be reference counted?

Thank you very much.

For the lifetime issues, check the weak reference functionality and the weakref add-on. These allow you to implement a shared flag which tells if the object has already been destroyed. The example in the first link describes a normal reference counted object, but I'd believe (not 100% sure though) the concept should also be possible for NOCOUNT objects.

http://www.angelcode.com/angelscript/sdk/docs/manual/doc_adv_weakref.html

http://www.angelcode.com/angelscript/sdk/docs/manual/doc_addon_weakref.html

Advertisement

asOBJ_NOCOUNT is difficult to use for objects that do not have a very precisely known lifetime, for the very reason that you discovered.

Adding user data to handles is not supported in AngelScript. But, you could register the type without the asOBJ_NOCOUNT and register the asBEHAVE_ADDREF and asBEHAVE_RELEASE behaviours as global functions (with asOBJ_CDECL_OBJLAST). These functions could then store a ref count in a map where the object pointer is the key.

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

Wouldn't removing asOBJ_NOCOUNT allow script to attempt to instantiate these objects? I'd need to prohibit that - these objects already exist and I just want script to be able to manipulate them. Also, by storing the refcount per object pointer, I'd have no way of knowing that C++ (outside the script) destroyed the object. The only thing I can think to do with the global map is to assert (when C++ is attempting to destroy the object) that the object's pointer isn't in the map.. as a means of warning the user that they have an object lifetime problem. Is that what you were thinking?

Thanks

No. AngelScript will only be able to instantiate the objects if you provide the factory functions for that (asBEHAVE_FACTORY).

You're correct, having the asBEHAVE_ADDREF/RELEASE behaviors will not prevent C++ from destroying the object from the application side. It will only allow AngelScript to tell the application how many references that the script engine still holds to the object so that you will have a chance of avoiding the destruction of the object from the application side until all references from AngelScript are released.

If you really cannot control the lifetime of the objects in the application, i.e. not destroying them, then you should probably avoid exposing the objects to the script all together, and instead have the scripts work through an abstraction layer (i.e. wrappers) where the abstraction layer can verify if the object is still alive before attempting to access 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