diff --git a/src-csharp/GameObject.cs b/src-csharp/GameObject.cs index d4ad0dd..15a334b 100644 --- a/src-csharp/GameObject.cs +++ b/src-csharp/GameObject.cs @@ -39,7 +39,7 @@ public class GameObject static public GameObject Create() { - NativeMethods.createGameObject(out ulong id, out uint index); + NativeFunctions.createGameObject(out ulong id, out uint index); var o = new GameObject(id, index); return o; } @@ -49,7 +49,7 @@ public class GameObject if(_isDestroyed) return; - _isDestroyed = NativeMethods.destroyGameObject(_index); + _isDestroyed = NativeFunctions.freeGameObject(_index); if(!_isDestroyed) throw new Exception($"Can't destroy GameObject({_id})"); } diff --git a/src-csharp/NativeMethods.cs b/src-csharp/NativeFunctions.cs similarity index 67% rename from src-csharp/NativeMethods.cs rename to src-csharp/NativeFunctions.cs index 7ec413f..77849b5 100644 --- a/src-csharp/NativeMethods.cs +++ b/src-csharp/NativeFunctions.cs @@ -3,11 +3,11 @@ using System.Runtime.InteropServices; namespace Ougge; -internal static class NativeMethods +internal static class NativeFunctions { - [DllImport("__Internal")] - internal extern static bool destroyGameObject(uint index); - [DllImport("__Internal")] internal extern static void createGameObject(out ulong id, out uint index); + + [DllImport("__Internal")] + internal extern static bool freeGameObject(uint index); } \ No newline at end of file diff --git a/src/game/GameObjectPool.cpp b/src/game/GameObjectPool.cpp index 5c25342..7ab1ed5 100644 --- a/src/game/GameObjectPool.cpp +++ b/src/game/GameObjectPool.cpp @@ -94,17 +94,20 @@ std::pair GameObjectPool::emplace(GameObject&& new_obj) return std::pair(i, r); } -void GameObjectPool::erase(u32 index) +bool GameObjectPool::erase(u32 index) { if(index >= size) throw UsefulException(ougge_format("index %i is out of size %i", index, size)); - if(!isIndexUsed(index)) - throw UsefulException(ougge_format("there is no object at index %i", index)); + if(!isIndexUsed(index)){ + // throw UsefulException(ougge_format("there is no object at index %i", index)); + return false; + } buffer[index] = GameObject(); used_indices[index/64] &= ~(u64(1)<<(index%64)); // mark index bit as unused if(index < first_unused_index) first_unused_index = index; + return true; } GameObjectPool::iterator::iterator(GameObjectPool* pool, u32 index) diff --git a/src/game/GameObjectPool.hpp b/src/game/GameObjectPool.hpp index 8405915..4d64317 100644 --- a/src/game/GameObjectPool.hpp +++ b/src/game/GameObjectPool.hpp @@ -45,7 +45,7 @@ public: ~GameObjectPool(); GameObject& get(u32 index); std::pair emplace(GameObject&& new_obj); - void erase(u32 index); + bool erase(u32 index); #pragma region iterator class class iterator { diff --git a/src/main.cpp b/src/main.cpp index 091d9ea..c085f20 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -40,7 +40,7 @@ public: void createExampleObject(Engine& engine){ std::cout<<"creating ExampleObject"<(); - game::GameObject& exampleObj = monoSystem.createGameObject(); + game::GameObject& exampleObj = monoSystem.createAndConstructGameObject(); std::string componentClassName = "Ougge.ExampleComponent"; if(!monoSystem.tryCreateComponent(exampleObj, componentClassName)) throw UsefulException(ougge_format("couldn't create component '%s'", componentClassName.c_str())); diff --git a/src/modules/MonoGameObjectSystem.cpp b/src/modules/MonoGameObjectSystem.cpp index 2f8e21e..9374b92 100644 --- a/src/modules/MonoGameObjectSystem.cpp +++ b/src/modules/MonoGameObjectSystem.cpp @@ -15,6 +15,28 @@ MonoGameObjectSystem::MonoGameObjectSystem(Engine& engine, u32 max_game_objects) gameObjectCtor = Mono::Method(gameObjectClass, ".ctor"); gameObjectInvokeUpdate = Mono::Method(gameObjectClass, "InvokeUpdate"); gameObjectTryCreateComponent = Mono::Method(gameObjectClass, "TryCreateComponent_internal"); + registerNativeCallbacks(); +} + +// sets implementations for extern functions from src-csharp/NativeFunctions.cs +void MonoGameObjectSystem::registerNativeCallbacks(){ + static MonoGameObjectSystem* this_static = this; + if(this_static != this) + throw new UsefulException("creation of more than one instance of MonoGameObjectSystem is not allowed"); + + auto createGameObject_callback = static_cast ( + [](u64* id_out, u32* index_out) -> void { + this_static->createGameObjectInPool(id_out, index_out); + } + ); + mono_add_internal_call("createGameObject", (void*)createGameObject_callback); + + auto freeGameObject_callback = static_cast( + [](u32 index) -> bool { + return this_static->gameObjectPool.erase(index); + } + ); + mono_add_internal_call("freeGameObject", (void*)freeGameObject_callback); } void MonoGameObjectSystem::beginFrame(){ @@ -23,10 +45,20 @@ void MonoGameObjectSystem::beginFrame(){ } } -game::GameObject& MonoGameObjectSystem::createGameObject(){ +// is used in NativeFunctions.cs +game::GameObject& MonoGameObjectSystem::createGameObjectInPool(u64* id_out, u32* index_out){ auto pair = gameObjectPool.emplace(game::GameObject(mono.createObject(gameObjectClass))); + *id_out = ++obj_id; + *index_out = pair.first; game::GameObject& obj = pair.second; - gameObjectCtor(obj.getObjectHandle().getObject(), ++obj_id, pair.first); + return obj; +} + +game::GameObject& MonoGameObjectSystem::createAndConstructGameObject(){ + u64 obj_id; + u32 obj_index; + game::GameObject& obj = createGameObjectInPool(&obj_id, &obj_index); + gameObjectCtor(obj.getObjectHandle().getObject(), obj_id, obj_index); return obj; } diff --git a/src/modules/MonoGameObjectSystem.hpp b/src/modules/MonoGameObjectSystem.hpp index 2257adb..2a1c641 100644 --- a/src/modules/MonoGameObjectSystem.hpp +++ b/src/modules/MonoGameObjectSystem.hpp @@ -24,8 +24,12 @@ public: const std::string& getName() override; void beginFrame() override; - game::GameObject& createGameObject(); + game::GameObject& createAndConstructGameObject(); bool tryCreateComponent(game::GameObject& obj, const std::string& componentClassName); + +private: + void registerNativeCallbacks(); + game::GameObject& createGameObjectInPool(u64* id_out, u32* index_out); }; }