Handling the deletion of an object in C++ in Angelscript

Started by
5 comments, last by Solokiller 9 years, 6 months ago

We have a class in C++ that doesn't use reference counting.

This class is exposed to Angelscript as asOBJ_REF | asOBJ_NOCOUNT, and can be stored with handles.

If the object is deleted in C++, is there any way to make the handles in Angelscript become null automatically?

Advertisement

There is no easy way to do that at the moment, it would also not be very quick trying to enumerate over all possible variables and objects where a handle to the object might exist.

Do you really have to delete the object while there are still live scripts? Or can you delay the delete until you are certain all the scripts are completed and unloaded so you're guaranteed that no handles to the object exists?

If you absolutely have to be able to delete the object at any time, then you should probably consider using a form of weak reference to it, i.e. don't expose the real object, but instead expose a proxy that can detect when the object has been deleted and do the appropriate action when the script attempts to access it (either throw an exception, or simply do nothing).

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 is exactly how I do it, regardless of AS.

I have an ObserverPtr for all entities which essentially has an isValid() method.

The object is being deleted by the game engine, there is no way to avoid that. I considered iterating over all the variables, but i know that's expensive.

We have an object type (EHandle) that stores handles to these objects and can tell when it has been deleted, the only problem is that script writers might stores handles to the object themselves.
I don't suppose there's any way to disallow the usage of handles to reference types in certain situations? Though, even if it were possible to disable storage of handles in non-local variables, we use member variable handles in certain situations where we control the lifetime of the class that stores them.

All we can realistically do is encourage the use of the EHandle type, if writers use raw handles and the game crashes, there's nothing we can do.

If you are registering the object type itself as a asOBJ_REF then it is difficult to prevent the scripts from using the raw handle and eventually storing it in some place that you may not consider before deleting it from the C++ application.

You might be able to register it with asOBJ_REF | asOBJ_NOHANDLE. With this the scripts wouldn't able to create or use any handles to the object. The scripts would only be able to access the object through references provided by the application, e.g. through a registered global property, or a reference returned by a function.

Another option would be to restrict global variables in the scripts so you can be certain that no handles to the object can be stored in the global variables. The engine property asEP_DISALLOW_GLOBAL_VARS disables global variables all together. With a little more work from your side, you can allow global variables but give a compiler error in case the script tries to declare a global variable that could potentially store a handle to the object type. To implement this you would have to enumerate all the global variables after the script compilation and look for anything that could store the object type (either directly or indirectly).

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

See http://www.gamedev.net/topic/660614-is-per-ref-object-user-data-possible/ where Andreas suggests keeping a global map<c++-object-exposed-to-script, refCount> such that when the C++ object is about to be deleted, you might at least assert or do something if you know that a script somewhere is still referencing it.

We're going to go for the use of an indirect handle, and a check to prevent global variables from storing the handle. Thanks for helping out.

This topic is closed to new replies.

Advertisement