Добавлена поддержка событий MTA

This commit is contained in:
Kernell 2015-12-05 13:26:07 +03:00
parent cb6432cffa
commit d293747f26
20 changed files with 871 additions and 50 deletions

@ -1 +1 @@
Subproject commit 13961748c6550de5674644eb0048f20460fa46c8 Subproject commit fe32901717e73b39b133449512e9ca7230ef37c4

View File

@ -9,18 +9,32 @@ namespace Test
{ {
static void Main( string[] args ) static void Main( string[] args )
{ {
Element.Root.OnElementDestroy += Root_ElementDestroy; Element.Root.OnElementDestroy += ( Element sender, ElementEventArgs e ) =>
{
Debug.Info( "lambda " + sender.GetType() + " " + e.This.GetType() );
};
Vehicle vehicle = new Vehicle( VehicleModel.ADMIRAL, Vector3.Zero, Vector3.Zero ); Vehicle vehicle = new Vehicle( VehicleModel.ADMIRAL, Vector3.Zero, Vector3.Zero );
vehicle.OnElementDestroy += Root_ElementDestroy; vehicle.OnElementDestroy += Root_ElementDestroy;
vehicle.Destroy(); Event.Add( "onTest", true );
Event.AddHandler( "onTest", vehicle, new Action<Element, string, char, bool>( testEvent_OnTrigger ) );
Event.Trigger( "onTest", vehicle, "test", 'a', true, false, 123, 456.7f, 1337.01d, null, vehicle );
//vehicle.Destroy();
} }
public static void Root_ElementDestroy( Element sender, ElementEventArgs e ) static void testEvent_OnTrigger( Element sender, string a, char b, bool c )
{ {
Debug.Info( "Root_ElementDestroy {0} {1}", sender.GetType(), e.This.GetType() ); Debug.Info( "testEvent_OnTrigger " + sender.GetType() + " " + a + " " + b + " " + c );
}
static void Root_ElementDestroy( Element sender, ElementEventArgs e )
{
Debug.Info( "Root_ElementDestroy " + sender.GetType() + " " + e.This.GetType() );
} }
} }
} }

View File

@ -142,6 +142,8 @@
</Link> </Link>
</ItemDefinitionGroup> </ItemDefinitionGroup>
<ItemGroup> <ItemGroup>
<ClCompile Include="src\CEvent.cpp" />
<ClCompile Include="src\CEventManager.cpp" />
<ClCompile Include="src\CMonoClass.cpp" /> <ClCompile Include="src\CMonoClass.cpp" />
<ClCompile Include="src\CMonoCorlib.cpp" /> <ClCompile Include="src\CMonoCorlib.cpp" />
<ClCompile Include="src\CMonoDomain.cpp" /> <ClCompile Include="src\CMonoDomain.cpp" />
@ -187,6 +189,8 @@
</ClCompile> </ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="src\CEvent.h" />
<ClInclude Include="src\CEventManager.h" />
<ClInclude Include="src\CMonoClass.h" /> <ClInclude Include="src\CMonoClass.h" />
<ClInclude Include="src\CMonoCorlib.h" /> <ClInclude Include="src\CMonoCorlib.h" />
<ClInclude Include="src\CMonoDomain.h" /> <ClInclude Include="src\CMonoDomain.h" />

View File

@ -115,6 +115,12 @@
<ClCompile Include="src\CFunctions.cpp"> <ClCompile Include="src\CFunctions.cpp">
<Filter>Lua</Filter> <Filter>Lua</Filter>
</ClCompile> </ClCompile>
<ClCompile Include="src\CEventManager.cpp">
<Filter>ResourceInterface</Filter>
</ClCompile>
<ClCompile Include="src\CEvent.cpp">
<Filter>ResourceInterface</Filter>
</ClCompile>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<ClInclude Include="src\include\ILuaModuleManager.h"> <ClInclude Include="src\include\ILuaModuleManager.h">
@ -266,6 +272,12 @@
<ClInclude Include="src\CFunctions.h"> <ClInclude Include="src\CFunctions.h">
<Filter>Lua</Filter> <Filter>Lua</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="src\CEventManager.h">
<Filter>ResourceInterface</Filter>
</ClInclude>
<ClInclude Include="src\CEvent.h">
<Filter>ResourceInterface</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Filter Include="MonoInterface"> <Filter Include="MonoInterface">

51
mta-mono/src/CEvent.cpp Normal file
View File

@ -0,0 +1,51 @@
/*********************************************************
*
* Copyright © 2013, Innovation Roleplay Engine.
*
* All Rights Reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification,
* is permitted only for authors.
*
*********************************************************/
#include "CEvent.h"
CEvent::CEvent( CEventManager* pEventManager, string strName, DWORD pElement, MonoObject* pMonoDelegate, bool bPropagated, string strPriority )
{
this->m_pEventManager = pEventManager;
this->m_strName = strName;
this->m_pElement = pElement;
this->m_pMonoDelegate = pMonoDelegate;
this->m_bPropagated = bPropagated;
this->m_strPriority = strPriority;
}
CEvent::~CEvent( void )
{
this->m_pMonoDelegate = nullptr;
this->m_bPropagated = nullptr;
this->m_pEventManager = nullptr;
}
bool CEvent::Call( DWORD pThis, void** params )
{
CResource* pResource = this->m_pEventManager->GetResource();
assert( pResource );
CMonoMTALib* pMTALib = pResource->GetDomain()->GetMTALib();
assert( pMTALib );
MonoObject* pException = nullptr;
mono_runtime_delegate_invoke( this->m_pMonoDelegate, params, &pException );
pResource->GetDomain()->HandleException( pException );
return pException == nullptr;
}

49
mta-mono/src/CEvent.h Normal file
View File

@ -0,0 +1,49 @@
/*********************************************************
*
* Copyright © 2013, Innovation Roleplay Engine.
*
* All Rights Reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification,
* is permitted only for authors.
*
*********************************************************/
class CEvent;
#ifndef __CEVENT_H
#define __CEVENT_H
#include "extra/CLuaArgument.h"
#include "extra/CLuaArguments.h"
#include "CResource.h"
#include "CEventManager.h"
class CEvent
{
private:
string m_strName;
DWORD m_pElement;
MonoObject* m_pMonoDelegate;
bool m_bPropagated;
string m_strPriority;
CEventManager* m_pEventManager;
public:
CEvent ( CEventManager* pEventManager, string strName, DWORD pElement, MonoObject* pMonoDelegate, bool bPropagated, string strPriority );
~CEvent ( void );
bool Call ( DWORD pThis, void** params );
string GetName ( void ) { return this->m_strName; }
DWORD GetElement ( void ) { return this->m_pElement; }
MonoObject* GetDelegate ( void ) { return this->m_pMonoDelegate; }
bool IsPropagated ( void ) { return this->m_bPropagated; }
string GetPriority ( void ) { return this->m_strPriority; }
};
#endif

View File

@ -0,0 +1,196 @@
/*********************************************************
*
* Copyright © 2013, Innovation Roleplay Engine.
*
* All Rights Reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification,
* is permitted only for authors.
*
*********************************************************/
#include "CEventManager.h"
CEventManager::CEventManager( CResource* pResource )
{
this->m_pResource = pResource;
}
CEventManager::~CEventManager( void )
{
this->DeleteAll();
this->m_pResource = nullptr;
}
bool CEventManager::Add( string strName, DWORD pUserData, MonoObject* pMonoDelegate, bool bPropagated, string strPriority )
{
if( !pUserData )
{
return false;
}
CEvent* pEvent = new CEvent( this, strName, pUserData, pMonoDelegate, bPropagated, strPriority );
this->m_Events.insert( pair< string, CEvent* >( pEvent->GetName(), pEvent ) );
return true;
}
bool CEventManager::Delete( string strName, DWORD pUserData, MonoObject* pMonoDelegate )
{
bool bFind = false;
for( auto iter = this->m_Events.begin(); iter != this->m_Events.end(); iter++ )
{
CEvent* pEvent = iter->second;
if( pEvent->GetName() == strName && ( pMonoDelegate == nullptr || pEvent->GetDelegate() == pMonoDelegate ) )
{
delete pEvent;
this->m_Events.erase( iter );
bFind = true;
}
}
return bFind;
}
void CEventManager::DeleteAll( void )
{
multimap< string, CEvent* >::iterator iter = this->m_Events.begin();
while( iter != this->m_Events.end() )
{
CEvent* pEvent = iter->second;
delete pEvent;
this->m_Events.erase( iter++ );
}
}
bool CEventManager::Call( string strName, void* pThis, list< CLuaArgument* > Arguments )
{
CMonoMTALib* pMTALib = this->GetResource()->GetDomain()->GetMTALib();
MonoObject* pThisObj = pMTALib->RegisterElement( pThis );
if( !pThisObj )
{
return false;
}
DWORD pSource = 0;
auto *iter = *Arguments.begin();
if( iter->GetType() == LUA_TLIGHTUSERDATA )
{
pSource = (DWORD)iter->GetLightUserData();
}
void** params = new void*[ Arguments.size() ];
this->ReadArgumens( Arguments, params );
for( auto iter : this->m_Events )
{
CEvent* pEvent = iter.second;
DWORD pElement = pEvent->GetElement();
if( pEvent->GetName() == strName && ( pElement == (DWORD)pThis || ( pEvent->IsPropagated() && pElement == pSource ) ) )
{
pEvent->Call( (DWORD)pThis, params );
}
}
delete[] params;
CMonoClass* pClass = pMTALib->GetClass( "Element" );
assert( pClass );
strName[ 0 ] = toupper( strName[ 0 ] );
CMonoEvent* pEvent = pClass->GetEvent( strName );
if( pEvent )
{
return pEvent->Call( pThisObj, Arguments );
}
return true;
}
void CEventManager::ReadArgumens( list< CLuaArgument* > Arguments, void** params )
{
CMonoDomain* pDomain = this->GetResource()->GetDomain();
CMonoMTALib* pMTALib = pDomain->GetMTALib();
CMonoCorlib* pCorlib = pDomain->GetCorlib();
uint argc = 0;
for( auto iter : Arguments )
{
int iLuaType = iter->GetType();
switch( iLuaType )
{
case LUA_TBOOLEAN:
{
bool bValue = iter->GetBoolean();
params[ argc++ ] = &bValue;
break;
}
case LUA_TNUMBER:
{
double value = iter->GetNumber< double >();
MonoObject* pObj = pCorlib->Class[ "double" ]->Box( &value );
params[ argc++ ] = pObj;
break;
}
case LUA_TSTRING:
{
const char* szValue = iter->GetString();
MonoString* pString = pDomain->NewString( szValue );
params[ argc++ ] = pString;
break;
}
case LUA_TLIGHTUSERDATA:
{
void* pUserData = iter->GetLightUserData();
MonoObject* pValue = pMTALib->RegisterElement( pUserData );
if( pValue )
{
params[ argc++ ] = pValue;
}
else
{
params[ argc++ ] = pUserData;
}
break;
}
default:
{
break;
}
}
}
}

View File

@ -0,0 +1,46 @@
/*********************************************************
*
* Copyright © 2013, Innovation Roleplay Engine.
*
* All Rights Reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification,
* is permitted only for authors.
*
*********************************************************/
class CEventManager;
#ifndef __CEVENTMANAGER_H
#define __CEVENTMANAGER_H
#include "CResource.h"
#include "CMonoDomain.h"
#include "CEvent.h"
#include "extra/CLuaArgument.h"
#include "extra/CLuaArguments.h"
class CEventManager
{
private:
CResource* m_pResource;
multimap< string, CEvent* > m_Events;
public:
CEventManager ( CResource* pResource );
~CEventManager ( void );
bool Add ( string strName, DWORD pUserData, MonoObject* pMonoDelegate, bool bPropagated, string strPriority );
bool Delete ( string strName, DWORD pUserData, MonoObject* pMonoDelegate = nullptr );
void DeleteAll ( void );
bool Call ( string strName, void* pThis, list< CLuaArgument* > Arguments );
void ReadArgumens ( list< CLuaArgument* > Arguments, void** params );
CResource* GetResource( void ) { return this->m_pResource; }
};
#endif

View File

@ -21,8 +21,6 @@ int CFunctions::monoInit( lua_State *pLuaVM )
if( pResource == nullptr ) if( pResource == nullptr )
{ {
//if( g_pModuleManager->GetResourceName( luaVM, strName ) )
CLuaArgument pLuaArgument( pLuaVM, -1 ); CLuaArgument pLuaArgument( pLuaVM, -1 );
string strName = pLuaArgument.GetString(); string strName = pLuaArgument.GetString();
@ -78,8 +76,6 @@ int CFunctions::monoEventHandler( lua_State *pLuaVM )
{ {
strEventName = iter->GetString(); strEventName = iter->GetString();
strEventName[ 0 ] = toupper( strEventName[ 0 ] );
break; break;
} }
case 2: case 2:

View File

@ -27,8 +27,8 @@ extern ILuaModuleManager10 *g_pModuleManager;
class CFunctions class CFunctions
{ {
public: public:
static int monoInit ( lua_State *pLuaVM ); static int monoInit ( lua_State *pLuaVM );
static int monoEventHandler ( lua_State *pLuaVM ); static int monoEventHandler ( lua_State *pLuaVM );
}; };
#endif #endif

View File

@ -221,10 +221,10 @@ list< CMonoMethod* > CMonoClass::GetMethods( string strMethodName )
CMonoEvent* CMonoClass::GetEvent( string strEventName ) CMonoEvent* CMonoClass::GetEvent( string strEventName )
{ {
return this->m_Events[ strEventName ]; return this->m_Events.count( strEventName ) ? this->m_Events[ strEventName ] : nullptr;
} }
MonoClassField* CMonoClass::GetField( string strFieldName ) MonoClassField* CMonoClass::GetField( string strFieldName )
{ {
return this->m_Fields[ strFieldName ]; return this->m_Fields.count( strFieldName ) ? this->m_Fields[ strFieldName ] : nullptr;
} }

View File

@ -37,7 +37,14 @@ void CMonoFunctions::AddInternals( void )
MONO_DECLARE( Game, SetRuleValue ); MONO_DECLARE( Game, SetRuleValue );
MONO_DECLARE( Game, RemoveRuleValue ); MONO_DECLARE( Game, RemoveRuleValue );
MONO_DECLARE( Event, Add );
MONO_DECLARE( Event, AddHandler ); MONO_DECLARE( Event, AddHandler );
MONO_DECLARE( Event, RemoveHandler );
MONO_DECLARE( Event, Trigger );
MONO_DECLARE( Event, Cancel );
MONO_DECLARE( Event, WasCancelled );
MONO_DECLARE( Event, GetCancelReason );
MONO_DECLARE( Event, TriggerClient );
// Element create/destroy // Element create/destroy
MONO_DECLARE( Element, Create ); MONO_DECLARE( Element, Create );

View File

@ -80,7 +80,15 @@ public:
class Event class Event
{ {
public: public:
static bool AddHandler ( MonoString* msName, DWORD pUserData, lua_CFunction iLuaFunction, bool bPropagated, MonoString* msEventPriority ); static bool Add ( MonoString* msName, bool bAllowRemoteTrigger );
static bool AddHandler ( MonoString* msName, DWORD pUserData, MonoObject* pDelegate, bool bPropagated, MonoString* msEventPriority );
static bool RemoveHandler ( MonoString* msName, DWORD pUserData, MonoObject* pDelegate );
static bool Trigger ( MonoString* msName, DWORD pUserData, MonoArray* mpArguments );
static bool Cancel ( bool bCancel, MonoString* msReason );
static bool WasCancelled ( void );
static string GetCancelReason ( void );
static bool TriggerClient ( DWORD pSendTo, MonoString* msName, DWORD pSource, MonoArray* mpArguments );
}; };
class Element class Element

View File

@ -12,9 +12,145 @@
#include "CMonoFunctions.h" #include "CMonoFunctions.h"
bool CMonoFunctions::Event::AddHandler( MonoString* msName, DWORD pUserData, lua_CFunction iLuaFunction, bool bPropagated, MonoString* msEventPriority ) bool CMonoFunctions::Event::Add( MonoString* msName, bool bAllowRemoteTrigger )
{ {
if( RESOURCE )
{
const char* szName = mono_string_to_utf8( msName );
if( CLuaFunctionDefinitions::AddEvent( RESOURCE->GetLua(), szName, bAllowRemoteTrigger ) )
{
return RESOURCE->AddEvent( szName, "root" );
}
}
return false;
}
bool CMonoFunctions::Event::AddHandler( MonoString* msName, DWORD pUserData, MonoObject* pDelegate, bool bPropagated, MonoString* msEventPriority )
{
if( RESOURCE )
{
if( !pUserData )
{
g_pModuleManager->ErrorPrintf( "Invalid argument #2 in method 'Event::AddHandler'\n" );
return false;
}
if( !pDelegate )
{
g_pModuleManager->ErrorPrintf( "Invalid argument #3 in method 'Event::AddHandler'\n" );
return false;
}
string strEventName = mono_string_to_utf8( msName );
if( strEventName.length() == 0 )
{
g_pModuleManager->ErrorPrintf( "Invalid argument #1 in method 'Event::AddHandler'\n" );
return false;
}
string strEventPriority = mono_string_to_utf8( msEventPriority );
return RESOURCE->GetEventManager()->Add( strEventName, pUserData, pDelegate, bPropagated, strEventPriority );
}
return false;
}
bool CMonoFunctions::Event::RemoveHandler( MonoString* msName, DWORD pUserData, MonoObject* pDelegate )
{
if( RESOURCE )
{
if( !pUserData )
{
g_pModuleManager->ErrorPrintf( "Invalid argument #2 in method 'Event::AddHandler'\n" );
return false;
}
if( !pDelegate )
{
g_pModuleManager->ErrorPrintf( "Invalid argument #3 in method 'Event::AddHandler'\n" );
return false;
}
string strEventName = mono_string_to_utf8( msName );
if( strEventName.length() == 0 )
{
g_pModuleManager->ErrorPrintf( "Invalid argument #1 in method 'Event::RemoveEvent'\n" );
return false;
}
return RESOURCE->GetEventManager()->Delete( strEventName, pUserData, pDelegate );
}
return false;
}
bool CMonoFunctions::Event::Trigger( MonoString* msName, DWORD pUserData, MonoArray* mpArguments )
{
if( RESOURCE )
{
const char* szEventName = mono_string_to_utf8( msName );
CLuaArguments Arguments = CMonoInterface::MonoArrayToLuaArguments( mpArguments );
return CLuaFunctionDefinitions::TriggerEvent( RESOURCE->GetLua(), szEventName, (void*)pUserData, Arguments );
}
return false;
}
bool CMonoFunctions::Event::Cancel( bool bCancel, MonoString* msReason )
{
if( RESOURCE )
{
const char* szReason = mono_string_to_utf8( msReason );
return CLuaFunctionDefinitions::CancelEvent( RESOURCE->GetLua(), bCancel, szReason );
}
return false;
}
bool CMonoFunctions::Event::WasCancelled( void )
{
if( RESOURCE )
{
return CLuaFunctionDefinitions::WasEventCancelled( RESOURCE->GetLua() );
}
return false;
}
string CMonoFunctions::Event::GetCancelReason( void )
{
if( RESOURCE )
{
return CLuaFunctionDefinitions::GetCancelReason( RESOURCE->GetLua() );
}
return string();
}
bool CMonoFunctions::Event::TriggerClient( DWORD pSendTo, MonoString* msName, DWORD pSource, MonoArray* mpArguments )
{
if( RESOURCE )
{
const char* szEventName = mono_string_to_utf8( msName );
CLuaArguments Arguments = CMonoInterface::MonoArrayToLuaArguments( mpArguments );
return CLuaFunctionDefinitions::TriggerClientEvent( RESOURCE->GetLua(), (void*)pSendTo, szEventName, (void*)pSource, Arguments );
}
return false; return false;
} }

View File

@ -53,3 +53,174 @@ void CMonoInterface::SetDomain( MonoDomain* pDomain, bool bForce )
{ {
mono_domain_set( pDomain != nullptr ? pDomain : this->m_pMonoDomain, bForce ); mono_domain_set( pDomain != nullptr ? pDomain : this->m_pMonoDomain, bForce );
} }
CLuaArguments CMonoInterface::MonoArrayToLuaArguments( MonoArray* pArray )
{
CLuaArguments pLuaArguments;
unsigned int uiLength = mono_array_length( pArray );
for( unsigned int i = 0; i < uiLength; i++ )
{
int iType = 0;
MonoObject* pObj = mono_array_get( pArray, MonoObject*, i );
MonoType* pType = nullptr;
if( pObj )
{
MonoClass* pClass = mono_object_get_class( pObj );
if( pClass )
{
pType = mono_class_get_type( pClass );
if( pType )
{
iType = mono_type_get_type( pType );
}
}
}
switch( iType )
{
case NULL:
{
pLuaArguments.PushNil();
break;
}
case MONO_TYPE_BOOLEAN: // System.Boolean
{
bool bValue = *( reinterpret_cast<bool*>( mono_object_unbox( pObj ) ) );
pLuaArguments.PushBoolean( bValue );
break;
}
case MONO_TYPE_CHAR: // System.Char
{
wchar_t iValue = *( reinterpret_cast<wchar_t*>( mono_object_unbox( pObj ) ) );
pLuaArguments.PushNumber( iValue );
break;
}
case MONO_TYPE_STRING: // System.String
{
const char* szValue = mono_string_to_utf8( reinterpret_cast<MonoString*>( pObj ) );
pLuaArguments.PushString( szValue );
break;
}
case MONO_TYPE_I1: // System.SByte
{
int8_t iValue = *( reinterpret_cast<int8_t*>( mono_object_unbox( pObj ) ) );
pLuaArguments.PushNumber( iValue );
break;
}
case MONO_TYPE_U1: // System.Byte
{
uint8_t iValue = *( reinterpret_cast<uint8_t*>( mono_object_unbox( pObj ) ) );
pLuaArguments.PushNumber( iValue );
break;
}
case MONO_TYPE_I2: // System.Int16
{
int16_t iValue = *( reinterpret_cast<int16_t*>( mono_object_unbox( pObj ) ) );
pLuaArguments.PushNumber( iValue );
break;
}
case MONO_TYPE_U2: // System.UInt16
{
uint16_t iValue = *( reinterpret_cast<uint16_t*>( mono_object_unbox( pObj ) ) );
pLuaArguments.PushNumber( iValue );
break;
}
case MONO_TYPE_I4: // System.Int32
{
int32_t iValue = *( reinterpret_cast<int32_t*>( mono_object_unbox( pObj ) ) );
pLuaArguments.PushNumber( iValue );
break;
}
case MONO_TYPE_U4: // System.UInt32
{
uint32 iValue = *( reinterpret_cast<uint32*>( mono_object_unbox( pObj ) ) );
pLuaArguments.PushNumber( iValue );
break;
}
case MONO_TYPE_I8: // System.Int64
{
int64_t iValue = *( reinterpret_cast<int64_t*>( mono_object_unbox( pObj ) ) );
pLuaArguments.PushNumber( iValue );
break;
}
case MONO_TYPE_U8: // System.UInt64
{
uint64_t iValue = *( reinterpret_cast<uint64_t*>( mono_object_unbox( pObj ) ) );
pLuaArguments.PushNumber( iValue );
break;
}
case MONO_TYPE_R4: // System.Single
{
float fValue = *( reinterpret_cast<float*>( mono_object_unbox( pObj ) ) );
pLuaArguments.PushNumber( fValue );
break;
}
case MONO_TYPE_R8: // System.Double
{
double dValue = *( reinterpret_cast<double*>( mono_object_unbox( pObj ) ) );
pLuaArguments.PushNumber( dValue );
break;
}
case MONO_TYPE_OBJECT: // System.Object
case MONO_TYPE_CLASS:
{
void* pValue = CMonoObject::GetPropertyValue<void*>( pObj, "userdata" );
if( pValue )
{
pLuaArguments.PushUserData( pValue );
break;
}
// do not break;
}
case MONO_TYPE_I:
case MONO_TYPE_U:
default:
{
g_pModuleManager->ErrorPrintf( "Unsupported type: %s (0x%i)\n", pType ? mono_type_get_name( pType ) : "(unknown type)", iType );
break;
}
}
iType = 0;
pType = nullptr;
}
return pLuaArguments;
}

View File

@ -19,6 +19,8 @@ class CMonoInterface;
#include "CMonoDomain.h" #include "CMonoDomain.h"
#include "CResource.h" #include "CResource.h"
#include "extra/CLuaArguments.h"
class CMonoInterface class CMonoInterface
{ {
private: private:
@ -38,11 +40,13 @@ public:
#pragma region Static methods #pragma region Static methods
static string GetBinariesDirectory( void ) static string GetBinariesDirectory( void )
{ {
return "mods/deathmatch/resources/[ire]"; return "mods/deathmatch/resources/[ire]";
} }
static CLuaArguments MonoArrayToLuaArguments( MonoArray* pArray );
#pragma endregion #pragma endregion
}; };

View File

@ -19,6 +19,8 @@ CResource::CResource( CMonoInterface* pMono, lua_State *pLuaVM, string sName )
this->m_sName = sName; this->m_sName = sName;
this->m_pMonoDomain = nullptr; this->m_pMonoDomain = nullptr;
this->m_pEventManager = new CEventManager( this );
} }
CResource::~CResource( void ) CResource::~CResource( void )
@ -27,10 +29,9 @@ CResource::~CResource( void )
this->GetMono()->GetGC()->Collect( this->GetMono()->GetGC()->GetMaxGeneration() ); this->GetMono()->GetGC()->Collect( this->GetMono()->GetGC()->GetMaxGeneration() );
//this->GetMono()->SetDomain( nullptr, true );
g_pResourceManager->RemoveFromList( this ); g_pResourceManager->RemoveFromList( this );
SAFE_DELETE( this->m_pEventManager );
SAFE_DELETE( this->m_pMonoDomain ); SAFE_DELETE( this->m_pMonoDomain );
this->GetMono()->SetDomain( nullptr, true ); this->GetMono()->SetDomain( nullptr, true );
@ -46,26 +47,7 @@ bool CResource::CallEvent( string strEventName, void* pThis, list< CLuaArgument*
return false; return false;
} }
CMonoMTALib* pMTALib = this->GetDomain()->GetMTALib(); return this->m_pEventManager->Call( strEventName, pThis, argv );
CMonoClass* pClass = pMTALib->GetClass( "Element" );
CMonoEvent* pEvent = pClass->GetEvent( strEventName );
if( !pEvent )
{
g_pModuleManager->ErrorPrintf( "[%s] event '%s' is class '%s' not found", this->m_sName.c_str(), strEventName.c_str(), pClass->GetName() );
return false;
}
MonoObject* pThisObj = pMTALib->RegisterElement( pThis );
if( !pThisObj )
{
return false;
}
return pEvent->Call( pThisObj, argv );
} }
bool CResource::AddEvent( const char* szName, const char* szHandleElement ) bool CResource::AddEvent( const char* szName, const char* szHandleElement )

View File

@ -21,6 +21,7 @@ class CResource;
#include "CMonoInterface.h" #include "CMonoInterface.h"
#include "CResourceManager.h" #include "CResourceManager.h"
#include "CEventManager.h"
#include "CFunctions.h" #include "CFunctions.h"
#include "extra/CLuaArgument.h" #include "extra/CLuaArgument.h"
@ -41,6 +42,8 @@ private:
CMonoInterface* m_pMono; CMonoInterface* m_pMono;
CMonoDomain* m_pMonoDomain; CMonoDomain* m_pMonoDomain;
CEventManager* m_pEventManager;
public: public:
CResource ( CMonoInterface* m_pMono, lua_State *pLuaVM, string sName ); CResource ( CMonoInterface* m_pMono, lua_State *pLuaVM, string sName );
~CResource ( void ); ~CResource ( void );
@ -64,6 +67,7 @@ public:
lua_State* GetLua ( void ) { return this->m_pLuaVM; } lua_State* GetLua ( void ) { return this->m_pLuaVM; }
CMonoInterface* GetMono ( void ) { return this->m_pMono; } CMonoInterface* GetMono ( void ) { return this->m_pMono; }
CMonoDomain* GetDomain ( void ) { return this->m_pMonoDomain; } CMonoDomain* GetDomain ( void ) { return this->m_pMonoDomain; }
CEventManager* GetEventManager ( void ) { return this->m_pEventManager; }
private: private:

View File

@ -200,6 +200,26 @@ bool CLuaFunctionDefinitions::SetPlayerAnnounceValue( lua_State* pLuaVM, void* p
return false; return false;
} }
bool CLuaFunctionDefinitions::AddEvent( lua_State* pLuaVM, const char* szName, bool bAllowRemoteTrigger )
{
CLuaArguments pLuaArguments;
pLuaArguments.PushString( szName );
pLuaArguments.PushBoolean( bAllowRemoteTrigger );
if( pLuaArguments.Call( pLuaVM, "addEvent", 1 ) )
{
CLuaArgument pLuaArgument( pLuaVM, -1 );
if( pLuaArgument.GetType() == LUA_TBOOLEAN )
{
return pLuaArgument.GetBoolean();
}
}
return false;
}
bool CLuaFunctionDefinitions::AddEventHandler( lua_State* pLuaVM, const char* szName, void* pUserData, lua_CFunction iLuaFunction, bool bPropagated, const char* szEventPriority ) bool CLuaFunctionDefinitions::AddEventHandler( lua_State* pLuaVM, const char* szName, void* pUserData, lua_CFunction iLuaFunction, bool bPropagated, const char* szEventPriority )
{ {
CLuaArguments pLuaArguments; CLuaArguments pLuaArguments;
@ -223,6 +243,127 @@ bool CLuaFunctionDefinitions::AddEventHandler( lua_State* pLuaVM, const char* sz
return false; return false;
} }
bool CLuaFunctionDefinitions::RemoveEventHandler( lua_State* pLuaVM, const char* szName, void* pUserData, lua_CFunction iLuaFunction )
{
CLuaArguments pLuaArguments;
pLuaArguments.PushString( szName );
pLuaArguments.PushUserData( pUserData );
pLuaArguments.PushFunction( iLuaFunction );
if( pLuaArguments.Call( pLuaVM, "removeEventHandler", 1 ) )
{
CLuaArgument pLuaArgument( pLuaVM, -1 );
if( pLuaArgument.GetType() == LUA_TBOOLEAN )
{
return pLuaArgument.GetBoolean();
}
}
return false;
}
bool CLuaFunctionDefinitions::TriggerEvent( lua_State* pLuaVM, const char* szName, void* pUserData, CLuaArguments& Arguments )
{
CLuaArguments pLuaArguments;
pLuaArguments.PushString( szName );
pLuaArguments.PushUserData( pUserData );
pLuaArguments.PushArguments( Arguments );
if( pLuaArguments.Call( pLuaVM, "triggerEvent", 1 ) )
{
CLuaArgument pLuaArgument( pLuaVM, -1 );
if( pLuaArgument.GetType() == LUA_TBOOLEAN )
{
return pLuaArgument.GetBoolean();
}
}
return false;
}
bool CLuaFunctionDefinitions::CancelEvent( lua_State* pLuaVM, bool bCancel, const char* szReason )
{
CLuaArguments pLuaArguments;
pLuaArguments.PushBoolean( bCancel );
pLuaArguments.PushString( szReason );
if( pLuaArguments.Call( pLuaVM, "cancelEvent", 1 ) )
{
CLuaArgument pLuaArgument( pLuaVM, -1 );
if( pLuaArgument.GetType() == LUA_TBOOLEAN )
{
return pLuaArgument.GetBoolean();
}
}
return false;
}
bool CLuaFunctionDefinitions::WasEventCancelled( lua_State* pLuaVM )
{
CLuaArguments pLuaArguments;
if( pLuaArguments.Call( pLuaVM, "wasEventCancelled", 1 ) )
{
CLuaArgument pLuaArgument( pLuaVM, -1 );
if( pLuaArgument.GetType() == LUA_TBOOLEAN )
{
return pLuaArgument.GetBoolean();
}
}
return false;
}
string CLuaFunctionDefinitions::GetCancelReason( lua_State* pLuaVM )
{
CLuaArguments pLuaArguments;
if( pLuaArguments.Call( pLuaVM, "getCancelReason", 1 ) )
{
CLuaArgument pLuaArgument( pLuaVM, -1 );
if( pLuaArgument.GetType() == LUA_TSTRING )
{
return pLuaArgument.GetString();
}
}
return string();
}
bool CLuaFunctionDefinitions::TriggerClientEvent( lua_State* pLuaVM, void* pSendTo, const char* szName, void* pSource, CLuaArguments& Arguments )
{
CLuaArguments pLuaArguments;
if( pSendTo )
{
pLuaArguments.PushUserData( pSendTo );
}
pLuaArguments.PushString( szName );
pLuaArguments.PushUserData( pSource );
pLuaArguments.PushArguments( Arguments );
if( pLuaArguments.Call( pLuaVM, "triggerClientEvent", 1 ) )
{
CLuaArgument pLuaArgument( pLuaVM, -1 );
if( pLuaArgument.GetType() == LUA_TBOOLEAN )
{
return pLuaArgument.GetBoolean();
}
}
return false;
}
// Element create/destroy // Element create/destroy

View File

@ -41,20 +41,20 @@ public:
// static int FetchRemote ( lua_State* luaVM ); // static int FetchRemote ( lua_State* luaVM );
// Event functions // Event functions
// static bool AddEvent ( lua_State* pLuaVM, const char* szName, bool bAllowRemoteTrigger ); static bool AddEvent ( lua_State* pLuaVM, const char* szName, bool bAllowRemoteTrigger );
static bool AddEventHandler ( lua_State* pLuaVM, const char* szName, void* pUserData, lua_CFunction iLuaFunction, bool bPropagated, const char* szEventPriority ); static bool AddEventHandler ( lua_State* pLuaVM, const char* szName, void* pUserData, lua_CFunction iLuaFunction, bool bPropagated, const char* szEventPriority );
// static bool RemoveEventHandler ( lua_State* pLuaVM, const char* szName, void* pUserData, const CLuaFunctionRef& iLuaFunction ); static bool RemoveEventHandler ( lua_State* pLuaVM, const char* szName, void* pUserData, lua_CFunction iLuaFunction );
// static bool GetEventHandlers ( lua_State* pLuaVM, const char* szName ); // static bool GetEventHandlers ( lua_State* pLuaVM, const char* szName );
// static bool TriggerEvent ( lua_State* pLuaVM, const char* szName, void* pUserData, const CLuaArguments& Arguments, bool& bWasCancelled ); static bool TriggerEvent ( lua_State* pLuaVM, const char* szName, void* pUserData, CLuaArguments& Arguments );
// static bool CancelEvent ( lua_State* pLuaVM, bool bCancel ); static bool CancelEvent ( lua_State* pLuaVM, bool bCancel, const char* szReason );
// static bool WasEventCancelled ( lua_State* pLuaVM ); static bool WasEventCancelled ( lua_State* pLuaVM );
static string GetCancelReason ( lua_State* pLuaVM );
// static int TriggerClientEvent ( lua_State* luaVM ); static bool TriggerClientEvent ( lua_State* pLuaVM, void* pSendTo, const char* szName, void* pSource, CLuaArguments& Arguments );
// static int GetCancelReason ( lua_State* luaVM ); // static int TriggerLatentClientEvent ( lua_State* pLuaVM );
// static int TriggerLatentClientEvent ( lua_State* luaVM ); // static int GetLatentEventHandles ( lua_State* pLuaVM );
// static int GetLatentEventHandles ( lua_State* luaVM ); // static int GetLatentEventStatus ( lua_State* pLuaVM );
// static int GetLatentEventStatus ( lua_State* luaVM ); // static int CancelLatentEvent ( lua_State* pLuaVM );
// static int CancelLatentEvent ( lua_State* luaVM );
// Element create/destroy // Element create/destroy
static void* CreateElement ( lua_State* pLuaVM, const char* szTypeName, const char* szID ); static void* CreateElement ( lua_State* pLuaVM, const char* szTypeName, const char* szID );