Sign in to follow this  
gjl

Automatic reference counting for application objects

Recommended Posts

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.

 

 

 

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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!

Share this post


Link to post
Share on other sites

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)

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this