diff --git a/Source/Editor/Cooker/CookingData.h b/Source/Editor/Cooker/CookingData.h index 0d8236e83..d4923b60f 100644 --- a/Source/Editor/Cooker/CookingData.h +++ b/Source/Editor/Cooker/CookingData.h @@ -131,7 +131,7 @@ extern FLAXENGINE_API const Char* ToString(const BuildConfiguration configuratio /// /// Game cooking temporary data. /// -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: diff --git a/Source/Editor/Cooker/GameCooker.cpp b/Source/Editor/Cooker/GameCooker.cpp index 452f4d230..c3696d6fe 100644 --- a/Source/Editor/Cooker/GameCooker.cpp +++ b/Source/Editor/Cooker/GameCooker.cpp @@ -164,7 +164,7 @@ CookingData::Statistics::Statistics() } CookingData::CookingData(const SpawnParams& params) - : PersistentScriptingObject(params) + : ScriptingObject(params) { } diff --git a/Source/Editor/Managed/ManagedEditor.cpp b/Source/Editor/Managed/ManagedEditor.cpp index b37ebf132..39bb9e05f 100644 --- a/Source/Editor/Managed/ManagedEditor.cpp +++ b/Source/Editor/Managed/ManagedEditor.cpp @@ -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(); } diff --git a/Source/Editor/Managed/ManagedEditor.h b/Source/Editor/Managed/ManagedEditor.h index 734dadc3c..540eb46c0 100644 --- a/Source/Editor/Managed/ManagedEditor.h +++ b/Source/Editor/Managed/ManagedEditor.h @@ -14,7 +14,7 @@ namespace CSG /// /// Managed Editor root object /// -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; }; diff --git a/Source/Engine/Audio/AudioDevice.h b/Source/Engine/Audio/AudioDevice.h index 4e7b5388b..e7bad7b56 100644 --- a/Source/Engine/Audio/AudioDevice.h +++ b/Source/Engine/Audio/AudioDevice.h @@ -7,17 +7,17 @@ /// /// Represents a single audio device. /// -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; diff --git a/Source/Engine/Core/Object.cpp b/Source/Engine/Core/Object.cpp deleted file mode 100644 index d931741dc..000000000 --- a/Source/Engine/Core/Object.cpp +++ /dev/null @@ -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); -} diff --git a/Source/Engine/Core/Object.h b/Source/Engine/Core/Object.h index ad9a37a51..5d1335d3c 100644 --- a/Source/Engine/Core/Object.h +++ b/Source/Engine/Core/Object.h @@ -37,30 +37,13 @@ public: /// /// Finalizes an instance of the class. /// - virtual ~Object() - { - } + virtual ~Object(); /// /// Gets the string representation of this object. /// /// The string. virtual String ToString() const = 0; -}; - -/// -/// Interface for removable Engine objects. -/// -/// -class FLAXENGINE_API RemovableObject : public Object -{ -public: - - /// - /// 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. - /// - virtual ~RemovableObject(); /// /// Deletes the object without queueing it to the ObjectsRemovalService. @@ -68,7 +51,7 @@ public: void DeleteObjectNow(); /// - /// Deletes the object. + /// Deletes the object (deferred). /// /// The time to live (in seconds). Use zero to kill it now. /// True if unscaled game time for the object life timeout, otherwise false to use absolute time. @@ -82,3 +65,6 @@ public: Delete(this); } }; + +// [Deprecated on 5.01.2022, expires on 5.01.2024] +typedef Object RemovableObject; diff --git a/Source/Engine/Core/ObjectsRemovalService.cpp b/Source/Engine/Core/ObjectsRemovalService.cpp index 254a30f2a..28e001168 100644 --- a/Source/Engine/Core/ObjectsRemovalService.cpp +++ b/Source/Engine/Core/ObjectsRemovalService.cpp @@ -16,8 +16,8 @@ namespace ObjectsRemovalServiceImpl CriticalSection NewItemsLocker; DateTime LastUpdate; float LastUpdateGameTime; - Dictionary Pool(8192); - Dictionary NewItemsPool(2048); + Dictionary Pool(8192); + Dictionary 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); +} diff --git a/Source/Engine/Core/ObjectsRemovalService.h b/Source/Engine/Core/ObjectsRemovalService.h index 883dc19ae..c68652756 100644 --- a/Source/Engine/Core/ObjectsRemovalService.h +++ b/Source/Engine/Core/ObjectsRemovalService.h @@ -16,7 +16,7 @@ public: /// /// The object. /// True if object has been registered in the pool for the removing, otherwise false. - static bool IsInPool(RemovableObject* obj); + static bool IsInPool(Object* obj); /// /// 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). /// /// The object. - static void Dereference(RemovableObject* obj); + static void Dereference(Object* obj); /// /// Adds the specified object to the dead pool. @@ -36,7 +36,7 @@ public: /// The object. /// The time to live (in seconds). /// True if unscaled game time for the object life timeout, otherwise false to use absolute time. - static void Add(RemovableObject* obj, float timeToLive = 1.0f, bool useGameTime = false); + static void Add(Object* obj, float timeToLive = 1.0f, bool useGameTime = false); /// /// Flushes the objects pool removing objects marked to remove now (with negative or zero time to live). diff --git a/Source/Engine/Foliage/FoliageType.cpp b/Source/Engine/Foliage/FoliageType.cpp index ccf1b2f3e..22977716f 100644 --- a/Source/Engine/Foliage/FoliageType.cpp +++ b/Source/Engine/Foliage/FoliageType.cpp @@ -7,7 +7,7 @@ #include "Foliage.h" FoliageType::FoliageType() - : PersistentScriptingObject(SpawnParams(Guid::New(), TypeInitializer)) + : ScriptingObject(SpawnParams(Guid::New(), TypeInitializer)) , Foliage(nullptr) , Index(-1) { diff --git a/Source/Engine/Foliage/FoliageType.h b/Source/Engine/Foliage/FoliageType.h index 537c5be01..3dc161434 100644 --- a/Source/Engine/Foliage/FoliageType.h +++ b/Source/Engine/Foliage/FoliageType.h @@ -41,7 +41,7 @@ API_ENUM() enum class FoliageScalingModes /// /// Foliage mesh instances type descriptor. Defines the shared properties of the spawned mesh instances. /// -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; diff --git a/Source/Engine/Graphics/GPUAdapter.h b/Source/Engine/Graphics/GPUAdapter.h index efacae2ba..1aabd34b5 100644 --- a/Source/Engine/Graphics/GPUAdapter.h +++ b/Source/Engine/Graphics/GPUAdapter.h @@ -13,13 +13,13 @@ /// /// Interface for GPU device adapter. /// -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)) { } diff --git a/Source/Engine/Graphics/GPUContext.cpp b/Source/Engine/Graphics/GPUContext.cpp index a1955fb4c..c327e8c6e 100644 --- a/Source/Engine/Graphics/GPUContext.cpp +++ b/Source/Engine/Graphics/GPUContext.cpp @@ -6,7 +6,7 @@ #include "Textures/GPUTexture.h" GPUContext::GPUContext(GPUDevice* device) - : PersistentScriptingObject(ScriptingObjectSpawnParams(Guid::New(), TypeInitializer)) + : ScriptingObject(ScriptingObjectSpawnParams(Guid::New(), TypeInitializer)) , _device(device) { } diff --git a/Source/Engine/Graphics/GPUContext.h b/Source/Engine/Graphics/GPUContext.h index c00f0852a..98e6b8069 100644 --- a/Source/Engine/Graphics/GPUContext.h +++ b/Source/Engine/Graphics/GPUContext.h @@ -113,7 +113,7 @@ DECLARE_SCRIPTING_TYPE_NO_SPAWN(GPUDrawIndexedIndirectArgs); /// /// Interface for GPU device context that can record and send graphics commands to the GPU in a sequence. /// -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: diff --git a/Source/Engine/Graphics/GPUDevice.cpp b/Source/Engine/Graphics/GPUDevice.cpp index f4ef475b4..5597bd067 100644 --- a/Source/Engine/Graphics/GPUDevice.cpp +++ b/Source/Engine/Graphics/GPUDevice.cpp @@ -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) diff --git a/Source/Engine/Graphics/GPUDevice.h b/Source/Engine/Graphics/GPUDevice.h index 45dd77c06..e064248cc 100644 --- a/Source/Engine/Graphics/GPUDevice.h +++ b/Source/Engine/Graphics/GPUDevice.h @@ -29,7 +29,7 @@ class MaterialBase; /// /// Graphics device object for rendering on GPU. /// -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: diff --git a/Source/Engine/Graphics/GPUResource.h b/Source/Engine/Graphics/GPUResource.h index 94753205f..34142b4c4 100644 --- a/Source/Engine/Graphics/GPUResource.h +++ b/Source/Engine/Graphics/GPUResource.h @@ -15,7 +15,7 @@ /// /// The base class for all GPU resources. /// -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: /// /// Interface for GPU resources views. Shared base class for texture and buffer views. /// -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) { } diff --git a/Source/Engine/Graphics/Materials/MaterialParams.h b/Source/Engine/Graphics/Materials/MaterialParams.h index d5e182878..78e91fab1 100644 --- a/Source/Engine/Graphics/Materials/MaterialParams.h +++ b/Source/Engine/Graphics/Materials/MaterialParams.h @@ -167,9 +167,9 @@ struct SerializedMaterialParam /// /// Material variable object. Allows to modify material parameter value at runtime. /// -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: diff --git a/Source/Engine/Graphics/Models/MaterialSlot.h b/Source/Engine/Graphics/Models/MaterialSlot.h index bdd491d52..84a394dcb 100644 --- a/Source/Engine/Graphics/Models/MaterialSlot.h +++ b/Source/Engine/Graphics/Models/MaterialSlot.h @@ -10,9 +10,9 @@ /// /// The material slot descriptor that specifies how to render geometry using it. /// -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); /// /// The material to use for rendering. diff --git a/Source/Engine/Graphics/Models/MeshBase.h b/Source/Engine/Graphics/Models/MeshBase.h index 61f76fa59..466b52e04 100644 --- a/Source/Engine/Graphics/Models/MeshBase.h +++ b/Source/Engine/Graphics/Models/MeshBase.h @@ -14,7 +14,7 @@ class ModelBase; /// /// Base class for model resources meshes. /// -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) { } diff --git a/Source/Engine/Graphics/Models/ModelLOD.h b/Source/Engine/Graphics/Models/ModelLOD.h index 94cb8d8ce..897f596d5 100644 --- a/Source/Engine/Graphics/Models/ModelLOD.h +++ b/Source/Engine/Graphics/Models/ModelLOD.h @@ -10,9 +10,9 @@ class MemoryReadStream; /// /// Represents single Level Of Detail for the model. Contains a collection of the meshes. /// -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: diff --git a/Source/Engine/Graphics/Models/SkinnedModelLOD.h b/Source/Engine/Graphics/Models/SkinnedModelLOD.h index 758db0a1b..9f46fb95e 100644 --- a/Source/Engine/Graphics/Models/SkinnedModelLOD.h +++ b/Source/Engine/Graphics/Models/SkinnedModelLOD.h @@ -10,9 +10,9 @@ class MemoryReadStream; /// /// Represents single Level Of Detail for the skinned model. Contains a collection of the meshes. /// -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: diff --git a/Source/Engine/Graphics/RenderBuffers.cpp b/Source/Engine/Graphics/RenderBuffers.cpp index 71fe5961e..ea2a46f7b 100644 --- a/Source/Engine/Graphics/RenderBuffers.cpp +++ b/Source/Engine/Graphics/RenderBuffers.cpp @@ -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); diff --git a/Source/Engine/Graphics/RenderBuffers.h b/Source/Engine/Graphics/RenderBuffers.h index 75f7f3d50..04fea6eb5 100644 --- a/Source/Engine/Graphics/RenderBuffers.h +++ b/Source/Engine/Graphics/RenderBuffers.h @@ -19,7 +19,7 @@ /// /// The scene rendering buffers container. /// -API_CLASS() class FLAXENGINE_API RenderBuffers : public PersistentScriptingObject +API_CLASS() class FLAXENGINE_API RenderBuffers : public ScriptingObject { DECLARE_SCRIPTING_TYPE(RenderBuffers); protected: diff --git a/Source/Engine/Graphics/RenderTask.cpp b/Source/Engine/Graphics/RenderTask.cpp index 4ce50b94f..5ce178601 100644 --- a/Source/Engine/Graphics/RenderTask.cpp +++ b/Source/Engine/Graphics/RenderTask.cpp @@ -82,7 +82,7 @@ void RenderTask::DrawAll() } RenderTask::RenderTask(const SpawnParams& params) - : PersistentScriptingObject(params) + : ScriptingObject(params) { // Register TasksLocker.Lock(); diff --git a/Source/Engine/Graphics/RenderTask.h b/Source/Engine/Graphics/RenderTask.h index 63c5894c2..2928b148e 100644 --- a/Source/Engine/Graphics/RenderTask.h +++ b/Source/Engine/Graphics/RenderTask.h @@ -24,7 +24,7 @@ class Actor; /// /// Allows to perform custom rendering using graphics pipeline. /// -API_CLASS() class FLAXENGINE_API RenderTask : public PersistentScriptingObject +API_CLASS() class FLAXENGINE_API RenderTask : public ScriptingObject { DECLARE_SCRIPTING_TYPE(RenderTask); diff --git a/Source/Engine/Input/InputDevice.h b/Source/Engine/Input/InputDevice.h index 27f6125ba..445b0b20e 100644 --- a/Source/Engine/Input/InputDevice.h +++ b/Source/Engine/Input/InputDevice.h @@ -11,7 +11,7 @@ /// /// Base class for all input device objects. /// -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) { } diff --git a/Source/Engine/Level/Actor.h b/Source/Engine/Level/Actor.h index 1d4296285..e3fcbc371 100644 --- a/Source/Engine/Level/Actor.h +++ b/Source/Engine/Level/Actor.h @@ -971,7 +971,7 @@ private: public: - // [PersistentScriptingObject] + // [ScriptingObject] String ToString() const override; void OnDeleteObject() override; diff --git a/Source/Engine/Level/SceneObject.h b/Source/Engine/Level/SceneObject.h index 387cbbc13..42d923403 100644 --- a/Source/Engine/Level/SceneObject.h +++ b/Source/Engine/Level/SceneObject.h @@ -55,7 +55,7 @@ typedef Dictionary ActorsLookup; /// /// Base class for objects that are parts of the scene (actors and scripts). /// -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 diff --git a/Source/Engine/Networking/Drivers/ENetDriver.cpp b/Source/Engine/Networking/Drivers/ENetDriver.cpp index 5079ef218..c1c26641e 100644 --- a/Source/Engine/Networking/Drivers/ENetDriver.cpp +++ b/Source/Engine/Networking/Drivers/ENetDriver.cpp @@ -51,7 +51,7 @@ void SendPacketToPeer(ENetPeer* peer, const NetworkChannelType channelType, cons } ENetDriver::ENetDriver(const SpawnParams& params) - : PersistentScriptingObject(params) + : ScriptingObject(params) { } diff --git a/Source/Engine/Networking/Drivers/ENetDriver.h b/Source/Engine/Networking/Drivers/ENetDriver.h index b9f4b5545..bc038e220 100644 --- a/Source/Engine/Networking/Drivers/ENetDriver.h +++ b/Source/Engine/Networking/Drivers/ENetDriver.h @@ -13,7 +13,7 @@ /// /// Low-level network transport interface implementation based on ENet library. /// -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: diff --git a/Source/Engine/Networking/NetworkPeer.h b/Source/Engine/Networking/NetworkPeer.h index 865a8f3ec..5ba1435bc 100644 --- a/Source/Engine/Networking/NetworkPeer.h +++ b/Source/Engine/Networking/NetworkPeer.h @@ -11,7 +11,7 @@ /// /// Low-level network peer class. Provides server-client communication functions, message processing and sending. /// -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 class. /// NetworkPeer() - : PersistentScriptingObject(SpawnParams(Guid::New(), TypeInitializer)) + : ScriptingObject(SpawnParams(Guid::New(), TypeInitializer)) { } diff --git a/Source/Engine/Particles/ParticleEffect.h b/Source/Engine/Particles/ParticleEffect.h index ac9a43a91..e43e1df8d 100644 --- a/Source/Engine/Particles/ParticleEffect.h +++ b/Source/Engine/Particles/ParticleEffect.h @@ -12,7 +12,7 @@ /// /// Particle system parameter. /// -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 class. /// ParticleEffectParameter() - : PersistentScriptingObject(SpawnParams(Guid::New(), TypeInitializer)) + : ScriptingObject(SpawnParams(Guid::New(), TypeInitializer)) { } diff --git a/Source/Engine/Platform/Base/PlatformBase.cpp b/Source/Engine/Platform/Base/PlatformBase.cpp index 382aff1b4..2e51c5e30 100644 --- a/Source/Engine/Platform/Base/PlatformBase.cpp +++ b/Source/Engine/Platform/Base/PlatformBase.cpp @@ -112,7 +112,7 @@ UserBase::UserBase(const String& name) } UserBase::UserBase(const SpawnParams& params, const String& name) - : PersistentScriptingObject(params) + : ScriptingObject(params) , _name(name) { } diff --git a/Source/Engine/Platform/Base/UserBase.h b/Source/Engine/Platform/Base/UserBase.h index c946c4ba1..c53e56169 100644 --- a/Source/Engine/Platform/Base/UserBase.h +++ b/Source/Engine/Platform/Base/UserBase.h @@ -10,7 +10,7 @@ API_INJECT_CPP_CODE("#include \"Engine/Platform/User.h\""); /// /// Native platform user object. /// -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: diff --git a/Source/Engine/Platform/Base/WindowBase.cpp b/Source/Engine/Platform/Base/WindowBase.cpp index 8df7ae6d1..7324003ed 100644 --- a/Source/Engine/Platform/Base/WindowBase.cpp +++ b/Source/Engine/Platform/Base/WindowBase.cpp @@ -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 diff --git a/Source/Engine/Platform/Base/WindowBase.h b/Source/Engine/Platform/Base/WindowBase.h index 799a3866e..ab77d2c56 100644 --- a/Source/Engine/Platform/Base/WindowBase.h +++ b/Source/Engine/Platform/Base/WindowBase.h @@ -269,7 +269,7 @@ API_INJECT_CPP_CODE("#include \"Engine/Platform/Window.h\""); /// Native platform window object. /// 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; }; diff --git a/Source/Engine/Renderer/RenderList.cpp b/Source/Engine/Renderer/RenderList.cpp index be1f035fc..51001cbb5 100644 --- a/Source/Engine/Renderer/RenderList.cpp +++ b/Source/Engine/Renderer/RenderList.cpp @@ -369,7 +369,7 @@ bool DrawCallsList::IsEmpty() const } RenderList::RenderList(const SpawnParams& params) - : PersistentScriptingObject(params) + : ScriptingObject(params) , DirectionalLights(4) , PointLights(32) , SpotLights(32) diff --git a/Source/Engine/Renderer/RenderList.h b/Source/Engine/Renderer/RenderList.h index 10b51448d..890ebb473 100644 --- a/Source/Engine/Renderer/RenderList.h +++ b/Source/Engine/Renderer/RenderList.h @@ -322,7 +322,7 @@ struct DrawCallsList /// /// Rendering cache container object for the draw calls collecting, sorting and executing. /// -API_CLASS(Sealed) class FLAXENGINE_API RenderList : public PersistentScriptingObject +API_CLASS(Sealed) class FLAXENGINE_API RenderList : public ScriptingObject { DECLARE_SCRIPTING_TYPE(RenderList); diff --git a/Source/Engine/Scripting/ManagedCLR/MUtils.h b/Source/Engine/Scripting/ManagedCLR/MUtils.h index 9bda26826..09db2bb88 100644 --- a/Source/Engine/Scripting/ManagedCLR/MUtils.h +++ b/Source/Engine/Scripting/ManagedCLR/MUtils.h @@ -197,7 +197,7 @@ struct MConverter::Va // Converter for Scripting Objects (collection of values). template -struct MConverter::Value>::Type> +struct MConverter::Value>::Type> { MonoObject* Box(const T& data, MonoClass* klass) { diff --git a/Source/Engine/Scripting/Script.h b/Source/Engine/Scripting/Script.h index 4f5079daf..32c2c03fd 100644 --- a/Source/Engine/Scripting/Script.h +++ b/Source/Engine/Scripting/Script.h @@ -134,7 +134,7 @@ private: public: - // [PersistentScriptingObject] + // [ScriptingObject] String ToString() const override; void OnDeleteObject() override; diff --git a/Source/Engine/Scripting/ScriptingObject.cpp b/Source/Engine/Scripting/ScriptingObject.cpp index b8775f941..43136929c 100644 --- a/Source/Engine/Scripting/ScriptingObject.cpp +++ b/Source/Engine/Scripting/ScriptingObject.cpp @@ -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, ¶m); + } + } + 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, ¶m); - } - } - 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(params); + return New(params); } }; diff --git a/Source/Engine/Scripting/ScriptingObject.h b/Source/Engine/Scripting/ScriptingObject.h index a0114b1a4..04983b43e 100644 --- a/Source/Engine/Scripting/ScriptingObject.h +++ b/Source/Engine/Scripting/ScriptingObject.h @@ -8,9 +8,9 @@ #include "ManagedCLR/MTypes.h" /// -/// Represents object from unmanaged memory that can use accessed via C# scripting. +/// Represents object from unmanaged memory that can use accessed via scripting. /// -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: - /// - /// Spawns a new objects of the given type. - /// + // Spawns a new objects of the given type. + static ScriptingObject* NewObject(const ScriptingTypeHandle& typeHandle); template - static T* Spawn() + static T* NewObject() { - const SpawnParams params(Guid::New(), T::TypeInitializer); - return T::New(params); + return (T*)NewObject(T::TypeInitializer); + } + template + static T* NewObject(const ScriptingTypeHandle& typeHandle) + { + auto obj = NewObject(typeHandle); + if (obj && !obj->Is()) + { + Delete(obj); + obj = nullptr; + } + return (T*)obj; } public: @@ -108,13 +117,6 @@ public: public: - static ScriptingObject* NewObject(const ScriptingTypeHandle& typeHandle); - template - 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; -}; - -/// -/// Managed object that uses pinned GC handle to prevent collecting and moving. -/// Used by the objects that lifetime is controlled by the C++ side. -/// -API_CLASS(InBuild) class FLAXENGINE_API PersistentScriptingObject : public ScriptingObject -{ -public: - - /// - /// Initializes a new instance of the class. - /// - /// The object initialization parameters. - explicit PersistentScriptingObject(const SpawnParams& params); - - /// - /// Finalizes an instance of the class. - /// - ~PersistentScriptingObject(); - -public: - - // [ManagedScriptingObject] void OnManagedInstanceDeleted() override; void OnScriptingDispose() override; bool CreateManaged() override; }; + +/// +/// Use ScriptingObject instead. +/// [Deprecated on 5.01.2022, expires on 5.01.2024] +/// +API_CLASS(InBuild) class FLAXENGINE_API PersistentScriptingObject : public ScriptingObject +{ +public: + PersistentScriptingObject(const SpawnParams& params); +}; diff --git a/Source/Engine/Threading/Task.h b/Source/Engine/Threading/Task.h index 86a34a992..10486288a 100644 --- a/Source/Engine/Threading/Task.h +++ b/Source/Engine/Threading/Task.h @@ -18,7 +18,7 @@ DECLARE_ENUM_EX_6(TaskState, int64, 0, Created, Failed, Canceled, Queued, Runnin /// /// Represents an asynchronous operation. /// -class FLAXENGINE_API Task : public RemovableObject, public NonCopyable +class FLAXENGINE_API Task : public Object, public NonCopyable { // // Tasks execution and states flow: diff --git a/Source/Engine/Threading/TaskGraph.cpp b/Source/Engine/Threading/TaskGraph.cpp index b36a85e31..5d32f7670 100644 --- a/Source/Engine/Threading/TaskGraph.cpp +++ b/Source/Engine/Threading/TaskGraph.cpp @@ -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) { } diff --git a/Source/Engine/Threading/TaskGraph.h b/Source/Engine/Threading/TaskGraph.h index 142b0d2a1..1664f6291 100644 --- a/Source/Engine/Threading/TaskGraph.h +++ b/Source/Engine/Threading/TaskGraph.h @@ -10,7 +10,7 @@ class TaskGraph; /// /// System that can generate work into Task Graph for asynchronous execution. /// -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: /// /// Graph-based asynchronous tasks scheduler for high-performance computing and processing. /// -API_CLASS() class FLAXENGINE_API TaskGraph : public PersistentScriptingObject +API_CLASS() class FLAXENGINE_API TaskGraph : public ScriptingObject { DECLARE_SCRIPTING_TYPE(TaskGraph); private: diff --git a/Source/Engine/Visject/GraphParameter.h b/Source/Engine/Visject/GraphParameter.h index 1fb3fd2dd..8b1f7cc8c 100644 --- a/Source/Engine/Visject/GraphParameter.h +++ b/Source/Engine/Visject/GraphParameter.h @@ -39,9 +39,9 @@ API_ENUM() enum class ChannelMask /// /// Represents a parameter in the Graph. /// -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: ///