created Engine class
This commit is contained in:
parent
366dd1214c
commit
3477b05cd8
@ -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)
|
||||
|
||||
37
src/Game/Engine.cpp
Normal file
37
src/Game/Engine.cpp
Normal file
@ -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<void(u64, u32)>(gameObjectClass, ".ctor");
|
||||
gameObjectInvokeUpdate = Mono::Method<void(f64)>(gameObjectClass, "InvokeUpdate");
|
||||
gameObjectTryCreateComponent = Mono::Method<Mono::Bool(Mono::String)>(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;
|
||||
}
|
||||
|
||||
}
|
||||
30
src/Game/Engine.hpp
Normal file
30
src/Game/Engine.hpp
Normal file
@ -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<void(u64, u32)> gameObjectCtor;
|
||||
Mono::Method<void(f64)> gameObjectInvokeUpdate;
|
||||
Mono::Method<Mono::Bool(Mono::String)> gameObjectTryCreateComponent;
|
||||
|
||||
public:
|
||||
Mono::RuntimeJIT mono;
|
||||
std::shared_ptr<Mono::Assembly> engineManagedAssembly;
|
||||
|
||||
Engine();
|
||||
void init();
|
||||
void invokeUpdate(f64 deltaTime);
|
||||
|
||||
GameObject& createGameObject();
|
||||
bool tryCreateComponent(GameObject& obj, const std::string& componentClassName);
|
||||
};
|
||||
|
||||
}
|
||||
@ -1,5 +1,7 @@
|
||||
#include "GameObject.hpp"
|
||||
|
||||
namespace ougge {
|
||||
|
||||
std::ostream& operator<<(std::ostream& s, Transform& t){
|
||||
s<<"{ position: {x: "<<t.position.x<<", y: "<<t.position.y;
|
||||
s<<"}, rotation: "<<t.rotation;
|
||||
@ -14,8 +16,7 @@ GameObject::GameObject(Mono::Object managed_obj)
|
||||
GameObject::GameObject(GameObject &&o) :
|
||||
object_handle(std::move(o.object_handle)),
|
||||
parent(o.parent),
|
||||
transform(o.transform),
|
||||
components(std::move(o.components))
|
||||
transform(o.transform)
|
||||
{
|
||||
}
|
||||
|
||||
@ -23,16 +24,7 @@ GameObject& GameObject::operator=(GameObject &&o){
|
||||
object_handle = std::move(o.object_handle);
|
||||
parent = o.parent;
|
||||
transform = o.transform;
|
||||
components = std::move(o.components);
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool GameObject::tryGetComponent(const std::u16string &name, Component **out_component)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool GameObject::tryAddComponent(const std::u16string &name, Component &&component)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ -6,15 +6,9 @@
|
||||
#include "../UsefulException.hpp"
|
||||
#include "../Mono/Mono.hpp"
|
||||
|
||||
class GameObject;
|
||||
namespace ougge {
|
||||
|
||||
class Component {
|
||||
Mono::ObjectHandle object_handle;
|
||||
GameObject* owner;
|
||||
public:
|
||||
inline Component(Mono::Object managed_obj, GameObject* owner)
|
||||
: object_handle(managed_obj), owner(owner) {}
|
||||
};
|
||||
class GameObject;
|
||||
|
||||
struct Transform {
|
||||
Vec2 scale = { 1, 1 };
|
||||
@ -29,7 +23,7 @@ class GameObject {
|
||||
Mono::ObjectHandle object_handle;
|
||||
GameObject* parent;
|
||||
Transform transform;
|
||||
std::map<std::u16string, Component> 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; }
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
#include <bit>
|
||||
#include <cstring>
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -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;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
@ -1,7 +0,0 @@
|
||||
#pragma once
|
||||
|
||||
#include "GameObject.hpp"
|
||||
|
||||
class Scene {
|
||||
|
||||
};
|
||||
@ -69,30 +69,7 @@ class Method<ReturnT(ArgTypes...)>
|
||||
MonoMethod* method_ptr;
|
||||
|
||||
public:
|
||||
|
||||
template<typename RT = ReturnT>
|
||||
std::enable_if_t<!std::is_void<RT>::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<ReturnT>(result);
|
||||
};
|
||||
template<typename RT = ReturnT>
|
||||
std::enable_if_t<std::is_void<RT>::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<T>()
|
||||
Method(MonoClass* target_class, const std::string& name){
|
||||
@ -104,6 +81,37 @@ public:
|
||||
name.c_str(), mono_class_get_name(target_class)));
|
||||
}
|
||||
}
|
||||
|
||||
template<typename RT = ReturnT>
|
||||
std::enable_if_t<!std::is_void<RT>::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<ReturnT>(result);
|
||||
};
|
||||
|
||||
template<typename RT = ReturnT>
|
||||
std::enable_if_t<std::is_void<RT>::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<Assembly> 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.
|
||||
|
||||
61
src/main.cpp
61
src/main.cpp
@ -3,66 +3,35 @@
|
||||
#include <iomanip>
|
||||
#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 '"<<LABEL<<"' took "<<t/1e6f<<" ms"<<std::endl;\
|
||||
}\
|
||||
|
||||
|
||||
std::vector<GUI::UpdateFunc_t> 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"<<std::endl;
|
||||
|
||||
Mono::RuntimeJIT mono;
|
||||
Engine engine;
|
||||
std::cout<<"initialized mono jit runtime"<<std::endl;
|
||||
GameObjectPool p(GAMEOBJECTPOOL_SIZE);
|
||||
|
||||
auto a = mono.loadAssembly("Ougge.dll");
|
||||
MonoClass* gameObjectClass = a->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<void(u64, u32)>(gameObjectClass, ".ctor");
|
||||
gameObjectCtor(exampleObjectHandle.getObject(), obj_id++, pair.first);
|
||||
|
||||
auto exampleObjectUpdate = Mono::Method<void(f64)>(gameObjectClass, "InvokeUpdate");
|
||||
updateCallbacks.push_back([&exampleObjectHandle, exampleObjectUpdate](f64 deltaTime) -> void {
|
||||
exampleObjectUpdate(exampleObjectHandle.getObject(), deltaTime);
|
||||
});
|
||||
|
||||
auto tryCreateComponent = Mono::Method<Mono::Bool(Mono::String)>(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"<<std::endl;
|
||||
|
||||
GameObject& exampleObj = engine.createGameObject();
|
||||
std::string componentClassName = "Ougge.ExampleComponent";
|
||||
if(!engine.tryCreateComponent(exampleObj, componentClassName))
|
||||
throw UsefulException(format("couldn't create component '%s'", componentClassName.c_str()));
|
||||
|
||||
std::cout<<"created ExampleObject"<<std::endl;
|
||||
|
||||
auto updateCallback = [&engine](f64 deltaTime) -> void {
|
||||
engine.invokeUpdate(deltaTime);
|
||||
};
|
||||
|
||||
GUI::MainWindow w;
|
||||
w.open("ougge", update);
|
||||
w.open("ougge", updateCallback);
|
||||
std::cout<<"created sdl window"<<std::endl;
|
||||
w.startUpdateLoop();
|
||||
std::cout<<"sdl window has been cosed"<<std::endl;
|
||||
|
||||
10
src/time.hpp
10
src/time.hpp
@ -8,3 +8,13 @@ typedef i64 nsec_t;
|
||||
/// can be used to measure delta time
|
||||
///@return time from some moment in nanoseconds.
|
||||
nsec_t getMonotonicTimeNsec();
|
||||
|
||||
#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 '"<<LABEL<<"' took "<<t/1e6f<<" ms"<<std::endl;\
|
||||
}
|
||||
|
||||
Loading…
Reference in New Issue
Block a user