Refactor native core objects to simplify usage for newcomers

This commit is contained in:
Wojtek Figat
2022-01-07 13:16:36 +01:00
parent e144a6f69d
commit 192af7ec14
47 changed files with 204 additions and 249 deletions

View File

@@ -131,7 +131,7 @@ extern FLAXENGINE_API const Char* ToString(const BuildConfiguration configuratio
/// <summary>
/// Game cooking temporary data.
/// </summary>
API_CLASS(Sealed, Namespace="FlaxEditor") class FLAXENGINE_API CookingData : public PersistentScriptingObject
API_CLASS(Sealed, Namespace="FlaxEditor") class FLAXENGINE_API CookingData : public ScriptingObject
{
DECLARE_SCRIPTING_TYPE(CookingData);
public:

View File

@@ -164,7 +164,7 @@ CookingData::Statistics::Statistics()
}
CookingData::CookingData(const SpawnParams& params)
: PersistentScriptingObject(params)
: ScriptingObject(params)
{
}

View File

@@ -140,7 +140,7 @@ void OnVisualScriptingDebugFlow()
void OnLogMessage(LogType type, const StringView& msg);
ManagedEditor::ManagedEditor()
: PersistentScriptingObject(SpawnParams(ObjectID, ManagedEditor::TypeInitializer))
: ScriptingObject(SpawnParams(ObjectID, ManagedEditor::TypeInitializer))
{
// Link events
auto editor = ((NativeBinaryModule*)GetBinaryModuleFlaxEngine())->Assembly;
@@ -494,5 +494,5 @@ void ManagedEditor::DestroyManaged()
Internal_OnVisualScriptingDebugFlow = nullptr;
// Base
PersistentScriptingObject::DestroyManaged();
ScriptingObject::DestroyManaged();
}

View File

@@ -14,7 +14,7 @@ namespace CSG
/// <summary>
/// Managed Editor root object
/// </summary>
class ManagedEditor : public PersistentScriptingObject
class ManagedEditor : public ScriptingObject
{
DECLARE_SCRIPTING_TYPE_NO_SPAWN(ManagedEditor);
@@ -144,6 +144,6 @@ private:
public:
// [PersistentScriptingObject]
// [ScriptingObject]
void DestroyManaged() override;
};

View File

@@ -7,17 +7,17 @@
/// <summary>
/// Represents a single audio device.
/// </summary>
API_CLASS(NoSpawn) class AudioDevice : public PersistentScriptingObject
API_CLASS(NoSpawn) class AudioDevice : public ScriptingObject
{
DECLARE_SCRIPTING_TYPE_NO_SPAWN(AudioDevice);
explicit AudioDevice()
: PersistentScriptingObject(SpawnParams(Guid::New(), TypeInitializer))
: ScriptingObject(SpawnParams(Guid::New(), TypeInitializer))
{
}
AudioDevice(const AudioDevice& other)
: PersistentScriptingObject(SpawnParams(Guid::New(), TypeInitializer))
: ScriptingObject(SpawnParams(Guid::New(), TypeInitializer))
{
Name = other.Name;
InternalName = other.InternalName;

View File

@@ -1,25 +0,0 @@
// Copyright (c) 2012-2021 Wojciech Figat. All rights reserved.
#include "Object.h"
#include "ObjectsRemovalService.h"
RemovableObject::~RemovableObject()
{
#if BUILD_DEBUG
// Prevent removing object that is still reverenced by the removal service
ASSERT(!ObjectsRemovalService::IsInPool(this));
#endif
}
void RemovableObject::DeleteObjectNow()
{
ObjectsRemovalService::Dereference(this);
OnDeleteObject();
}
void RemovableObject::DeleteObject(float timeToLive, bool useGameTime)
{
// Add to deferred remove (or just update timeout but don't remove object here)
ObjectsRemovalService::Add(this, timeToLive, useGameTime);
}

View File

@@ -37,30 +37,13 @@ public:
/// <summary>
/// Finalizes an instance of the <see cref="Object"/> class.
/// </summary>
virtual ~Object()
{
}
virtual ~Object();
/// <summary>
/// Gets the string representation of this object.
/// </summary>
/// <returns>The string.</returns>
virtual String ToString() const = 0;
};
/// <summary>
/// Interface for removable Engine objects.
/// </summary>
/// <seealso cref="Object" />
class FLAXENGINE_API RemovableObject : public Object
{
public:
/// <summary>
/// Virtual destructor but protected. Removable objects should be deleted using `DeleteObject` which supports deferred delete.
/// Note: it's unsafe to delete object using destructor it it has been marked for deferred delete.
/// </summary>
virtual ~RemovableObject();
/// <summary>
/// Deletes the object without queueing it to the ObjectsRemovalService.
@@ -68,7 +51,7 @@ public:
void DeleteObjectNow();
/// <summary>
/// Deletes the object.
/// Deletes the object (deferred).
/// </summary>
/// <param name="timeToLive">The time to live (in seconds). Use zero to kill it now.</param>
/// <param name="useGameTime">True if unscaled game time for the object life timeout, otherwise false to use absolute time.</param>
@@ -82,3 +65,6 @@ public:
Delete(this);
}
};
// [Deprecated on 5.01.2022, expires on 5.01.2024]
typedef Object RemovableObject;

View File

@@ -16,8 +16,8 @@ namespace ObjectsRemovalServiceImpl
CriticalSection NewItemsLocker;
DateTime LastUpdate;
float LastUpdateGameTime;
Dictionary<RemovableObject*, float> Pool(8192);
Dictionary<RemovableObject*, float> NewItemsPool(2048);
Dictionary<Object*, float> Pool(8192);
Dictionary<Object*, float> NewItemsPool(2048);
}
using namespace ObjectsRemovalServiceImpl;
@@ -38,7 +38,7 @@ public:
ObjectsRemovalServiceService ObjectsRemovalServiceServiceInstance;
bool ObjectsRemovalService::IsInPool(RemovableObject* obj)
bool ObjectsRemovalService::IsInPool(Object* obj)
{
if (!IsReady)
return false;
@@ -67,7 +67,7 @@ bool ObjectsRemovalService::HasNewItemsForFlush()
return result;
}
void ObjectsRemovalService::Dereference(RemovableObject* obj)
void ObjectsRemovalService::Dereference(Object* obj)
{
if (!IsReady)
return;
@@ -81,7 +81,7 @@ void ObjectsRemovalService::Dereference(RemovableObject* obj)
PoolLocker.Unlock();
}
void ObjectsRemovalService::Add(RemovableObject* obj, float timeToLive, bool useGameTime)
void ObjectsRemovalService::Add(Object* obj, float timeToLive, bool useGameTime)
{
ScopeLock lock(NewItemsLocker);
@@ -213,3 +213,24 @@ void ObjectsRemovalServiceService::Dispose()
IsReady = false;
}
Object::~Object()
{
#if BUILD_DEBUG
// Prevent removing object that is still reverenced by the removal service
ASSERT(!ObjectsRemovalService::IsInPool(this));
#endif
}
void Object::DeleteObjectNow()
{
ObjectsRemovalService::Dereference(this);
OnDeleteObject();
}
void Object::DeleteObject(float timeToLive, bool useGameTime)
{
// Add to deferred remove (or just update timeout but don't remove object here)
ObjectsRemovalService::Add(this, timeToLive, useGameTime);
}

View File

@@ -16,7 +16,7 @@ public:
/// </summary>
/// <param name="obj">The object.</param>
/// <returns>True if object has been registered in the pool for the removing, otherwise false.</returns>
static bool IsInPool(RemovableObject* obj);
static bool IsInPool(Object* obj);
/// <summary>
/// Determines whether any object has been registered to be removed from pool (requests are flushed on Flush call).
@@ -28,7 +28,7 @@ public:
/// Removes the specified object from the dead pool (clears the reference to it).
/// </summary>
/// <param name="obj">The object.</param>
static void Dereference(RemovableObject* obj);
static void Dereference(Object* obj);
/// <summary>
/// Adds the specified object to the dead pool.
@@ -36,7 +36,7 @@ public:
/// <param name="obj">The object.</param>
/// <param name="timeToLive">The time to live (in seconds).</param>
/// <param name="useGameTime">True if unscaled game time for the object life timeout, otherwise false to use absolute time.</param>
static void Add(RemovableObject* obj, float timeToLive = 1.0f, bool useGameTime = false);
static void Add(Object* obj, float timeToLive = 1.0f, bool useGameTime = false);
/// <summary>
/// Flushes the objects pool removing objects marked to remove now (with negative or zero time to live).

View File

@@ -7,7 +7,7 @@
#include "Foliage.h"
FoliageType::FoliageType()
: PersistentScriptingObject(SpawnParams(Guid::New(), TypeInitializer))
: ScriptingObject(SpawnParams(Guid::New(), TypeInitializer))
, Foliage(nullptr)
, Index(-1)
{

View File

@@ -41,7 +41,7 @@ API_ENUM() enum class FoliageScalingModes
/// <summary>
/// Foliage mesh instances type descriptor. Defines the shared properties of the spawned mesh instances.
/// </summary>
API_CLASS(Sealed, NoSpawn) class FLAXENGINE_API FoliageType : public PersistentScriptingObject, public ISerializable
API_CLASS(Sealed, NoSpawn) class FLAXENGINE_API FoliageType : public ScriptingObject, public ISerializable
{
DECLARE_SCRIPTING_TYPE_NO_SPAWN(FoliageType);
friend Foliage;

View File

@@ -13,13 +13,13 @@
/// <summary>
/// Interface for GPU device adapter.
/// </summary>
API_CLASS(NoSpawn, Attributes="HideInEditor") class FLAXENGINE_API GPUAdapter : public PersistentScriptingObject
API_CLASS(NoSpawn, Attributes="HideInEditor") class FLAXENGINE_API GPUAdapter : public ScriptingObject
{
DECLARE_SCRIPTING_TYPE_NO_SPAWN(GPUDevice);
public:
GPUAdapter()
: PersistentScriptingObject(SpawnParams(Guid::New(), TypeInitializer))
: ScriptingObject(SpawnParams(Guid::New(), TypeInitializer))
{
}

View File

@@ -6,7 +6,7 @@
#include "Textures/GPUTexture.h"
GPUContext::GPUContext(GPUDevice* device)
: PersistentScriptingObject(ScriptingObjectSpawnParams(Guid::New(), TypeInitializer))
: ScriptingObject(ScriptingObjectSpawnParams(Guid::New(), TypeInitializer))
, _device(device)
{
}

View File

@@ -113,7 +113,7 @@ DECLARE_SCRIPTING_TYPE_NO_SPAWN(GPUDrawIndexedIndirectArgs);
/// <summary>
/// Interface for GPU device context that can record and send graphics commands to the GPU in a sequence.
/// </summary>
API_CLASS(Sealed, NoSpawn) class FLAXENGINE_API GPUContext : public PersistentScriptingObject
API_CLASS(Sealed, NoSpawn) class FLAXENGINE_API GPUContext : public ScriptingObject
{
DECLARE_SCRIPTING_TYPE_NO_SPAWN(GPUContext);
private:

View File

@@ -173,12 +173,12 @@ GPUPipelineState::Description GPUPipelineState::Description::DefaultFullscreenTr
};
GPUResource::GPUResource()
: PersistentScriptingObject(SpawnParams(Guid::New(), GPUResource::TypeInitializer))
: ScriptingObject(SpawnParams(Guid::New(), GPUResource::TypeInitializer))
{
}
GPUResource::GPUResource(const SpawnParams& params)
: PersistentScriptingObject(params)
: ScriptingObject(params)
{
}
@@ -241,7 +241,7 @@ void GPUResource::OnDeleteObject()
{
ReleaseGPU();
PersistentScriptingObject::OnDeleteObject();
ScriptingObject::OnDeleteObject();
}
double GPUResourceView::DummyLastRenderTime = -1;
@@ -262,7 +262,7 @@ struct GPUDevice::PrivateData
GPUDevice* GPUDevice::Instance = nullptr;
GPUDevice::GPUDevice(RendererType type, ShaderProfile profile)
: PersistentScriptingObject(SpawnParams(Guid::New(), TypeInitializer))
: ScriptingObject(SpawnParams(Guid::New(), TypeInitializer))
, _state(DeviceState::Missing)
, _isRendering(false)
, _wasVSyncUsed(false)

View File

@@ -29,7 +29,7 @@ class MaterialBase;
/// <summary>
/// Graphics device object for rendering on GPU.
/// </summary>
API_CLASS(Sealed, NoSpawn) class FLAXENGINE_API GPUDevice : public PersistentScriptingObject
API_CLASS(Sealed, NoSpawn) class FLAXENGINE_API GPUDevice : public ScriptingObject
{
DECLARE_SCRIPTING_TYPE_NO_SPAWN(GPUDevice);
public:

View File

@@ -15,7 +15,7 @@
/// <summary>
/// The base class for all GPU resources.
/// </summary>
API_CLASS(Abstract, NoSpawn) class FLAXENGINE_API GPUResource : public PersistentScriptingObject
API_CLASS(Abstract, NoSpawn) class FLAXENGINE_API GPUResource : public ScriptingObject
{
DECLARE_SCRIPTING_TYPE_NO_SPAWN(GPUResource);
public:
@@ -108,7 +108,7 @@ protected:
public:
// [PersistentScriptingObject]
// [ScriptingObject]
String ToString() const override;
void OnDeleteObject() override;
};
@@ -186,14 +186,14 @@ public:
/// <summary>
/// Interface for GPU resources views. Shared base class for texture and buffer views.
/// </summary>
API_CLASS(Abstract, NoSpawn, Attributes="HideInEditor") class FLAXENGINE_API GPUResourceView : public PersistentScriptingObject
API_CLASS(Abstract, NoSpawn, Attributes="HideInEditor") class FLAXENGINE_API GPUResourceView : public ScriptingObject
{
DECLARE_SCRIPTING_TYPE_NO_SPAWN(GPUResourceView);
protected:
static double DummyLastRenderTime;
explicit GPUResourceView(const SpawnParams& params)
: PersistentScriptingObject(params)
: ScriptingObject(params)
, LastRenderTime(&DummyLastRenderTime)
{
}

View File

@@ -167,9 +167,9 @@ struct SerializedMaterialParam
/// <summary>
/// Material variable object. Allows to modify material parameter value at runtime.
/// </summary>
API_CLASS(NoSpawn) class FLAXENGINE_API MaterialParameter : public PersistentScriptingObject
API_CLASS(NoSpawn) class FLAXENGINE_API MaterialParameter : public ScriptingObject
{
DECLARE_SCRIPTING_TYPE_WITH_CONSTRUCTOR_IMPL(MaterialParameter, PersistentScriptingObject);
DECLARE_SCRIPTING_TYPE_WITH_CONSTRUCTOR_IMPL(MaterialParameter, ScriptingObject);
friend MaterialParams;
friend MaterialInstance;
private:

View File

@@ -10,9 +10,9 @@
/// <summary>
/// The material slot descriptor that specifies how to render geometry using it.
/// </summary>
API_CLASS(NoSpawn) class FLAXENGINE_API MaterialSlot : public PersistentScriptingObject
API_CLASS(NoSpawn) class FLAXENGINE_API MaterialSlot : public ScriptingObject
{
DECLARE_SCRIPTING_TYPE_WITH_CONSTRUCTOR_IMPL(MaterialSlot, PersistentScriptingObject);
DECLARE_SCRIPTING_TYPE_WITH_CONSTRUCTOR_IMPL(MaterialSlot, ScriptingObject);
/// <summary>
/// The material to use for rendering.

View File

@@ -14,7 +14,7 @@ class ModelBase;
/// <summary>
/// Base class for model resources meshes.
/// </summary>
API_CLASS(Abstract, NoSpawn) class FLAXENGINE_API MeshBase : public PersistentScriptingObject
API_CLASS(Abstract, NoSpawn) class FLAXENGINE_API MeshBase : public ScriptingObject
{
DECLARE_SCRIPTING_TYPE_MINIMAL(MeshBase);
protected:
@@ -30,7 +30,7 @@ protected:
bool _use16BitIndexBuffer;
explicit MeshBase(const SpawnParams& params)
: PersistentScriptingObject(params)
: ScriptingObject(params)
{
}

View File

@@ -10,9 +10,9 @@ class MemoryReadStream;
/// <summary>
/// Represents single Level Of Detail for the model. Contains a collection of the meshes.
/// </summary>
API_CLASS(NoSpawn) class FLAXENGINE_API ModelLOD : public PersistentScriptingObject
API_CLASS(NoSpawn) class FLAXENGINE_API ModelLOD : public ScriptingObject
{
DECLARE_SCRIPTING_TYPE_WITH_CONSTRUCTOR_IMPL(ModelLOD, PersistentScriptingObject);
DECLARE_SCRIPTING_TYPE_WITH_CONSTRUCTOR_IMPL(ModelLOD, ScriptingObject);
friend Model;
friend Mesh;
private:

View File

@@ -10,9 +10,9 @@ class MemoryReadStream;
/// <summary>
/// Represents single Level Of Detail for the skinned model. Contains a collection of the meshes.
/// </summary>
API_CLASS(NoSpawn) class FLAXENGINE_API SkinnedModelLOD : public PersistentScriptingObject
API_CLASS(NoSpawn) class FLAXENGINE_API SkinnedModelLOD : public ScriptingObject
{
DECLARE_SCRIPTING_TYPE_WITH_CONSTRUCTOR_IMPL(SkinnedModelLOD, PersistentScriptingObject);
DECLARE_SCRIPTING_TYPE_WITH_CONSTRUCTOR_IMPL(SkinnedModelLOD, ScriptingObject);
friend SkinnedModel;
private:

View File

@@ -8,7 +8,7 @@
#include "Engine/Engine/Engine.h"
RenderBuffers::RenderBuffers(const SpawnParams& params)
: PersistentScriptingObject(params)
: ScriptingObject(params)
{
#define CREATE_TEXTURE(name) name = GPUDevice::Instance->CreateTexture(TEXT(#name)); _resources.Add(name)
CREATE_TEXTURE(DepthBuffer);

View File

@@ -19,7 +19,7 @@
/// <summary>
/// The scene rendering buffers container.
/// </summary>
API_CLASS() class FLAXENGINE_API RenderBuffers : public PersistentScriptingObject
API_CLASS() class FLAXENGINE_API RenderBuffers : public ScriptingObject
{
DECLARE_SCRIPTING_TYPE(RenderBuffers);
protected:

View File

@@ -82,7 +82,7 @@ void RenderTask::DrawAll()
}
RenderTask::RenderTask(const SpawnParams& params)
: PersistentScriptingObject(params)
: ScriptingObject(params)
{
// Register
TasksLocker.Lock();

View File

@@ -24,7 +24,7 @@ class Actor;
/// <summary>
/// Allows to perform custom rendering using graphics pipeline.
/// </summary>
API_CLASS() class FLAXENGINE_API RenderTask : public PersistentScriptingObject
API_CLASS() class FLAXENGINE_API RenderTask : public ScriptingObject
{
DECLARE_SCRIPTING_TYPE(RenderTask);

View File

@@ -11,7 +11,7 @@
/// <summary>
/// Base class for all input device objects.
/// </summary>
API_CLASS(Abstract, NoSpawn) class FLAXENGINE_API InputDevice : public PersistentScriptingObject
API_CLASS(Abstract, NoSpawn) class FLAXENGINE_API InputDevice : public ScriptingObject
{
DECLARE_SCRIPTING_TYPE_NO_SPAWN(InputDevice);
public:
@@ -86,7 +86,7 @@ protected:
EventQueue _queue;
explicit InputDevice(const SpawnParams& params, const StringView& name)
: PersistentScriptingObject(params)
: ScriptingObject(params)
, _name(name)
{
}

View File

@@ -971,7 +971,7 @@ private:
public:
// [PersistentScriptingObject]
// [ScriptingObject]
String ToString() const override;
void OnDeleteObject() override;

View File

@@ -55,7 +55,7 @@ typedef Dictionary<Guid, Actor*, HeapAllocation> ActorsLookup;
/// <summary>
/// Base class for objects that are parts of the scene (actors and scripts).
/// </summary>
API_CLASS(Abstract, NoSpawn) class FLAXENGINE_API SceneObject : public PersistentScriptingObject, public ISerializable
API_CLASS(Abstract, NoSpawn) class FLAXENGINE_API SceneObject : public ScriptingObject, public ISerializable
{
DECLARE_SCRIPTING_TYPE_NO_SPAWN(SceneObject);
friend PrefabInstanceData;
@@ -64,7 +64,7 @@ DECLARE_SCRIPTING_TYPE_NO_SPAWN(SceneObject);
friend ScriptsFactory;
friend SceneTicking;
public:
typedef PersistentScriptingObject Base;
typedef ScriptingObject Base;
// Scene Object lifetime flow:
// - Create

View File

@@ -51,7 +51,7 @@ void SendPacketToPeer(ENetPeer* peer, const NetworkChannelType channelType, cons
}
ENetDriver::ENetDriver(const SpawnParams& params)
: PersistentScriptingObject(params)
: ScriptingObject(params)
{
}

View File

@@ -13,7 +13,7 @@
/// <summary>
/// Low-level network transport interface implementation based on ENet library.
/// </summary>
API_CLASS(Namespace="FlaxEngine.Networking", Sealed) class FLAXENGINE_API ENetDriver : public PersistentScriptingObject, public INetworkDriver
API_CLASS(Namespace="FlaxEngine.Networking", Sealed) class FLAXENGINE_API ENetDriver : public ScriptingObject, public INetworkDriver
{
DECLARE_SCRIPTING_TYPE(ENetDriver);
public:

View File

@@ -11,7 +11,7 @@
/// <summary>
/// Low-level network peer class. Provides server-client communication functions, message processing and sending.
/// </summary>
API_CLASS(sealed, NoSpawn, Namespace = "FlaxEngine.Networking") class FLAXENGINE_API NetworkPeer final : public PersistentScriptingObject
API_CLASS(sealed, NoSpawn, Namespace = "FlaxEngine.Networking") class FLAXENGINE_API NetworkPeer final : public ScriptingObject
{
DECLARE_SCRIPTING_TYPE_NO_SPAWN(NetworkPeer);
friend class NetworkManager;
@@ -30,7 +30,7 @@ public:
/// Initializes a new instance of the <see cref="NetworkPeer"/> class.
/// </summary>
NetworkPeer()
: PersistentScriptingObject(SpawnParams(Guid::New(), TypeInitializer))
: ScriptingObject(SpawnParams(Guid::New(), TypeInitializer))
{
}

View File

@@ -12,7 +12,7 @@
/// <summary>
/// Particle system parameter.
/// </summary>
API_CLASS(NoSpawn) class ParticleEffectParameter : public PersistentScriptingObject
API_CLASS(NoSpawn) class ParticleEffectParameter : public ScriptingObject
{
DECLARE_SCRIPTING_TYPE_NO_SPAWN(ParticleEffectParameter);
friend ParticleEffect;
@@ -30,7 +30,7 @@ public:
/// Initializes a new instance of the <see cref="ParticleEffectParameter"/> class.
/// </summary>
ParticleEffectParameter()
: PersistentScriptingObject(SpawnParams(Guid::New(), TypeInitializer))
: ScriptingObject(SpawnParams(Guid::New(), TypeInitializer))
{
}

View File

@@ -112,7 +112,7 @@ UserBase::UserBase(const String& name)
}
UserBase::UserBase(const SpawnParams& params, const String& name)
: PersistentScriptingObject(params)
: ScriptingObject(params)
, _name(name)
{
}

View File

@@ -10,7 +10,7 @@ API_INJECT_CPP_CODE("#include \"Engine/Platform/User.h\"");
/// <summary>
/// Native platform user object.
/// </summary>
API_CLASS(NoSpawn, NoConstructor, Sealed, Name="User") class FLAXENGINE_API UserBase : public PersistentScriptingObject
API_CLASS(NoSpawn, NoConstructor, Sealed, Name="User") class FLAXENGINE_API UserBase : public ScriptingObject
{
DECLARE_SCRIPTING_TYPE_NO_SPAWN(UserBase);
protected:

View File

@@ -87,7 +87,7 @@
#endif
WindowBase::WindowBase(const CreateWindowSettings& settings)
: PersistentScriptingObject(SpawnParams(Guid::New(), TypeInitializer))
: ScriptingObject(SpawnParams(Guid::New(), TypeInitializer))
, _visible(false)
, _minimized(false)
, _maximized(false)
@@ -190,7 +190,7 @@ void WindowBase::OnDeleteObject()
SAFE_DELETE(_swapChain);
// Base
PersistentScriptingObject::OnDeleteObject();
ScriptingObject::OnDeleteObject();
}
bool WindowBase::GetRenderingEnabled() const

View File

@@ -269,7 +269,7 @@ API_INJECT_CPP_CODE("#include \"Engine/Platform/Window.h\"");
/// Native platform window object.
/// </summary>
API_CLASS(NoSpawn, NoConstructor, Sealed, Name="Window")
class FLAXENGINE_API WindowBase : public PersistentScriptingObject
class FLAXENGINE_API WindowBase : public ScriptingObject
{
DECLARE_SCRIPTING_TYPE_NO_SPAWN(WindowBase);
friend GPUSwapChain;
@@ -941,7 +941,7 @@ private:
public:
// [PersistentScriptingObject]
// [ScriptingObject]
String ToString() const override;
void OnDeleteObject() override;
};

View File

@@ -369,7 +369,7 @@ bool DrawCallsList::IsEmpty() const
}
RenderList::RenderList(const SpawnParams& params)
: PersistentScriptingObject(params)
: ScriptingObject(params)
, DirectionalLights(4)
, PointLights(32)
, SpotLights(32)

View File

@@ -322,7 +322,7 @@ struct DrawCallsList
/// <summary>
/// Rendering cache container object for the draw calls collecting, sorting and executing.
/// </summary>
API_CLASS(Sealed) class FLAXENGINE_API RenderList : public PersistentScriptingObject
API_CLASS(Sealed) class FLAXENGINE_API RenderList : public ScriptingObject
{
DECLARE_SCRIPTING_TYPE(RenderList);

View File

@@ -197,7 +197,7 @@ struct MConverter<T*, typename TEnableIf<TIsBaseOf<class ScriptingObject, T>::Va
// Converter for Scripting Objects (collection of values).
template<typename T>
struct MConverter<T, typename TEnableIf<TIsBaseOf<class PersistentScriptingObject, T>::Value>::Type>
struct MConverter<T, typename TEnableIf<TIsBaseOf<class ScriptingObject, T>::Value>::Type>
{
MonoObject* Box(const T& data, MonoClass* klass)
{

View File

@@ -134,7 +134,7 @@ private:
public:
// [PersistentScriptingObject]
// [ScriptingObject]
String ToString() const override;
void OnDeleteObject() override;

View File

@@ -40,20 +40,32 @@ ScriptingObject::ScriptingObject(const SpawnParams& params)
ScriptingObject::~ScriptingObject()
{
// Ensure that GC handle is empty
ASSERT(_gcHandle == 0);
// Ensure that object has been already unregistered
if (IsRegistered())
UnregisterObject();
Deleted(this);
// Get rid of managed object
ScriptingObject::DestroyManaged();
ASSERT(_gcHandle == 0);
// Handle custom scripting objects removing
if (Flags & ObjectFlags::IsCustomScriptingType)
{
_type.Module->OnObjectDeleted(this);
}
// Ensure that object has been already unregistered
if (IsRegistered())
UnregisterObject();
}
ScriptingObject* ScriptingObject::NewObject(const ScriptingTypeHandle& typeHandle)
{
if (!typeHandle)
return nullptr;
auto& type = typeHandle.GetType();
if (type.Type != ScriptingTypes::Script)
return nullptr;
const ScriptingObjectSpawnParams params(Guid::New(), typeHandle);
return type.Script.Spawn(params);
}
MObject* ScriptingObject::GetManagedInstance() const
@@ -82,17 +94,6 @@ MClass* ScriptingObject::GetClass() const
return _type ? _type.GetType().ManagedClass : nullptr;
}
ScriptingObject* ScriptingObject::NewObject(const ScriptingTypeHandle& typeHandle)
{
if (!typeHandle)
return nullptr;
auto& type = typeHandle.GetType();
if (type.Type != ScriptingTypes::Script)
return nullptr;
const ScriptingObjectSpawnParams params(Guid::New(), typeHandle);
return type.Script.Spawn(params);
}
ScriptingObject* ScriptingObject::FromInterface(void* interfaceObj, const ScriptingTypeHandle& interfaceType)
{
if (!interfaceObj || !interfaceType)
@@ -220,18 +221,49 @@ void ScriptingObject::OnManagedInstanceDeleted()
// Unregister object
if (IsRegistered())
UnregisterObject();
// Self destruct
DeleteObject();
}
void ScriptingObject::OnScriptingDispose()
{
// Delete C# object
if (IsRegistered())
UnregisterObject();
DestroyManaged();
}
// Delete C++ object
DeleteObject();
bool ScriptingObject::CreateManaged()
{
#if USE_MONO
MonoObject* managedInstance = CreateManagedInternal();
if (!managedInstance)
return true;
// Prevent form object GC destruction
auto handle = mono_gchandle_new(managedInstance, false);
auto oldHandle = Platform::InterlockedCompareExchange((int32*)&_gcHandle, *(int32*)&handle, 0);
if (*(uint32*)&oldHandle != 0)
{
// Other thread already created the object before
if (const auto monoClass = GetClass())
{
// Reset managed to unmanaged pointer
const MField* monoUnmanagedPtrField = monoClass->GetField(ScriptingObject_unmanagedPtr);
if (monoUnmanagedPtrField)
{
void* param = nullptr;
monoUnmanagedPtrField->SetValue(managedInstance, &param);
}
}
mono_gchandle_free(handle);
return true;
}
#endif
// Ensure to be registered
if (!IsRegistered())
RegisterObject();
return false;
}
#if USE_MONO
@@ -379,7 +411,7 @@ void ScriptingObject::OnDeleteObject()
UnregisterObject();
// Base
RemovableObject::OnDeleteObject();
Object::OnDeleteObject();
}
String ScriptingObject::ToString() const
@@ -392,6 +424,24 @@ ManagedScriptingObject::ManagedScriptingObject(const SpawnParams& params)
{
}
void ManagedScriptingObject::OnManagedInstanceDeleted()
{
// Base
ScriptingObject::OnManagedInstanceDeleted();
// Self destruct
DeleteObject();
}
void ManagedScriptingObject::OnScriptingDispose()
{
// Base
ScriptingObject::OnScriptingDispose();
// Self destruct
DeleteObject();
}
bool ManagedScriptingObject::CreateManaged()
{
#if USE_MONO
@@ -432,70 +482,6 @@ PersistentScriptingObject::PersistentScriptingObject(const SpawnParams& params)
{
}
PersistentScriptingObject::~PersistentScriptingObject()
{
PersistentScriptingObject::DestroyManaged();
}
void PersistentScriptingObject::OnManagedInstanceDeleted()
{
// Cleanup
if (_gcHandle)
{
#if USE_MONO
mono_gchandle_free(_gcHandle);
#endif
_gcHandle = 0;
}
// But do not delete itself
}
void PersistentScriptingObject::OnScriptingDispose()
{
// Delete C# object
if (IsRegistered())
UnregisterObject();
DestroyManaged();
// Don't delete C++ object
}
bool PersistentScriptingObject::CreateManaged()
{
#if USE_MONO
MonoObject* managedInstance = CreateManagedInternal();
if (!managedInstance)
return true;
// Prevent form object GC destruction
auto handle = mono_gchandle_new(managedInstance, false);
auto oldHandle = Platform::InterlockedCompareExchange((int32*)&_gcHandle, *(int32*)&handle, 0);
if (*(uint32*)&oldHandle != 0)
{
// Other thread already created the object before
if (const auto monoClass = GetClass())
{
// Reset managed to unmanaged pointer
const MField* monoUnmanagedPtrField = monoClass->GetField(ScriptingObject_unmanagedPtr);
if (monoUnmanagedPtrField)
{
void* param = nullptr;
monoUnmanagedPtrField->SetValue(managedInstance, &param);
}
}
mono_gchandle_free(handle);
return true;
}
#endif
// Ensure to be registered
if (!IsRegistered())
RegisterObject();
return false;
}
class ScriptingObjectInternal
{
public:
@@ -767,7 +753,7 @@ public:
static ScriptingObject* Spawn(const ScriptingObjectSpawnParams& params)
{
return New<PersistentScriptingObject>(params);
return New<ScriptingObject>(params);
}
};

View File

@@ -8,9 +8,9 @@
#include "ManagedCLR/MTypes.h"
/// <summary>
/// Represents object from unmanaged memory that can use accessed via C# scripting.
/// Represents object from unmanaged memory that can use accessed via scripting.
/// </summary>
API_CLASS(InBuild) class FLAXENGINE_API ScriptingObject : public RemovableObject
API_CLASS(InBuild) class FLAXENGINE_API ScriptingObject : public Object
{
friend class Scripting;
friend class BinaryModule;
@@ -40,14 +40,23 @@ public:
public:
/// <summary>
/// Spawns a new objects of the given type.
/// </summary>
// Spawns a new objects of the given type.
static ScriptingObject* NewObject(const ScriptingTypeHandle& typeHandle);
template<typename T>
static T* Spawn()
static T* NewObject()
{
const SpawnParams params(Guid::New(), T::TypeInitializer);
return T::New(params);
return (T*)NewObject(T::TypeInitializer);
}
template<typename T>
static T* NewObject(const ScriptingTypeHandle& typeHandle)
{
auto obj = NewObject(typeHandle);
if (obj && !obj->Is<T>())
{
Delete(obj);
obj = nullptr;
}
return (T*)obj;
}
public:
@@ -108,13 +117,6 @@ public:
public:
static ScriptingObject* NewObject(const ScriptingTypeHandle& typeHandle);
template<typename T>
static T* NewObject()
{
return (T*)NewObject(T::TypeInitializer);
}
// Tries to cast native interface object to scripting object instance. Returns null if fails.
static ScriptingObject* FromInterface(void* interfaceObj, const ScriptingTypeHandle& interfaceType);
static void* ToInterface(ScriptingObject* obj, const ScriptingTypeHandle& interfaceType);
@@ -189,7 +191,7 @@ public:
virtual void OnManagedInstanceDeleted();
virtual void OnScriptingDispose();
virtual bool CreateManaged() = 0;
virtual bool CreateManaged();
virtual void DestroyManaged();
public:
@@ -223,7 +225,7 @@ protected:
public:
// [RemovableObject]
// [Object]
void OnDeleteObject() override;
String ToString() const override;
};
@@ -246,32 +248,17 @@ public:
public:
// [ScriptingObject]
bool CreateManaged() override;
};
/// <summary>
/// Managed object that uses pinned GC handle to prevent collecting and moving.
/// Used by the objects that lifetime is controlled by the C++ side.
/// </summary>
API_CLASS(InBuild) class FLAXENGINE_API PersistentScriptingObject : public ScriptingObject
{
public:
/// <summary>
/// Initializes a new instance of the <see cref="PersistentScriptingObject"/> class.
/// </summary>
/// <param name="params">The object initialization parameters.</param>
explicit PersistentScriptingObject(const SpawnParams& params);
/// <summary>
/// Finalizes an instance of the <see cref="PersistentScriptingObject"/> class.
/// </summary>
~PersistentScriptingObject();
public:
// [ManagedScriptingObject]
void OnManagedInstanceDeleted() override;
void OnScriptingDispose() override;
bool CreateManaged() override;
};
/// <summary>
/// Use ScriptingObject instead.
/// [Deprecated on 5.01.2022, expires on 5.01.2024]
/// </summary>
API_CLASS(InBuild) class FLAXENGINE_API PersistentScriptingObject : public ScriptingObject
{
public:
PersistentScriptingObject(const SpawnParams& params);
};

View File

@@ -18,7 +18,7 @@ DECLARE_ENUM_EX_6(TaskState, int64, 0, Created, Failed, Canceled, Queued, Runnin
/// <summary>
/// Represents an asynchronous operation.
/// </summary>
class FLAXENGINE_API Task : public RemovableObject, public NonCopyable
class FLAXENGINE_API Task : public Object, public NonCopyable
{
//
// Tasks execution and states flow:

View File

@@ -14,7 +14,7 @@ namespace
}
TaskGraphSystem::TaskGraphSystem(const SpawnParams& params)
: PersistentScriptingObject(params)
: ScriptingObject(params)
{
}
@@ -36,7 +36,7 @@ void TaskGraphSystem::PostExecute(TaskGraph* graph)
}
TaskGraph::TaskGraph(const SpawnParams& params)
: PersistentScriptingObject(params)
: ScriptingObject(params)
{
}

View File

@@ -10,7 +10,7 @@ class TaskGraph;
/// <summary>
/// System that can generate work into Task Graph for asynchronous execution.
/// </summary>
API_CLASS(Abstract) class FLAXENGINE_API TaskGraphSystem : public PersistentScriptingObject
API_CLASS(Abstract) class FLAXENGINE_API TaskGraphSystem : public ScriptingObject
{
DECLARE_SCRIPTING_TYPE(TaskGraphSystem);
friend TaskGraph;
@@ -52,7 +52,7 @@ public:
/// <summary>
/// Graph-based asynchronous tasks scheduler for high-performance computing and processing.
/// </summary>
API_CLASS() class FLAXENGINE_API TaskGraph : public PersistentScriptingObject
API_CLASS() class FLAXENGINE_API TaskGraph : public ScriptingObject
{
DECLARE_SCRIPTING_TYPE(TaskGraph);
private:

View File

@@ -39,9 +39,9 @@ API_ENUM() enum class ChannelMask
/// <summary>
/// Represents a parameter in the Graph.
/// </summary>
API_CLASS() class FLAXENGINE_API GraphParameter : public PersistentScriptingObject
API_CLASS() class FLAXENGINE_API GraphParameter : public ScriptingObject
{
DECLARE_SCRIPTING_TYPE_WITH_CONSTRUCTOR_IMPL(GraphParameter, PersistentScriptingObject);
DECLARE_SCRIPTING_TYPE_WITH_CONSTRUCTOR_IMPL(GraphParameter, ScriptingObject);
public:
/// <summary>