From 3477b05cd8e5007b24329f2199516a2e3221ffdf Mon Sep 17 00:00:00 2001 From: Timerix Date: Thu, 24 Apr 2025 04:50:56 +0500 Subject: [PATCH] created Engine class --- src-csharp/GameObject.cs | 3 +- src/Game/Engine.cpp | 37 ++++++++++++++++++++++ src/Game/Engine.hpp | 30 ++++++++++++++++++ src/Game/GameObject.cpp | 14 ++------- src/Game/GameObject.hpp | 22 +++++-------- src/Game/GameObjectPool.cpp | 6 +++- src/Game/GameObjectPool.hpp | 6 +++- src/Game/Scene.hpp | 7 ----- src/Mono/Mono.hpp | 62 ++++++++++++++++++++++--------------- src/main.cpp | 61 +++++++++--------------------------- src/time.hpp | 10 ++++++ 11 files changed, 152 insertions(+), 106 deletions(-) create mode 100644 src/Game/Engine.cpp create mode 100644 src/Game/Engine.hpp delete mode 100644 src/Game/Scene.hpp diff --git a/src-csharp/GameObject.cs b/src-csharp/GameObject.cs index 550ec69..77c9ec3 100644 --- a/src-csharp/GameObject.cs +++ b/src-csharp/GameObject.cs @@ -65,7 +65,8 @@ public class GameObject if(Components.ContainsKey(t)) return false; - Components.Add(t, (Component)Activator.CreateInstance(t, this)); + Component component = (Component)Activator.CreateInstance(t, this); + Components.Add(t, component); return true; } private bool TryCreateComponent_internal(string fullName) diff --git a/src/Game/Engine.cpp b/src/Game/Engine.cpp new file mode 100644 index 0000000..148cf56 --- /dev/null +++ b/src/Game/Engine.cpp @@ -0,0 +1,37 @@ +#include "Engine.hpp" + +namespace ougge { + +Engine::Engine() + : gameObjectPool(GAMEOBJECTPOOL_SIZE) +{ +} + +void Engine::init(){ + engineManagedAssembly = mono.loadAssembly("Ougge.dll"); + gameObjectClass = engineManagedAssembly->getClass("Ougge", "GameObject"); + gameObjectCtor = Mono::Method(gameObjectClass, ".ctor"); + gameObjectInvokeUpdate = Mono::Method(gameObjectClass, "InvokeUpdate"); + gameObjectTryCreateComponent = Mono::Method(gameObjectClass, "TryCreateComponent_internal"); +} + +void Engine::invokeUpdate(f64 deltaTime){ + for(auto pair : gameObjectPool){ + gameObjectInvokeUpdate(pair.second.getObjectHandle().getObject(), deltaTime); + } +} + +GameObject& Engine::createGameObject(){ + auto pair = gameObjectPool.emplace(GameObject(mono.createObject(gameObjectClass))); + GameObject& obj = pair.second; + gameObjectCtor(obj.getObjectHandle().getObject(), obj_id++, pair.first); + return obj; +} + +bool Engine::tryCreateComponent(GameObject& obj, const std::string& componentClassName){ + Mono::String componentClassNameManaged = mono.createString(componentClassName); + Mono::Bool created = gameObjectTryCreateComponent(obj.getObjectHandle().getObject(), componentClassNameManaged); + return created.wide_bool; +} + +} diff --git a/src/Game/Engine.hpp b/src/Game/Engine.hpp new file mode 100644 index 0000000..8652e32 --- /dev/null +++ b/src/Game/Engine.hpp @@ -0,0 +1,30 @@ +#pragma once + +#include "../Mono/Mono.hpp" +#include "GameObjectPool.hpp" + +namespace ougge { + +#define GAMEOBJECTPOOL_SIZE 64*1024 + +class Engine { + GameObjectPool gameObjectPool; + u64 obj_id = 0; + MonoClass* gameObjectClass; + Mono::Method gameObjectCtor; + Mono::Method gameObjectInvokeUpdate; + Mono::Method gameObjectTryCreateComponent; + +public: + Mono::RuntimeJIT mono; + std::shared_ptr engineManagedAssembly; + + Engine(); + void init(); + void invokeUpdate(f64 deltaTime); + + GameObject& createGameObject(); + bool tryCreateComponent(GameObject& obj, const std::string& componentClassName); +}; + +} diff --git a/src/Game/GameObject.cpp b/src/Game/GameObject.cpp index 3c8550d..6aab972 100644 --- a/src/Game/GameObject.cpp +++ b/src/Game/GameObject.cpp @@ -1,5 +1,7 @@ #include "GameObject.hpp" +namespace ougge { + std::ostream& operator<<(std::ostream& s, Transform& t){ s<<"{ position: {x: "< components; + public: /// @warning Do not use this to create objects. /// This constructor creates null values for GameObject arrays @@ -42,10 +36,10 @@ public: GameObject& operator=(GameObject&& o); - inline Transform& getTransform() { return transform; } - inline const Transform& getTransform() const { return transform; } inline Mono::ObjectHandle& getObjectHandle() { return object_handle; } - inline const Mono::ObjectHandle& getObjectHandle() const { return object_handle; } - bool tryGetComponent(const std::u16string& name, Component** out_component); - bool tryAddComponent(const std::u16string& name, Component&& component); + inline GameObject* getParent() { return parent; } + inline void setParent(GameObject* p) { parent = p; } + inline Transform& getTransform() { return transform; } }; + +} diff --git a/src/Game/GameObjectPool.cpp b/src/Game/GameObjectPool.cpp index af92b4e..92f709a 100644 --- a/src/Game/GameObjectPool.cpp +++ b/src/Game/GameObjectPool.cpp @@ -2,6 +2,8 @@ #include #include +namespace ougge { + GameObjectPool::GameObjectPool(u32 size) { useful_assert(size % 64 == 0, "size of GameObjectPool must be a multiple of 64"); @@ -123,4 +125,6 @@ GameObjectPool::iterator& GameObjectPool::iterator::operator++() { index = pool->getNearestUsedIndex(index+1); return *this; -} \ No newline at end of file +} + +} diff --git a/src/Game/GameObjectPool.hpp b/src/Game/GameObjectPool.hpp index ca557be..56e777d 100644 --- a/src/Game/GameObjectPool.hpp +++ b/src/Game/GameObjectPool.hpp @@ -1,7 +1,9 @@ #include "GameObject.hpp" +namespace ougge { + /* -Fixed array stkring deleted elements indices as bits in array of u64. +Fixed array that stores deleted elements indices as bits in array of u64. Fast emplace, erase and lookup. ------------------------[construct]------------------------ @@ -64,3 +66,5 @@ public: friend class iterator; }; + +} diff --git a/src/Game/Scene.hpp b/src/Game/Scene.hpp deleted file mode 100644 index 0a7c399..0000000 --- a/src/Game/Scene.hpp +++ /dev/null @@ -1,7 +0,0 @@ -#pragma once - -#include "GameObject.hpp" - -class Scene { - -}; diff --git a/src/Mono/Mono.hpp b/src/Mono/Mono.hpp index 7a37834..a9a0a9f 100644 --- a/src/Mono/Mono.hpp +++ b/src/Mono/Mono.hpp @@ -69,30 +69,7 @@ class Method MonoMethod* method_ptr; public: - - template - std::enable_if_t::value, RT> operator()(MonoObject* class_instance, ArgTypes... args) const { - void* arg_array[] = { valueToVoidPtr(args)..., nullptr }; - MonoObject* ex = nullptr; - MonoObject* result = mono_runtime_invoke(method_ptr, class_instance, arg_array, &ex); - if(ex){ - //TODO: call mono_trace_set_printerr_handler from mono/mono/utils/mono-logger.h - mono_print_unhandled_exception(ex); - throw UsefulException("Some C# exception occured"); - } - return valueFromMonoObject(result); - }; - template - std::enable_if_t::value, RT> operator()(MonoObject* class_instance, ArgTypes... args) const { - void* arg_array[] = { valueToVoidPtr(args)..., nullptr }; - MonoObject* ex = nullptr; - mono_runtime_invoke(method_ptr, class_instance, arg_array, &ex); - if(ex){ - //TODO: call mono_trace_set_printerr_handler from mono/mono/utils/mono-logger.h - mono_print_unhandled_exception(ex); - throw UsefulException("Some C# exception occured"); - } - }; + Method() { method_ptr = nullptr; } /// all types must implement getClass() Method(MonoClass* target_class, const std::string& name){ @@ -104,6 +81,37 @@ public: name.c_str(), mono_class_get_name(target_class))); } } + + template + std::enable_if_t::value, RT> operator()(MonoObject* class_instance, ArgTypes... args) const { + if(method_ptr == nullptr) + throw UsefulException("method_ptr is null"); + + void* arg_array[] = { valueToVoidPtr(args)..., nullptr }; + MonoObject* ex = nullptr; + MonoObject* result = mono_runtime_invoke(method_ptr, class_instance, arg_array, &ex); + if(ex){ + //TODO: call mono_trace_set_printerr_handler from mono/mono/utils/mono-logger.h + mono_print_unhandled_exception(ex); + throw UsefulException("Some C# exception occured"); + } + return valueFromMonoObject(result); + }; + + template + std::enable_if_t::value, RT> operator()(MonoObject* class_instance, ArgTypes... args) const { + if(method_ptr == nullptr) + throw UsefulException("method_ptr is null"); + + void* arg_array[] = { valueToVoidPtr(args)..., nullptr }; + MonoObject* ex = nullptr; + mono_runtime_invoke(method_ptr, class_instance, arg_array, &ex); + if(ex){ + //TODO: call mono_trace_set_printerr_handler from mono/mono/utils/mono-logger.h + mono_print_unhandled_exception(ex); + throw UsefulException("Some C# exception occured"); + } + }; }; @@ -127,12 +135,16 @@ public: class RuntimeJIT { MonoDomain* domain; public: - RuntimeJIT(const std::string& domain_name = "MonoApp"); + RuntimeJIT(const std::string& domain_name = "OuggeDomain"); RuntimeJIT(const RuntimeJIT&) = delete; ~RuntimeJIT(); inline MonoDomain* getDomain() { return domain; } std::shared_ptr loadAssembly(const std::string& name); + + inline Object createObject(MonoClass* klass) { return mono_object_new(domain, klass); } + inline String createString(const std::string& v) { return mono_string_new_len(domain, v.c_str(), v.size()); } + inline String createString(const char* v) { return mono_string_new(domain, v); } }; /// @brief ObjectHandle can be used to store reliable reference to MonoObject. diff --git a/src/main.cpp b/src/main.cpp index cc3e551..6347c80 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -3,66 +3,35 @@ #include #include "GUI/MainWindow.hpp" #include "Resources/Resources.hpp" -#include "Game/Scene.hpp" +#include "Game/Engine.hpp" #include "format.hpp" #include "UsefulException.hpp" -#include "Mono/Mono.hpp" -#include "Game/GameObjectPool.hpp" using namespace ougge; -#define GAMEOBJECTPOOL_SIZE 64 - -#define optime(N, LABEL, CODE) {\ - nsec_t b = getMonotonicTimeNsec();\ - for(u32 i = 0; i < (u32)N; i++) {\ - CODE ;\ - }\ - nsec_t e = getMonotonicTimeNsec();\ - nsec_t t = e-b;\ - std::cout<<"operation '"< updateCallbacks; - -void update(f64 deltaTime){ - for(auto upd : updateCallbacks){ - upd(deltaTime); - } -} - int main(int argc, const char** argv){ try { Resources::init(); std::cout<<"initialized resource loader"<getClass("Ougge", "GameObject"); - u64 obj_id = 0; - auto pair = p.emplace(GameObject(mono_object_new(mono.getDomain(), gameObjectClass))); - Mono::ObjectHandle& exampleObjectHandle = pair.second.getObjectHandle(); - auto gameObjectCtor = Mono::Method(gameObjectClass, ".ctor"); - gameObjectCtor(exampleObjectHandle.getObject(), obj_id++, pair.first); - - auto exampleObjectUpdate = Mono::Method(gameObjectClass, "InvokeUpdate"); - updateCallbacks.push_back([&exampleObjectHandle, exampleObjectUpdate](f64 deltaTime) -> void { - exampleObjectUpdate(exampleObjectHandle.getObject(), deltaTime); - }); - - auto tryCreateComponent = Mono::Method(gameObjectClass, "TryCreateComponent_internal"); - Mono::String componentNameManaged = mono_string_new(mono.getDomain(), "Ougge.ExampleComponent"); - Mono::Bool created = tryCreateComponent(exampleObjectHandle.getObject(), componentNameManaged); - if(!created.wide_bool) - throw UsefulException("couldn't create ExampleComponent"); + engine.init(); + std::cout<<"initialized game engine"< void { + engine.invokeUpdate(deltaTime); + }; + GUI::MainWindow w; - w.open("ougge", update); + w.open("ougge", updateCallback); std::cout<<"created sdl window"<