From d5d28d4884a5ff40eebe3ede1aefaadab2769663 Mon Sep 17 00:00:00 2001 From: Timerix Date: Fri, 18 Apr 2025 22:31:32 +0500 Subject: [PATCH] tried to fix bugs (partial success) --- .vscode/tasks.json | 2 +- dependencies/src-csharp.config | 6 +++--- src-csharp/GameObject.cs | 24 +++++++++++++----------- src-csharp/Ougge.csproj | 3 +-- src/Mono/Mono.cpp | 11 ++++++++++- src/Mono/Mono.hpp | 8 ++++++-- src/Mono/Runtime.cpp | 3 ++- src/main.cpp | 19 ++++++++++--------- 8 files changed, 46 insertions(+), 30 deletions(-) diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 9840ce9..bcbd170 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -10,7 +10,7 @@ "command": "bash", "args": [ "-c", - "cbuild build_exec_dbg" + "cbuild rebuild_dependencies=src-csharp build_exec_dbg" ], "options": { "cwd": "${workspaceFolder}" diff --git a/dependencies/src-csharp.config b/dependencies/src-csharp.config index f679ca8..23fe21a 100755 --- a/dependencies/src-csharp.config +++ b/dependencies/src-csharp.config @@ -1,9 +1,9 @@ #!/usr/bin/env bash DEP_WORKING_DIR='src-csharp' +CS_CONFIGURATION='Release' if [[ "$TASK" = *_dbg ]]; then - DEP_BUILD_COMMAND='dotnet build src-csharp.sln -o bin -c Debug' -else - DEP_BUILD_COMMAND='dotnet build src-csharp.sln -o bin -c Release' + CS_CONFIGURATION='Debug' fi +DEP_BUILD_COMMAND=$"dotnet build src-csharp.sln -o bin -c $CS_CONFIGURATION" DEP_CLEAN_COMMAND='rm -rf bin obj' DEP_OTHER_OUT_FILES='bin/Ougge.dll' diff --git a/src-csharp/GameObject.cs b/src-csharp/GameObject.cs index 676273b..0bd6c89 100644 --- a/src-csharp/GameObject.cs +++ b/src-csharp/GameObject.cs @@ -26,23 +26,21 @@ public class GameObject public Transform Transform { get; } public GameObject? Parent; - public readonly Dictionary Components = new(); + public Dictionary Components = new(); - private GameObject() - { - } - - private void Init(ulong id, uint nativePoolIndex) + private GameObject(ulong id, uint nativePoolIndex) { _id = id; _index = nativePoolIndex; + // constructor doesn't work without writing to console + // TODO: FIX THIS BULLSHIT + Console.WriteLine($"GameObject(id: {id}, nativePoolIndex: {nativePoolIndex})"); } static public GameObject Create() { NativeMethods.createGameObject(out ulong id, out uint index); - var o = new GameObject(); - o.Init(id, index); + var o = new GameObject(id, index); return o; } @@ -56,6 +54,9 @@ public class GameObject throw new Exception($"Can't destroy GameObject({_id})"); } + /// type derived from Component + /// true if new component instance was created, false if component of the same tipe is already added to GameObject + /// public bool TryCreateComponent(Type t) { if(!t.IsSubclassOf(typeof(Component))) @@ -67,12 +68,13 @@ public class GameObject Components.Add(t, (Component)Activator.CreateInstance(t, this)); return true; } - private bool TryCreateComponent(string fullName) + private bool TryCreateComponent_internal(string fullName) { - return TryCreateComponent(Type.GetType(fullName)); + Type t = Type.GetType(fullName) ?? throw new Exception($"type not found '{fullName}'"); + return TryCreateComponent(t); } - private void UpdateComponents(double deltaTime) + private void InvokeUpdate(double deltaTime) { foreach(var p in Components) { diff --git a/src-csharp/Ougge.csproj b/src-csharp/Ougge.csproj index 0772100..176d871 100644 --- a/src-csharp/Ougge.csproj +++ b/src-csharp/Ougge.csproj @@ -1,11 +1,10 @@  - net48 latest Ougge disable enable + embedded - diff --git a/src/Mono/Mono.cpp b/src/Mono/Mono.cpp index a157196..7721a8b 100644 --- a/src/Mono/Mono.cpp +++ b/src/Mono/Mono.cpp @@ -38,20 +38,28 @@ MonoMethod* tryGetMonoMethod(MonoClass* target_class, const std::string& name, { if(target_class == nullptr) throw UsefulException("target_class is nullptr"); + // iterate each method void* iter = nullptr; MonoMethod* m = nullptr; - MonoType* return_type = nullptr; std::vector argument_types; while( (m = mono_class_get_methods(target_class, &iter)) ){ + // compare name + std::string m_name = mono_method_get_name(m); + if(m_name != name) + continue; + argument_types.clear(); + MonoType* return_type = nullptr; getMethodSignatureTypes(m, &return_type, argument_types); // compare argument count if(argument_types.size() != arg_classes_size) continue; + // compare return type if(!mono_metadata_type_equal(return_type, mono_class_get_type(return_class))) continue; + // compare argument types bool argument_types_mismatch = false; for(size_t i = 0; i < arg_classes_size; i++){ @@ -62,6 +70,7 @@ MonoMethod* tryGetMonoMethod(MonoClass* target_class, const std::string& name, } if(argument_types_mismatch) continue; + // passed all tests successfully break; } diff --git a/src/Mono/Mono.hpp b/src/Mono/Mono.hpp index d77f7ff..fc7a9bd 100644 --- a/src/Mono/Mono.hpp +++ b/src/Mono/Mono.hpp @@ -85,8 +85,11 @@ public: void* arg_array[] = { valueToVoidPtr(args)..., nullptr }; MonoObject* ex = nullptr; mono_runtime_invoke(method_ptr, class_instance, arg_array, &ex); - if(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"); + } }; /// all types must implement getClass() @@ -94,9 +97,10 @@ public: static MonoClass* arg_classes[] { getClass()... }; static MonoClass* return_class { getClass() }; method_ptr = tryGetMonoMethod(target_class, name, return_class, arg_classes, sizeof...(ArgTypes)); - if(method_ptr == nullptr) + if(method_ptr == nullptr){ throw UsefulException(format("can't get method '%s' from class '%s'", name.c_str(), mono_class_get_name(target_class))); + } } }; diff --git a/src/Mono/Runtime.cpp b/src/Mono/Runtime.cpp index bc4cd9e..ee6ad64 100644 --- a/src/Mono/Runtime.cpp +++ b/src/Mono/Runtime.cpp @@ -15,7 +15,8 @@ RuntimeJIT::RuntimeJIT(const std::string& domain_name){ } RuntimeJIT::~RuntimeJIT(){ - mono_jit_cleanup(domain); + // TODO: fix segfault on cleanup + // mono_jit_cleanup(domain); } std::shared_ptr RuntimeJIT::loadAssembly(const std::string &name){ diff --git a/src/main.cpp b/src/main.cpp index a0874fc..62d3cbc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -46,22 +46,23 @@ int main(int argc, const char** argv){ MonoObject* exampleObjectManaged = mono_object_new(mono.getDomain(), gameObjectClass); u64 obj_id = 0; auto pair = p.emplace(GameObject(exampleObjectManaged, nullptr)); - mono_runtime_object_init(exampleObjectManaged); - auto exampleObjectInit = Mono::Method(gameObjectClass, "Init"); - exampleObjectInit(exampleObjectManaged, obj_id++, pair.first); - auto exampleObjectUpdate = Mono::Method(gameObjectClass, "UpdateComponents"); - + auto gameObjectCtor = Mono::Method(gameObjectClass, ".ctor"); + gameObjectCtor(exampleObjectManaged, obj_id++, pair.first); + + auto exampleObjectUpdate = Mono::Method(gameObjectClass, "InvokeUpdate"); updateCallbacks.push_back([exampleObjectManaged, exampleObjectUpdate](f64 deltaTime) -> void { exampleObjectUpdate(exampleObjectManaged, deltaTime); }); - auto tryCreateComponent = Mono::Method(gameObjectClass, "TryCreateComponent"); - Mono::String componentNameManaged = mono_string_new(mono.getDomain(), "ExampleComponent"); - Mono::ObjectHandle componentNameObjectHandle((MonoObject*)(void*)componentNameManaged); + auto tryCreateComponent = Mono::Method(gameObjectClass, "TryCreateComponent_internal"); + Mono::String componentNameManaged = mono_string_new(mono.getDomain(), "Ougge.ExampleComponent"); + // Mono::ObjectHandle componentNameObjectHandle((MonoObject*)(void*)componentNameManaged); Mono::Bool created = tryCreateComponent(exampleObjectManaged, componentNameManaged); if(!created.wide_bool) throw UsefulException("couldn't create ExampleComponent"); - + + std::cout<<"OK!"<