Jump to content
  • Advertisement
Sign in to follow this  
gjl

Automatic reference counting for application objects

This topic is 920 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

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
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.

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

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

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
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!