Compare commits
3 Commits
f7a8d32865
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 7e7454278d | |||
| 346779060e | |||
| 175fe61e5c |
2
dependencies/cimgui
vendored
2
dependencies/cimgui
vendored
Submodule dependencies/cimgui updated: bcb179376b...d94ad1b162
@@ -14,6 +14,14 @@ public class ExampleComponent : Component
|
|||||||
Console.WriteLine($"C# deltaTime {deltaTime} object id {Owner.Id}");
|
Console.WriteLine($"C# deltaTime {deltaTime} object id {Owner.Id}");
|
||||||
ImGui.Begin("C# WINDOW");
|
ImGui.Begin("C# WINDOW");
|
||||||
ImGui.Text("Hello from ExampleComponent!");
|
ImGui.Text("Hello from ExampleComponent!");
|
||||||
|
if (ImGui.Button("create GameObject"))
|
||||||
|
{
|
||||||
|
GameObject.Create();
|
||||||
|
}
|
||||||
|
if (ImGui.Button("GC Collect"))
|
||||||
|
{
|
||||||
|
GC.Collect();
|
||||||
|
}
|
||||||
ImGui.End();
|
ImGui.End();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -39,8 +39,9 @@ public class GameObject
|
|||||||
|
|
||||||
static public GameObject Create()
|
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);
|
var o = new GameObject(id, index);
|
||||||
|
Console.WriteLine($"C# created object with id {id}, index {index}");
|
||||||
return o;
|
return o;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,11 +50,17 @@ public class GameObject
|
|||||||
if(_isDestroyed)
|
if(_isDestroyed)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
_isDestroyed = NativeMethods.destroyGameObject(_index);
|
_isDestroyed = NativeFunctions.freeGameObject(_index);
|
||||||
if(!_isDestroyed)
|
if(!_isDestroyed)
|
||||||
throw new Exception($"Can't destroy GameObject({_id})");
|
throw new Exception($"Can't destroy GameObject({_id})");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
~GameObject()
|
||||||
|
{
|
||||||
|
// destroys object native part when managed part is garbage-collected
|
||||||
|
Destroy();
|
||||||
|
}
|
||||||
|
|
||||||
/// <param name="t">type derived from Component</param>
|
/// <param name="t">type derived from Component</param>
|
||||||
/// <returns>true if new component instance was created, false if component of the same tipe is already added to GameObject</returns>
|
/// <returns>true if new component instance was created, false if component of the same tipe is already added to GameObject</returns>
|
||||||
/// <exception cref="Exception"></exception>
|
/// <exception cref="Exception"></exception>
|
||||||
@@ -78,6 +85,8 @@ public class GameObject
|
|||||||
|
|
||||||
private void InvokeUpdate(double deltaTime)
|
private void InvokeUpdate(double deltaTime)
|
||||||
{
|
{
|
||||||
|
Console.WriteLine("C# InvokeUpdate");
|
||||||
|
Console.WriteLine($"id {_id}, index {_index}, destroyed {_isDestroyed}");
|
||||||
foreach (var p in Components)
|
foreach (var p in Components)
|
||||||
{
|
{
|
||||||
p.Value.Update(deltaTime);
|
p.Value.Update(deltaTime);
|
||||||
|
|||||||
12
src-csharp/NativeFunctions.cs
Normal file
12
src-csharp/NativeFunctions.cs
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
using System.Runtime.CompilerServices;
|
||||||
|
|
||||||
|
namespace Ougge;
|
||||||
|
|
||||||
|
internal static class NativeFunctions
|
||||||
|
{
|
||||||
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
|
internal extern static void createGameObject(out ulong id, out uint index);
|
||||||
|
|
||||||
|
[MethodImpl(MethodImplOptions.InternalCall)]
|
||||||
|
internal extern static bool freeGameObject(uint index);
|
||||||
|
}
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
using System;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
|
|
||||||
namespace Ougge;
|
|
||||||
|
|
||||||
internal static class NativeMethods
|
|
||||||
{
|
|
||||||
[DllImport("__Internal")]
|
|
||||||
internal extern static bool destroyGameObject(uint index);
|
|
||||||
|
|
||||||
[DllImport("__Internal")]
|
|
||||||
internal extern static void createGameObject(out ulong id, out uint index);
|
|
||||||
}
|
|
||||||
@@ -48,7 +48,7 @@ void Engine::stopLoop(){
|
|||||||
void Engine::handleModuleError(IEngineModule& module, const char* type, const char* method, const char* error){
|
void Engine::handleModuleError(IEngineModule& module, const char* type, const char* method, const char* error){
|
||||||
std::string error_message = ougge_format(
|
std::string error_message = ougge_format(
|
||||||
"Catched %s at %s.%s(): %s",
|
"Catched %s at %s.%s(): %s",
|
||||||
type, module.getName(), method, error);
|
type, module.getName().c_str(), method, error);
|
||||||
std::cerr<<error_message<<std::endl;
|
std::cerr<<error_message<<std::endl;
|
||||||
error_messages.push_back(error_message);
|
error_messages.push_back(error_message);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,17 +94,20 @@ std::pair<u32, GameObject&> GameObjectPool::emplace(GameObject&& new_obj)
|
|||||||
return std::pair<u32, GameObject&>(i, r);
|
return std::pair<u32, GameObject&>(i, r);
|
||||||
}
|
}
|
||||||
|
|
||||||
void GameObjectPool::erase(u32 index)
|
bool GameObjectPool::erase(u32 index)
|
||||||
{
|
{
|
||||||
if(index >= size)
|
if(index >= size)
|
||||||
throw UsefulException(ougge_format("index %i is out of size %i", index, size));
|
throw UsefulException(ougge_format("index %i is out of size %i", index, size));
|
||||||
if(!isIndexUsed(index))
|
if(!isIndexUsed(index)){
|
||||||
throw UsefulException(ougge_format("there is no object at index %i", index));
|
// throw UsefulException(ougge_format("there is no object at index %i", index));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
buffer[index] = GameObject();
|
buffer[index] = GameObject();
|
||||||
used_indices[index/64] &= ~(u64(1)<<(index%64)); // mark index bit as unused
|
used_indices[index/64] &= ~(u64(1)<<(index%64)); // mark index bit as unused
|
||||||
if(index < first_unused_index)
|
if(index < first_unused_index)
|
||||||
first_unused_index = index;
|
first_unused_index = index;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
GameObjectPool::iterator::iterator(GameObjectPool* pool, u32 index)
|
GameObjectPool::iterator::iterator(GameObjectPool* pool, u32 index)
|
||||||
|
|||||||
@@ -45,7 +45,7 @@ public:
|
|||||||
~GameObjectPool();
|
~GameObjectPool();
|
||||||
GameObject& get(u32 index);
|
GameObject& get(u32 index);
|
||||||
std::pair<u32, GameObject&> emplace(GameObject&& new_obj);
|
std::pair<u32, GameObject&> emplace(GameObject&& new_obj);
|
||||||
void erase(u32 index);
|
bool erase(u32 index);
|
||||||
|
|
||||||
#pragma region iterator class
|
#pragma region iterator class
|
||||||
class iterator {
|
class iterator {
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ public:
|
|||||||
void createExampleObject(Engine& engine){
|
void createExampleObject(Engine& engine){
|
||||||
std::cout<<"creating ExampleObject"<<std::endl;
|
std::cout<<"creating ExampleObject"<<std::endl;
|
||||||
auto& monoSystem = engine.getModule<modules::MonoGameObjectSystem>();
|
auto& monoSystem = engine.getModule<modules::MonoGameObjectSystem>();
|
||||||
game::GameObject& exampleObj = monoSystem.createGameObject();
|
game::GameObject& exampleObj = monoSystem.createAndConstructGameObject();
|
||||||
std::string componentClassName = "Ougge.ExampleComponent";
|
std::string componentClassName = "Ougge.ExampleComponent";
|
||||||
if(!monoSystem.tryCreateComponent(exampleObj, componentClassName))
|
if(!monoSystem.tryCreateComponent(exampleObj, componentClassName))
|
||||||
throw UsefulException(ougge_format("couldn't create component '%s'", componentClassName.c_str()));
|
throw UsefulException(ougge_format("couldn't create component '%s'", componentClassName.c_str()));
|
||||||
|
|||||||
@@ -15,18 +15,55 @@ MonoGameObjectSystem::MonoGameObjectSystem(Engine& engine, u32 max_game_objects)
|
|||||||
gameObjectCtor = Mono::Method<void(u64, u32)>(gameObjectClass, ".ctor");
|
gameObjectCtor = Mono::Method<void(u64, u32)>(gameObjectClass, ".ctor");
|
||||||
gameObjectInvokeUpdate = Mono::Method<void(f64)>(gameObjectClass, "InvokeUpdate");
|
gameObjectInvokeUpdate = Mono::Method<void(f64)>(gameObjectClass, "InvokeUpdate");
|
||||||
gameObjectTryCreateComponent = Mono::Method<Mono::Bool(Mono::String)>(gameObjectClass, "TryCreateComponent_internal");
|
gameObjectTryCreateComponent = Mono::Method<Mono::Bool(Mono::String)>(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<void(*)(u64*, u32*)> (
|
||||||
|
[](u64* id_out, u32* index_out) -> void {
|
||||||
|
std::cout<<"createGameObject_callback"<<std::endl;
|
||||||
|
this_static->createGameObjectInPool(id_out, index_out);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
mono_add_internal_call("Ougge.NativeFunctions::createGameObject", (void*)createGameObject_callback);
|
||||||
|
|
||||||
|
auto freeGameObject_callback = static_cast<bool(*)(u32)>(
|
||||||
|
[](u32 index) -> bool {
|
||||||
|
std::cout<<"freeGameObject_callback"<<std::endl;
|
||||||
|
return this_static->gameObjectPool.erase(index);
|
||||||
|
}
|
||||||
|
);
|
||||||
|
mono_add_internal_call("Ougge.NativeFunctions::freeGameObject", (void*)freeGameObject_callback);
|
||||||
}
|
}
|
||||||
|
|
||||||
void MonoGameObjectSystem::beginFrame(){
|
void MonoGameObjectSystem::beginFrame(){
|
||||||
for(auto pair : gameObjectPool){
|
for(auto pair : gameObjectPool){
|
||||||
gameObjectInvokeUpdate(pair.second.getObjectHandle().getObject(), engine.deltaTime);
|
|
||||||
|
auto obj = pair.second.getObjectHandle().getObject();
|
||||||
|
std::cout<<"updating obj: "<<obj<<std::endl;
|
||||||
|
gameObjectInvokeUpdate(obj, engine.deltaTime);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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)));
|
auto pair = gameObjectPool.emplace(game::GameObject(mono.createObject(gameObjectClass)));
|
||||||
|
*id_out = ++obj_id;
|
||||||
|
*index_out = pair.first;
|
||||||
game::GameObject& obj = pair.second;
|
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;
|
return obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -24,8 +24,12 @@ public:
|
|||||||
const std::string& getName() override;
|
const std::string& getName() override;
|
||||||
void beginFrame() override;
|
void beginFrame() override;
|
||||||
|
|
||||||
game::GameObject& createGameObject();
|
game::GameObject& createAndConstructGameObject();
|
||||||
bool tryCreateComponent(game::GameObject& obj, const std::string& componentClassName);
|
bool tryCreateComponent(game::GameObject& obj, const std::string& componentClassName);
|
||||||
|
|
||||||
|
private:
|
||||||
|
void registerNativeCallbacks();
|
||||||
|
game::GameObject& createGameObjectInPool(u64* id_out, u32* index_out);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user