_dotnet events
This commit is contained in:
@@ -872,6 +872,13 @@ void VisualScriptExecutor::ProcessGroupFunction(Box* boxBase, Node* node, Value&
|
|||||||
|
|
||||||
// Find event binding callback
|
// Find event binding callback
|
||||||
auto eventBinder = ScriptingEvents::EventsTable.TryGet(Pair<ScriptingTypeHandle, StringView>(eventType, eventName));
|
auto eventBinder = ScriptingEvents::EventsTable.TryGet(Pair<ScriptingTypeHandle, StringView>(eventType, eventName));
|
||||||
|
if (!eventBinder)
|
||||||
|
{
|
||||||
|
const StringAnsiView eventNameAnsi(node->Values[1]);
|
||||||
|
auto managedEvent = eventType.GetClass()->GetEvent(eventNameAnsi.GetText());
|
||||||
|
//eventBinder = (void(**)(ScriptingObject*, void*, bool))managedEvent;
|
||||||
|
}
|
||||||
|
|
||||||
if (!eventBinder)
|
if (!eventBinder)
|
||||||
{
|
{
|
||||||
LOG(Error, "Cannot bind to missing event {0} from type {1}.", eventName, eventTypeName);
|
LOG(Error, "Cannot bind to missing event {0} from type {1}.", eventName, eventTypeName);
|
||||||
|
|||||||
@@ -45,6 +45,16 @@ namespace FlaxEngine.Interop
|
|||||||
internal uint fieldAttributes;
|
internal uint fieldAttributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
|
internal struct NativeEventDefinitions
|
||||||
|
{
|
||||||
|
internal IntPtr name;
|
||||||
|
internal ManagedHandle eventHandle;
|
||||||
|
internal ManagedHandle addMethodHandle;
|
||||||
|
internal ManagedHandle removeMethodHandle;
|
||||||
|
internal uint attributes;
|
||||||
|
}
|
||||||
|
|
||||||
[StructLayout(LayoutKind.Sequential)]
|
[StructLayout(LayoutKind.Sequential)]
|
||||||
internal struct NativePropertyDefinitions
|
internal struct NativePropertyDefinitions
|
||||||
{
|
{
|
||||||
@@ -368,6 +378,46 @@ namespace FlaxEngine.Interop
|
|||||||
*classFieldsCount = fields.Length;
|
*classFieldsCount = fields.Length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[UnmanagedCallersOnly]
|
||||||
|
internal static void GetClassEvents(ManagedHandle typeHandle, NativeEventDefinitions** classEvents, int* classEventCount)
|
||||||
|
{
|
||||||
|
Type type = Unsafe.As<TypeHolder>(typeHandle.Target);
|
||||||
|
var events = type.GetEvents(BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic);
|
||||||
|
|
||||||
|
var arr = (NativeEventDefinitions*)NativeAlloc(events.Length, Unsafe.SizeOf<NativeEventDefinitions>());
|
||||||
|
for (int i = 0; i < events.Length; i++)
|
||||||
|
{
|
||||||
|
IntPtr ptr = IntPtr.Add(new IntPtr(arr), Unsafe.SizeOf<NativeEventDefinitions>() * i);
|
||||||
|
|
||||||
|
ManagedHandle eventHandle = ManagedHandle.Alloc(events[i]);
|
||||||
|
var raiseMethod = events[i].GetRaiseMethod(true);
|
||||||
|
var addMethod = events[i].GetAddMethod(true);
|
||||||
|
var removeMethod = events[i].GetRemoveMethod(true);
|
||||||
|
|
||||||
|
var classEvent = new NativeEventDefinitions
|
||||||
|
{
|
||||||
|
name = NativeAllocStringAnsi(events[i].Name),
|
||||||
|
eventHandle = eventHandle,
|
||||||
|
attributes = (uint)(addMethod?.Attributes ?? removeMethod?.Attributes ?? MethodAttributes.PrivateScope),
|
||||||
|
};
|
||||||
|
/*if (raiseMethod != null)
|
||||||
|
{
|
||||||
|
classEvent.raiseMethodHandle = GetMethodGCHandle(raiseMethod);
|
||||||
|
}*/
|
||||||
|
if (addMethod != null)
|
||||||
|
{
|
||||||
|
classEvent.addMethodHandle = GetMethodGCHandle(addMethod);
|
||||||
|
}
|
||||||
|
if (removeMethod != null)
|
||||||
|
{
|
||||||
|
classEvent.removeMethodHandle = GetMethodGCHandle(removeMethod);
|
||||||
|
}
|
||||||
|
Unsafe.Write(ptr.ToPointer(), classEvent);
|
||||||
|
}
|
||||||
|
*classEvents = arr;
|
||||||
|
*classEventCount = events.Length;
|
||||||
|
}
|
||||||
|
|
||||||
[UnmanagedCallersOnly]
|
[UnmanagedCallersOnly]
|
||||||
internal static void GetClassProperties(ManagedHandle typeHandle, NativePropertyDefinitions** classProperties, int* classPropertiesCount)
|
internal static void GetClassProperties(ManagedHandle typeHandle, NativePropertyDefinitions** classProperties, int* classPropertiesCount)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ public:
|
|||||||
#if USE_MONO
|
#if USE_MONO
|
||||||
explicit MEvent(MonoEvent* monoEvent, const char* name, MClass* parentClass);
|
explicit MEvent(MonoEvent* monoEvent, const char* name, MClass* parentClass);
|
||||||
#elif USE_NETCORE
|
#elif USE_NETCORE
|
||||||
MEvent(MClass* parentClass, void* handle, const char* name);
|
MEvent(MClass* parentClass, void* handle, void* addMethodHandle, void* removeMethodHandle, MMethodAttributes attributes, const char* name);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|||||||
@@ -241,6 +241,15 @@ struct NativeFieldDefinitions
|
|||||||
MFieldAttributes fieldAttributes;
|
MFieldAttributes fieldAttributes;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct NativeEventDefinitions
|
||||||
|
{
|
||||||
|
const char* name;
|
||||||
|
void* eventHandle;
|
||||||
|
void* addMethodHandle;
|
||||||
|
void* removeMethodHandle;
|
||||||
|
MMethodAttributes attributes;
|
||||||
|
};
|
||||||
|
|
||||||
struct NativePropertyDefinitions
|
struct NativePropertyDefinitions
|
||||||
{
|
{
|
||||||
const char* name;
|
const char* name;
|
||||||
@@ -1045,7 +1054,23 @@ const Array<MEvent*>& MClass::GetEvents() const
|
|||||||
if (_hasCachedEvents)
|
if (_hasCachedEvents)
|
||||||
return _events;
|
return _events;
|
||||||
|
|
||||||
// TODO: implement MEvent in .NET
|
ScopeLock lock(BinaryModule::Locker);
|
||||||
|
if (_hasCachedEvents)
|
||||||
|
return _events;
|
||||||
|
|
||||||
|
NativeEventDefinitions* foundEvents;
|
||||||
|
int numEvents;
|
||||||
|
static void* GetClassEventsPtr = GetStaticMethodPointer(TEXT("GetClassEvents"));
|
||||||
|
CallStaticMethod<void, void*, NativeEventDefinitions**, int*>(GetClassEventsPtr, _handle, &foundEvents, &numEvents);
|
||||||
|
_events.SetCapacity(numEvents, false);
|
||||||
|
for (int i = 0; i < numEvents; i++)
|
||||||
|
{
|
||||||
|
const NativeEventDefinitions& definition = foundEvents[i];
|
||||||
|
MEvent* evnt = New<MEvent>(const_cast<MClass*>(this), definition.eventHandle, definition.addMethodHandle, definition.removeMethodHandle, definition.attributes, definition.name);
|
||||||
|
_events.Add(evnt);
|
||||||
|
MCore::GC::FreeMemory((void*)definition.name);
|
||||||
|
}
|
||||||
|
MCore::GC::FreeMemory(foundEvents);
|
||||||
|
|
||||||
_hasCachedEvents = true;
|
_hasCachedEvents = true;
|
||||||
return _events;
|
return _events;
|
||||||
@@ -1154,26 +1179,33 @@ void MDomain::Dispatch() const
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
MEvent::MEvent(MClass* parentClass, void* handle, const char* name)
|
MEvent::MEvent(MClass* parentClass, void* handle, void* addMethodHandle, void* removeMethodHandle, MMethodAttributes attributes, const char* name)
|
||||||
: _handle(handle)
|
: _handle(handle)
|
||||||
, _addMethod(nullptr)
|
|
||||||
, _removeMethod(nullptr)
|
|
||||||
, _parentClass(parentClass)
|
, _parentClass(parentClass)
|
||||||
, _name(name)
|
, _name(name)
|
||||||
, _hasCachedAttributes(false)
|
, _hasCachedAttributes(false)
|
||||||
, _hasAddMonoMethod(true)
|
|
||||||
, _hasRemoveMonoMethod(true)
|
|
||||||
{
|
{
|
||||||
|
//_raiseMethod = New<MMethod>(parentClass, StringAnsi("raise_" + _name), handle, 1, attributes);
|
||||||
|
_hasAddMonoMethod = addMethodHandle != nullptr;
|
||||||
|
if (_hasAddMonoMethod)
|
||||||
|
_addMethod = New<MMethod>(parentClass, StringAnsi("add_" + _name), addMethodHandle, 1, attributes);
|
||||||
|
else
|
||||||
|
_addMethod = nullptr;
|
||||||
|
_hasRemoveMonoMethod = removeMethodHandle != nullptr;
|
||||||
|
if (_hasRemoveMonoMethod)
|
||||||
|
_removeMethod = New<MMethod>(parentClass, StringAnsi("remove_" + _name), removeMethodHandle, 1, attributes);
|
||||||
|
else
|
||||||
|
_removeMethod = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
MMethod* MEvent::GetAddMethod() const
|
MMethod* MEvent::GetAddMethod() const
|
||||||
{
|
{
|
||||||
return nullptr; // TODO: implement MEvent in .NET
|
return _addMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
MMethod* MEvent::GetRemoveMethod() const
|
MMethod* MEvent::GetRemoveMethod() const
|
||||||
{
|
{
|
||||||
return nullptr; // TODO: implement MEvent in .NET
|
return _removeMethod;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool MEvent::HasAttribute(MClass* monoClass) const
|
bool MEvent::HasAttribute(MClass* monoClass) const
|
||||||
|
|||||||
Reference in New Issue
Block a user