|
|
@@ -12,6 +12,10 @@ namespace BansheeEngine
|
|
|
{
|
|
|
struct ScriptObjectBackup;
|
|
|
|
|
|
+ /**
|
|
|
+ * @brief Helper class to initialize all script interop objects
|
|
|
+ * as soon as the library is loaded.
|
|
|
+ */
|
|
|
template <class Type, class Base>
|
|
|
struct InitScriptObjectOnStart
|
|
|
{
|
|
|
@@ -20,41 +24,83 @@ namespace BansheeEngine
|
|
|
{
|
|
|
ScriptObject<Type, Base>::_initMetaData();
|
|
|
}
|
|
|
-
|
|
|
- void makeSureIAmInstantiated() { }
|
|
|
};
|
|
|
|
|
|
+ /**
|
|
|
+ * @brief Base class for all script interop objects. Interop
|
|
|
+ * objects form a connection between C++ and CLR classes
|
|
|
+ * and methods.
|
|
|
+ */
|
|
|
class BS_SCR_BE_EXPORT ScriptObjectBase
|
|
|
{
|
|
|
public:
|
|
|
ScriptObjectBase(MonoObject* instance);
|
|
|
virtual ~ScriptObjectBase();
|
|
|
|
|
|
+ /**
|
|
|
+ * @brief Gets the managed object this interop object represents.
|
|
|
+ */
|
|
|
MonoObject* getManagedInstance() const { return mManagedInstance; }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @brief Should the interop object persist through assembly reload.
|
|
|
+ * If false then the interop object will be destroyed on reload.
|
|
|
+ */
|
|
|
virtual bool isPersistent() const { return false; }
|
|
|
|
|
|
+ /**
|
|
|
+ * @brief Clears any managed instance references from the interop object.
|
|
|
+ * Normally called right after the assemblies are unloaded.
|
|
|
+ */
|
|
|
virtual void _clearManagedInstance() { }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @brief Allows persistent objects to restore their managed instances after
|
|
|
+ * assembly reload.
|
|
|
+ */
|
|
|
virtual void _restoreManagedInstance() { }
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @brief Called when the managed instance gets destroyed. Usually
|
|
|
+ * triggered by the runtime when the finalizer is called.
|
|
|
+ */
|
|
|
virtual void _onManagedInstanceDeleted();
|
|
|
|
|
|
+ /**
|
|
|
+ * @brief Called before assembly reload starts to give the object a chance to
|
|
|
+ * back up its data.
|
|
|
+ */
|
|
|
virtual ScriptObjectBackup beginRefresh();
|
|
|
+
|
|
|
+ /**
|
|
|
+ * @brief Called after assembly reload starts to give the object a chance
|
|
|
+ * to restore the data backed up by the previous ::beginRefresh call.
|
|
|
+ */
|
|
|
virtual void endRefresh(const ScriptObjectBackup& data);
|
|
|
|
|
|
protected:
|
|
|
MonoObject* mManagedInstance;
|
|
|
};
|
|
|
|
|
|
+ /**
|
|
|
+ * @brief Base class for all persistent interop objects. Persistent objects
|
|
|
+ * persist through assembly reload.
|
|
|
+ */
|
|
|
class BS_SCR_BE_EXPORT PersistentScriptObjectBase : public ScriptObjectBase
|
|
|
{
|
|
|
public:
|
|
|
PersistentScriptObjectBase(MonoObject* instance);
|
|
|
virtual ~PersistentScriptObjectBase();
|
|
|
|
|
|
+ /**
|
|
|
+ * @copydoc ScriptObjectBase::isPersistent
|
|
|
+ */
|
|
|
virtual bool isPersistent() const override { return true; }
|
|
|
};
|
|
|
|
|
|
/**
|
|
|
- * @brief Base class for objects that can be extended using Mono scripting
|
|
|
+ * @brief Template version of ScriptObjectBase populates the object
|
|
|
+ * meta-data on library load.
|
|
|
*/
|
|
|
template <class Type, class Base = ScriptObjectBase>
|
|
|
class ScriptObject : public Base
|
|
|
@@ -78,6 +124,9 @@ namespace BansheeEngine
|
|
|
virtual ~ScriptObject()
|
|
|
{ }
|
|
|
|
|
|
+ /**
|
|
|
+ * @copydoc ScriptObjectBase::_clearManagedInstance
|
|
|
+ */
|
|
|
void _clearManagedInstance()
|
|
|
{
|
|
|
if (metaData.thisPtrField != nullptr && mManagedInstance != nullptr)
|
|
|
@@ -86,6 +135,9 @@ namespace BansheeEngine
|
|
|
mManagedInstance = nullptr;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * @copydoc ScriptObjectBase::_restoreManagedInstance
|
|
|
+ */
|
|
|
void _restoreManagedInstance()
|
|
|
{
|
|
|
mManagedInstance = _createManagedInstance(true);
|
|
|
@@ -96,11 +148,19 @@ namespace BansheeEngine
|
|
|
metaData.thisPtrField->setValue(mManagedInstance, ¶m);
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * @brief Creates a new managed instance of the type wrapped
|
|
|
+ * by this interop object.
|
|
|
+ */
|
|
|
virtual MonoObject* _createManagedInstance(bool construct)
|
|
|
{
|
|
|
return metaData.scriptClass->createInstance(construct);
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * @brief Converts a managed instance into a specific interop object.
|
|
|
+ * Caller must ensure the managed instance is of the proper type.
|
|
|
+ */
|
|
|
static Type* toNative(MonoObject* managedInstance)
|
|
|
{
|
|
|
Type* nativeInstance = nullptr;
|
|
|
@@ -111,8 +171,16 @@ namespace BansheeEngine
|
|
|
return nativeInstance;
|
|
|
}
|
|
|
|
|
|
+ /**
|
|
|
+ * @brief Returns the meta-data containing class and method information
|
|
|
+ * for the managed type.
|
|
|
+ */
|
|
|
static const ScriptMeta* getMetaData() { return &metaData; }
|
|
|
|
|
|
+ /**
|
|
|
+ * @brief Initializes the meta-data containing class and method information
|
|
|
+ * for the managed type. Called on library load and on assembly reload.
|
|
|
+ */
|
|
|
static void _initMetaData()
|
|
|
{
|
|
|
metaData = ScriptMeta(Type::getAssemblyName(), Type::getNamespace(), Type::getTypeName(), &Type::initRuntimeData);
|
|
|
@@ -124,15 +192,18 @@ namespace BansheeEngine
|
|
|
static ScriptMeta metaData;
|
|
|
|
|
|
private:
|
|
|
- static InitScriptObjectOnStart<Type, Base> initOnStart;
|
|
|
+ static volatile InitScriptObjectOnStart<Type, Base> initOnStart;
|
|
|
};
|
|
|
|
|
|
template <typename Type, typename Base>
|
|
|
- InitScriptObjectOnStart<Type, Base> ScriptObject<Type, Base>::initOnStart;
|
|
|
+ volatile InitScriptObjectOnStart<Type, Base> ScriptObject<Type, Base>::initOnStart;
|
|
|
|
|
|
template <typename Type, typename Base>
|
|
|
ScriptMeta ScriptObject<Type, Base>::metaData;
|
|
|
|
|
|
+ /**
|
|
|
+ * @brief Contains backed up interop object data.
|
|
|
+ */
|
|
|
struct ScriptObjectBackup
|
|
|
{
|
|
|
Any data;
|