🎉 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!

Automatic reference counting for application objects

Started by
3 comments, last by gjl 8 years, 2 months ago

Hi,

I am working on exposing an application interface that uses the factory pattern on a regular basis:


//Existing C++ Factory class
class ObjectFactory
{
public:
    Object* BuildObject();
}

Exposed as:


//Exposed Angelscript Factory class
class ObjectFactory
{
public:
    Object@ BuildObject();
} 

The issue is that the application does not implement reference counting, so all the "Object" instances do not have addref/release capabilities.

So far, it seems that the only way I can expose this to angelscript is to wrap both the factory and object classes into new classes that act as a proxy, just for reference counting, so that the built object can be properly destroyed when there is no more reference to it from the angelscript side. Is this correct, or have I missed an option to avoid this?

If it is not already available, what about implementing a specific option for type registration (something like asOBJ_AUTOREFCOUNT), so that the script engine does the reference counting for you and just calls a release function when refcount is 0? This would simplify wrapping a lot when the existing classes cannot be modified for reference counting.

Advertisement

If you can control the object life time without reference counting than you can register it with AngelScript using the flag asOBJ_NOCOUNT to tell AngelScript that the AddRef and Release behaviours aren't needed.

If you wish to implement reference counting for the object without modifying the class itself, you can do so by keeping track of the reference counter in a map, and then providing a couple of global functions for updating it, e.g:

std::unordered_map<Object*, size_t> refCounts;
void AddRef(Object *obj)
{
   refCounts[obj]++;
}
void Release(Object *obj)
{
   size_t r = refCounts[obj]--;
   if( r == 0 )
   {
     refCounts.erase(obj);
     delete obj;
   }
}

You'd use asCALL_CDECL_OBJLAST calling convention to register these as the asBEHAVE_ADDREF and asBEHAVE_RELEASE behaviours.

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

Thanks, that's indeed what I figured out. The problem with keeping a list of objects is that it requires extra locks and adds overheads to parse the table, that's why I thought it could be beneficial to have the extra refcount data stored into the engine directly, just like with script objects. But now that I think about it, it might not be as easy as it seems :-). So I will keep writing wrappers. It's not so bad after all!

If I were to implement this inside the engine, the map of objects to refCounts is exactly what I would have to implement anyway.

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

Woops, my bad: I forgot that native objects are not wrapped but used "as is" by the script engine... You can forget this feature request! :-)

Anyway, I ended up writing wrapper classes, which is not a big deal (not so many methods to wrap)

This topic is closed to new replies.

Advertisement