calling mono_gchandle_get_target instead of using expiring raw pointers
This commit is contained in:
parent
5d84e744ce
commit
5c247ce032
@ -24,6 +24,8 @@ typedef f64 Double;
|
|||||||
typedef union { mono_bool wide_bool; } Bool; //USAGE: Bool t = {true};
|
typedef union { mono_bool wide_bool; } Bool; //USAGE: Bool t = {true};
|
||||||
typedef char16_t Char;
|
typedef char16_t Char;
|
||||||
typedef MonoString* String;
|
typedef MonoString* String;
|
||||||
|
/// @warning MonoObject can be moved in memory by GC in any time and raw pointer will be invalid.
|
||||||
|
/// Use ObjectHandle where it is possible.
|
||||||
typedef MonoObject* Object;
|
typedef MonoObject* Object;
|
||||||
typedef void Void;
|
typedef void Void;
|
||||||
|
|
||||||
@ -133,25 +135,39 @@ public:
|
|||||||
std::shared_ptr<Assembly> loadAssembly(const std::string& name);
|
std::shared_ptr<Assembly> loadAssembly(const std::string& name);
|
||||||
};
|
};
|
||||||
|
|
||||||
class ObjectHandle {
|
/// @brief ObjectHandle can be used to store reliable reference to MonoObject.
|
||||||
Object object;
|
/// MonoObject can be moved in memory by GC in any time and raw pointer will be invalid.
|
||||||
|
struct ObjectHandle {
|
||||||
u32 gc_handle;
|
u32 gc_handle;
|
||||||
public:
|
|
||||||
inline ObjectHandle() : object(nullptr), gc_handle(0) {}
|
inline ObjectHandle() : gc_handle(0) {}
|
||||||
inline ObjectHandle(Object obj) : object(obj) { gc_handle = mono_gchandle_new(obj, false); }
|
|
||||||
|
inline ObjectHandle(Object obj) {
|
||||||
|
gc_handle = mono_gchandle_new(obj, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// implicitly create new ObjectHandle instead
|
||||||
inline ObjectHandle(const ObjectHandle& o) = delete;
|
inline ObjectHandle(const ObjectHandle& o) = delete;
|
||||||
inline ObjectHandle(ObjectHandle&& o)
|
|
||||||
: object(o.object), gc_handle(o.gc_handle)
|
inline ObjectHandle(ObjectHandle&& o) {
|
||||||
{ o.gc_handle = 0; };
|
gc_handle = o.gc_handle;
|
||||||
|
o.gc_handle = 0;
|
||||||
|
}
|
||||||
|
|
||||||
inline ObjectHandle& operator=(ObjectHandle&& o) {
|
inline ObjectHandle& operator=(ObjectHandle&& o) {
|
||||||
object = o.object;
|
|
||||||
gc_handle = o.gc_handle;
|
gc_handle = o.gc_handle;
|
||||||
o.gc_handle = 0;
|
o.gc_handle = 0;
|
||||||
return *this;
|
return *this;
|
||||||
};
|
}
|
||||||
inline ~ObjectHandle() { if(gc_handle) mono_gchandle_free(gc_handle); }
|
|
||||||
inline Object getObject() const { return object; }
|
inline ~ObjectHandle() {
|
||||||
inline u32 getGCHandle() const { return gc_handle; }
|
if(gc_handle)
|
||||||
|
mono_gchandle_free(gc_handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Object getObject() const {
|
||||||
|
return mono_gchandle_get_target(gc_handle);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
15
src/main.cpp
15
src/main.cpp
@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
using namespace ougge;
|
using namespace ougge;
|
||||||
|
|
||||||
#define GAMEOBJECTPOOL_SIZE 64*1024
|
#define GAMEOBJECTPOOL_SIZE 64
|
||||||
|
|
||||||
#define optime(N, LABEL, CODE) {\
|
#define optime(N, LABEL, CODE) {\
|
||||||
nsec_t b = getMonotonicTimeNsec();\
|
nsec_t b = getMonotonicTimeNsec();\
|
||||||
@ -43,21 +43,20 @@ int main(int argc, const char** argv){
|
|||||||
|
|
||||||
auto a = mono.loadAssembly("Ougge.dll");
|
auto a = mono.loadAssembly("Ougge.dll");
|
||||||
MonoClass* gameObjectClass = a->getClass("Ougge", "GameObject");
|
MonoClass* gameObjectClass = a->getClass("Ougge", "GameObject");
|
||||||
MonoObject* exampleObjectManaged = mono_object_new(mono.getDomain(), gameObjectClass);
|
|
||||||
u64 obj_id = 0;
|
u64 obj_id = 0;
|
||||||
auto pair = p.emplace(GameObject(exampleObjectManaged));
|
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");
|
auto gameObjectCtor = Mono::Method<void(u64, u32)>(gameObjectClass, ".ctor");
|
||||||
gameObjectCtor(exampleObjectManaged, obj_id++, pair.first);
|
gameObjectCtor(exampleObjectHandle.getObject(), obj_id++, pair.first);
|
||||||
|
|
||||||
auto exampleObjectUpdate = Mono::Method<void(f64)>(gameObjectClass, "InvokeUpdate");
|
auto exampleObjectUpdate = Mono::Method<void(f64)>(gameObjectClass, "InvokeUpdate");
|
||||||
updateCallbacks.push_back([exampleObjectManaged, exampleObjectUpdate](f64 deltaTime) -> void {
|
updateCallbacks.push_back([&exampleObjectHandle, exampleObjectUpdate](f64 deltaTime) -> void {
|
||||||
exampleObjectUpdate(exampleObjectManaged, deltaTime);
|
exampleObjectUpdate(exampleObjectHandle.getObject(), deltaTime);
|
||||||
});
|
});
|
||||||
|
|
||||||
auto tryCreateComponent = Mono::Method<Mono::Bool(Mono::String)>(gameObjectClass, "TryCreateComponent_internal");
|
auto tryCreateComponent = Mono::Method<Mono::Bool(Mono::String)>(gameObjectClass, "TryCreateComponent_internal");
|
||||||
Mono::String componentNameManaged = mono_string_new(mono.getDomain(), "Ougge.ExampleComponent");
|
Mono::String componentNameManaged = mono_string_new(mono.getDomain(), "Ougge.ExampleComponent");
|
||||||
// Mono::ObjectHandle componentNameObjectHandle((MonoObject*)(void*)componentNameManaged);
|
Mono::Bool created = tryCreateComponent(exampleObjectHandle.getObject(), componentNameManaged);
|
||||||
Mono::Bool created = tryCreateComponent(exampleObjectManaged, componentNameManaged);
|
|
||||||
if(!created.wide_bool)
|
if(!created.wide_bool)
|
||||||
throw UsefulException("couldn't create ExampleComponent");
|
throw UsefulException("couldn't create ExampleComponent");
|
||||||
|
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user