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

This commit is contained in:
Kernell 2015-12-01 12:26:55 +03:00
parent 5bd91b1c98
commit 07e2feba72
13 changed files with 743 additions and 80 deletions

View File

@ -145,6 +145,7 @@
<ClCompile Include="src\CMonoClass.cpp" />
<ClCompile Include="src\CMonoCorlib.cpp" />
<ClCompile Include="src\CMonoDomain.cpp" />
<ClCompile Include="src\CMonoEvent.cpp" />
<ClCompile Include="src\CMonoFunctions.cpp" />
<ClCompile Include="src\CMonoFunctions_Account.cpp" />
<ClCompile Include="src\CMonoFunctions_Audio.cpp" />
@ -167,6 +168,7 @@
<ClCompile Include="src\CMonoFunctions_World.cpp" />
<ClCompile Include="src\CMonoGC.cpp" />
<ClCompile Include="src\CMonoInterface.cpp" />
<ClCompile Include="src\CMonoMethod.cpp" />
<ClCompile Include="src\CMonoMTALib.cpp" />
<ClCompile Include="src\CMonoObject.cpp" />
<ClCompile Include="src\Common.cpp" />
@ -188,9 +190,11 @@
<ClInclude Include="src\CMonoClass.h" />
<ClInclude Include="src\CMonoCorlib.h" />
<ClInclude Include="src\CMonoDomain.h" />
<ClInclude Include="src\CMonoEvent.h" />
<ClInclude Include="src\CMonoFunctions.h" />
<ClInclude Include="src\CMonoGC.h" />
<ClInclude Include="src\CMonoInterface.h" />
<ClInclude Include="src\CMonoMethod.h" />
<ClInclude Include="src\CMonoMTALib.h" />
<ClInclude Include="src\CMonoObject.h" />
<ClInclude Include="src\CResource.h" />

View File

@ -10,7 +10,6 @@
*
*********************************************************/
#include "StdInc.h"
#include "CFunctions.h"
#include "extra/CLuaArguments.h"
@ -53,20 +52,66 @@ int CFunctions::monoEventHandler( lua_State *pLuaVM )
if( pResource )
{
// eventName, this, source, client, ...
string strEventName;
void* pThis = nullptr;
string strEventName = CLuaArgument( pLuaVM, -4 ).GetString();
void* pThis = CLuaArgument( pLuaVM, -3 ).GetLightUserData();
void* pSource = CLuaArgument( pLuaVM, -2 ).GetLightUserData();
void* pClient = CLuaArgument( pLuaVM, -1 ).GetLightUserData();
CLuaArguments pLuaArgs;
//void *args[] = { &vecVector.fX, &vecVector.fY };
pLuaArgs.ReadArguments( pLuaVM );
if( pLuaArgs.Count() == 0 )
{
return 0;
}
g_pModuleManager->DebugPrintf( pLuaVM, "event: %s", strEventName.c_str() );
uint i = 0;
pResource->CallEvent( strEventName, pThis, pSource, pClient, nullptr );
list< CLuaArgument* > argv;
return 1;
for( auto iter : pLuaArgs.GetArguments() )
{
int iLuaType = iter->GetType();
switch( i )
{
case 0:
{
strEventName = iter->GetString();
strEventName[ 0 ] = toupper( strEventName[ 0 ] );
break;
}
case 2:
{
pThis = iter->GetLightUserData();
break;
}
case 3:
{
if( iLuaType == LUA_TNIL )
{
break;
}
// dot not break
}
default:
{
argv.push_back( iter );
break;
}
}
i++;
}
if( pResource->CallEvent( strEventName, pThis, argv ) )
{
return 1;
}
}
}

View File

@ -25,9 +25,9 @@ CMonoClass::CMonoClass( MonoClass* pMonoClass, CMonoDomain* pDomain )
while( MonoMethod* pMonoMethod = mono_class_get_methods( pMonoBaseClass, &iter ) )
{
const char* szName = mono_method_get_name( pMonoMethod );
CMonoMethod* pMethod = new CMonoMethod( this, pMonoMethod );
this->m_Methods[ szName ].push_back( pMonoMethod );
this->m_Methods[ pMethod->GetName() ].push_back( pMethod );
}
iter = nullptr;
@ -45,7 +45,7 @@ CMonoClass::CMonoClass( MonoClass* pMonoClass, CMonoDomain* pDomain )
{
const char* szName = mono_event_get_name( pMonoEvent );
this->m_Events[ szName ] = pMonoEvent;
this->m_Events[ szName ] = new CMonoEvent( this, pMonoEvent );
}
iter = nullptr;
@ -69,6 +69,12 @@ CMonoClass::~CMonoClass( void )
this->m_pClass = nullptr;
this->m_Fields.clear();
for( auto iter : this->m_Events )
{
delete iter.second;
}
this->m_Events.clear();
for( auto iter : this->m_Properties )
@ -80,6 +86,11 @@ CMonoClass::~CMonoClass( void )
for( auto iter : this->m_Methods )
{
for( auto method : iter.second )
{
delete method;
}
iter.second.clear();
}
@ -130,18 +141,22 @@ MonoObject* CMonoClass::New( void** args, int argc )
return nullptr;
}
MonoMethod* pMonoMethod = this->GetMethod( ".ctor", argc );
CMonoMethod* pMethod = this->GetMethod( ".ctor", argc );
if( !pMonoMethod )
if( !pMethod )
{
return nullptr;
}
mono_runtime_invoke( pMonoMethod, pObject, args, nullptr );
pMethod->Invoke( pObject, args, nullptr );
return pObject;
}
MonoObject* CMonoClass::Box( void* value )
{
return mono_value_box( this->m_pDomain->GetMonoPtr(), this->m_pClass, value );
}
const char* CMonoClass::GetName( void )
{
@ -174,7 +189,7 @@ MonoMethod* CMonoClass::GetMethod( string strMethodName )
return nullptr;
}
MonoMethod* CMonoClass::GetMethod( string strMethodName, uint uiIndex )
CMonoMethod* CMonoClass::GetMethod( string strMethodName, uint uiIndex )
{
if( this->m_Methods[ strMethodName ].size() > 0 )
{
@ -192,7 +207,12 @@ MonoMethod* CMonoClass::GetMethod( string strMethodName, uint uiIndex )
return nullptr;
}
MonoEvent* CMonoClass::GetEvent( string strEventName )
list< CMonoMethod* > CMonoClass::GetMethods( string strMethodName )
{
return this->m_Methods[ strMethodName ];
}
CMonoEvent* CMonoClass::GetEvent( string strEventName )
{
return this->m_Events[ strEventName ];
}

View File

@ -16,10 +16,12 @@ class CMonoClass;
#define _C_MONOCLASS_H
#include "CMonoDomain.h"
#include "CMonoEvent.h"
#include "CMonoMethod.h"
typedef map< string, list< MonoMethod* > > MonoMethodMap;
typedef map< string, list< CMonoMethod* > > MonoMethodMap;
typedef map< string, list< MonoProperty* > > MonoPropertyMap;
typedef map< string, MonoEvent* > MonoEventMap;
typedef map< string, CMonoEvent* > MonoEventMap;
typedef map< string, MonoClassField* > MonoClassFieldMap;
class CMonoClass
@ -44,16 +46,21 @@ public:
MonoObject* New ( Vector3& vecVector );
MonoObject* New ( void** args, int argc );
MonoObject* Box ( void* value );
const char* GetName ( void );
const char* GetNameSpace ( void );
MonoMethod* GetMethodFromName ( string strMethodName, int iParamCount );
MonoMethod* GetMethod ( string strMethodName );
MonoMethod* GetMethod ( string strMethodName, uint uiIndex );
CMonoMethod* GetMethod ( string strMethodName, uint uiIndex );
list< CMonoMethod* > GetMethods ( string strMethodName );
MonoEvent* GetEvent ( string strEventName );
CMonoEvent* GetEvent ( string strEventName );
MonoClassField* GetField ( string strFieldName );
MonoEventMap GetAllEvents ( void ) { return this->m_Events; }
MonoClass* GetMonoPtr ( void ) { return this->m_pClass; }
CMonoDomain* GetDomain ( void ) { return this->m_pDomain; }
};

View File

@ -25,7 +25,7 @@ private:
MonoImage* m_pImage;
CMonoDomain* m_pDomain;
protected:
public:
map< const char*, CMonoClass* > Class;
public:

331
mta-mono/src/CMonoEvent.cpp Normal file
View File

@ -0,0 +1,331 @@
/*********************************************************
*
* 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 "CMonoEvent.h"
CMonoEvent::CMonoEvent( CMonoClass* pClass, MonoEvent* pEvent )
{
this->m_pClass = pClass;
this->m_pEvent = pEvent;
this->m_pAddMethod = nullptr;
this->m_pRemoveMethod = nullptr;
this->m_pRaiseMethod = nullptr;
this->m_strName = mono_event_get_name( pEvent );
}
CMonoEvent::~CMonoEvent( void )
{
this->m_pClass = nullptr;
this->m_pEvent = nullptr;
this->m_pAddMethod = nullptr;
this->m_pRemoveMethod = nullptr;
this->m_pRaiseMethod = nullptr;
}
bool CMonoEvent::Call( MonoObject* pThis, list< CLuaArgument* > argv )
{
CMonoMethod* pMethod = this->GetRaiseMethod();
if( !pMethod )
{
return false;
}
void** pArguments = this->ParseArguments( argv );
if( !pArguments )
{
this->GetClass()->GetDomain()->GetResource()->ErrorPrintf( "Raise method for event '%s' not found\n", this->GetName().c_str() );
return false;
}
MonoObject* pException = nullptr;
pMethod->Invoke( pThis, pArguments, pException );
if( !pException )
{
auto iter = argv.begin();
if( (*iter)->GetType() == LUA_TLIGHTUSERDATA )
{
pMethod->Invoke( pArguments[ 0 ], pArguments, pException );
}
}
delete [] pArguments;
if( pException )
{
this->GetClass()->GetDomain()->GetResource()->ErrorPrintf( "%s\n", mono_string_to_utf8( mono_object_to_string( pException, nullptr ) ) );
return false;
}
return false;
}
void** CMonoEvent::ParseArguments( list< CLuaArgument* > argv )
{
CMonoMTALib* pMTALib = this->GetClass()->GetDomain()->GetMTALib();
CMonoCorlib* pCorlib = this->GetClass()->GetDomain()->GetCorlib();
gpointer *pArguments = new gpointer[ argv.size() ];
uint argc = 0;
auto pMethods = this->m_pClass->GetMethods( "raise_" + this->GetName() );
for( auto pMethod : pMethods )
{
vector< SMonoType > pArgList = pMethod->GetArguments();
if( pArgList.size() != argv.size() )
{
continue;
}
auto iter = argv.begin();
auto pType = pArgList.begin();
for( ; ; iter++ )
{
if( iter == argv.end() || pType == pArgList.end() )
{
return pArguments;
}
int iLuaType = (*iter)->GetType();
switch( pType->iType )
{
case MONO_TYPE_BOOLEAN: // System.Boolean
{
if( iLuaType == LUA_TBOOLEAN )
{
bool bValue = (*iter)->GetBoolean();
pArguments[ argc++ ] = &bValue;
}
break;
}
case MONO_TYPE_CHAR: // System.Char
{
if( iLuaType == LUA_TNUMBER )
{
wchar_t iValue = (*iter)->GetNumber< wchar_t >();
MonoObject* pObj = pCorlib->Class[ "char" ]->Box( &iValue );
pArguments[ argc++ ] = pObj;
}
break;
}
case MONO_TYPE_I1: // System.SByte
{
if( iLuaType == LUA_TNUMBER )
{
int8_t iValue = (*iter)->GetNumber< int8_t >();
MonoObject* pObj = pCorlib->Class[ "sbyte" ]->Box( &iValue );
pArguments[ argc++ ] = pObj;
}
break;
}
case MONO_TYPE_U1: // System.Byte
{
if( iLuaType == LUA_TNUMBER )
{
uint8_t iValue = (*iter)->GetNumber< uint8_t >();
MonoObject* pObj = pCorlib->Class[ "byte" ]->Box( &iValue );
pArguments[ argc++ ] = pObj;
}
break;
}
case MONO_TYPE_I2: // System.Int16
{
if( iLuaType == LUA_TNUMBER )
{
int16_t iValue = (*iter)->GetNumber< int16_t >();
MonoObject* pObj = pCorlib->Class[ "int16" ]->Box( &iValue );
pArguments[ argc++ ] = pObj;
}
break;
}
case MONO_TYPE_U2: // System.UInt16
{
if( iLuaType == LUA_TNUMBER )
{
uint16_t iValue = (*iter)->GetNumber< uint16_t >();
MonoObject* pObj = pCorlib->Class[ "uint16" ]->Box( &iValue );
pArguments[ argc++ ] = pObj;
}
break;
}
case MONO_TYPE_I4: // System.Int32
{
if( iLuaType == LUA_TNUMBER )
{
int32_t iValue = (*iter)->GetNumber< int32_t >();
MonoObject* pObj = pCorlib->Class[ "int32" ]->Box( &iValue );
pArguments[ argc++ ] = pObj;
}
break;
}
case MONO_TYPE_U4: // System.UInt32
{
if( iLuaType == LUA_TNUMBER )
{
uint32_t iValue = (*iter)->GetNumber< uint32_t >();
MonoObject* pObj = pCorlib->Class[ "uint32" ]->Box( &iValue );
pArguments[ argc++ ] = pObj;
}
break;
}
case MONO_TYPE_I8: // System.Int64
{
if( iLuaType == LUA_TNUMBER )
{
int64_t iValue = (*iter)->GetNumber< int64_t >();
MonoObject* pObj = pCorlib->Class[ "int64" ]->Box( &iValue );
pArguments[ argc++ ] = pObj;
}
break;
}
case MONO_TYPE_U8: // System.UInt64
{
if( iLuaType == LUA_TNUMBER )
{
uint64_t iValue = (*iter)->GetNumber< uint64_t >();
MonoObject* pObj = pCorlib->Class[ "uint64" ]->Box( &iValue );
pArguments[ argc++ ] = pObj;
}
break;
}
case MONO_TYPE_R4: // System.Single
{
if( iLuaType == LUA_TNUMBER )
{
float iValue = (*iter)->GetNumber< float >();
MonoObject* pObj = pCorlib->Class[ "float" ]->Box( &iValue );
pArguments[ argc++ ] = pObj;
}
break;
}
case MONO_TYPE_R8: // System.Double
{
if( iLuaType == LUA_TNUMBER )
{
double iValue = (*iter)->GetNumber< double >();
MonoObject* pObj = pCorlib->Class[ "double" ]->Box( &iValue );
pArguments[ argc++ ] = pObj;
}
break;
}
case MONO_TYPE_STRING: // System.String
{
if( iLuaType == LUA_TSTRING )
{
const char* szValue = (*iter)->GetString();
MonoString* pString = this->GetClass()->GetDomain()->NewString( szValue );
pArguments[ argc++ ] = pString;
}
break;
}
case MONO_TYPE_OBJECT: // System.Object
case MONO_TYPE_CLASS:
{
if( iLuaType == LUA_TLIGHTUSERDATA )
{
void* pUserData = (*iter)->GetLightUserData();
MonoObject* pValue = pMTALib->RegisterElement( pUserData );
if( pValue )
{
pArguments[ argc++ ] = pValue;
}
else
{
pArguments[ argc++ ] = pUserData;
}
}
break;
}
case MONO_TYPE_I:
case MONO_TYPE_U:
default:
{
this->GetClass()->GetDomain()->GetResource()->ErrorPrintf( "Unsupported type '%s (0x%i)' for '%s'\n", pType->strName.c_str(), pType->iType, this->GetName().c_str() );
break;
}
}
}
}
delete [] pArguments;
return nullptr;
}
CMonoMethod* CMonoEvent::GetAddMethod( void )
{
return this->m_pClass->GetMethod( "add_" + this->GetName(), 0 );
}
CMonoMethod* CMonoEvent::GetRemoveMethod( void )
{
return this->m_pClass->GetMethod( "remove_" + this->GetName(), 0 );
}
CMonoMethod* CMonoEvent::GetRaiseMethod( void )
{
return this->m_pClass->GetMethod( "raise_" + this->GetName(), 0 );
}

52
mta-mono/src/CMonoEvent.h Normal file
View File

@ -0,0 +1,52 @@
/*********************************************************
*
* 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 CMonoEvent;
#ifndef __CMONOEVENT_H
#define __CMONOEVENT_H
#include "CMonoClass.h"
#include "CMonoMethod.h"
#include "extra/CLuaArgument.h"
class CMonoEvent
{
private:
CMonoClass* m_pClass;
MonoEvent* m_pEvent;
MonoMethod* m_pAddMethod;
MonoMethod* m_pRemoveMethod;
MonoMethod* m_pRaiseMethod;
string m_strName;
public:
CMonoEvent ( CMonoClass* pClass, MonoEvent* pEvent );
~CMonoEvent ( void );
bool Call ( MonoObject* pThis, list< CLuaArgument* > argv );
void** ParseArguments ( list< CLuaArgument* > argv );
CMonoMethod* GetAddMethod ( void );
CMonoMethod* GetRemoveMethod ( void );
CMonoMethod* GetRaiseMethod ( void );
CMonoClass* GetClass ( void ) { return this->m_pClass; }
MonoEvent* GetMonoPtr ( void ) { return this->m_pEvent; }
string GetName ( void ) { return this->m_strName; }
};
#endif

View File

@ -21,8 +21,6 @@ CMonoMTALib::CMonoMTALib( CMonoDomain* pDomain )
this->m_pImage = nullptr;
this->m_pDomain = pDomain;
this->m_uiGCHandle = 0;
string strPath( CMonoInterface::GetBinariesDirectory() + "/" + pDomain->GetResource()->GetName() + "/MultiTheftAuto.dll" );
this->m_pAssembly = pDomain->OpenAssembly( strPath.c_str() );
@ -42,8 +40,6 @@ CMonoMTALib::CMonoMTALib( CMonoDomain* pDomain )
if( this->m_pClass )
{
this->m_pObject = this->m_pClass->New();
//this->m_uiGCHandle = mono_gchandle_new( this->m_pObject, true );
}
}
}
@ -51,13 +47,6 @@ CMonoMTALib::CMonoMTALib( CMonoDomain* pDomain )
CMonoMTALib::~CMonoMTALib( void )
{
if( this->m_uiGCHandle )
{
mono_gchandle_free( this->m_uiGCHandle );
this->m_uiGCHandle = 0;
}
SAFE_DELETE( this->Color );
SAFE_DELETE( this->Vector2 );
SAFE_DELETE( this->Vector3 );
@ -81,4 +70,36 @@ CMonoClass* CMonoMTALib::GetClass( const char* szNameSpace, const char* szName )
sprintf( szBuffer, "MultiTheftAuto.%s", szNameSpace );
return this->GetDomain()->FindOrAdd( mono_class_from_name( this->m_pImage, szBuffer, szName ) );
}
MonoObject* CMonoMTALib::RegisterElement( void* pUseData )
{
CMonoClass* pClass = this->GetClass( "Element" );
if( !pClass )
{
return false;
}
CMonoMethod* pMethod = pClass->GetMethod( "FindOrCreate", 0 );
if( !pMethod )
{
return nullptr;
}
void *Args[] = { &pUseData };
MonoObject* pException = nullptr;
MonoObject* pObject = pMethod->Invoke( nullptr, Args, pException );
if( pException )
{
this->GetDomain()->GetResource()->ErrorPrintf( "%s\n", mono_string_to_utf8( mono_object_to_string( pException, nullptr ) ) );
return nullptr;
}
return pObject;
}

View File

@ -27,8 +27,6 @@ private:
CMonoClass* m_pClass;
CMonoDomain* m_pDomain;
uint32_t m_uiGCHandle;
public:
CMonoClass* Color;
CMonoClass* Vector2;
@ -41,6 +39,8 @@ public:
CMonoClass* GetClass ( const char* szName );
CMonoClass* GetClass ( const char* szNameSpace, const char* szName );
MonoObject* RegisterElement ( void* pUserData );
CMonoDomain* GetDomain ( void ) { return this->m_pDomain; }
};

View File

@ -0,0 +1,65 @@
/*********************************************************
*
* 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 "CMonoMethod.h"
CMonoMethod::CMonoMethod( CMonoClass* pClass, MonoMethod* pMethod )
{
this->m_pClass = pClass;
this->m_pMethod = pMethod;
this->m_strName = mono_method_get_name( pMethod );
this->ParseSignature();
}
CMonoMethod::~CMonoMethod( void )
{
this->m_pClass = nullptr;
this->m_pMethod = nullptr;
}
void CMonoMethod::ParseSignature( void )
{
this->m_strSignature = "";
MonoMethodSignature* pSignature = mono_method_signature( this->m_pMethod );
if( pSignature )
{
gpointer iter = nullptr;
this->m_strSignature += this->GetName() + "(";
while( MonoType* pType = mono_signature_get_params( pSignature, &iter ) )
{
string strTypeName = mono_type_get_name( pType );
int iType = mono_type_get_type( pType );
this->m_ArgList.push_back( { strTypeName, iType } );
if( this->m_ArgList.size() > 0 )
{
this->m_strSignature += ", ";
}
this->m_strSignature += strTypeName;
}
this->m_strSignature += ")";
}
}
MonoObject* CMonoMethod::Invoke( void* pObject, void** params, MonoObject* pException )
{
return mono_runtime_invoke( this->m_pMethod, pObject, params, &pException );
}

View File

@ -0,0 +1,58 @@
/*********************************************************
*
* 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 CMonoMethod;
struct SMonoType;
#ifndef __CMONOMETHOD_H
#define __CMONOMETHOD_H
#include "CMonoClass.h"
struct SMonoType
{
string strName;
int iType;
};
class CMonoMethod
{
private:
MonoMethod* m_pMethod;
CMonoClass* m_pClass;
vector< SMonoType > m_ArgList;
string m_strName;
string m_strSignature;
private:
void ParseSignature ( void );
public:
CMonoMethod ( CMonoClass* pClass, MonoMethod* pMethod );
~CMonoMethod ( void );
MonoObject* Invoke ( void* pObject, void** params, MonoObject* pException );
string GetSignature ( void ) { return this->m_strSignature; }
vector< SMonoType > GetArguments ( void ) { return this->m_ArgList; }
MonoMethod* GetMonoPtr ( void ) { return this->m_pMethod; }
CMonoClass* GetMonoClass ( void ) { return this->m_pClass; }
string GetName ( void ) { return this->m_strName; }
};
#endif

View File

@ -10,15 +10,7 @@
*
*********************************************************/
#include "StdInc.h"
#include "CResource.h"
#include "CResourceManager.h"
#include "CFunctions.h"
#include "include/ILuaModuleManager.h"
#include "lua/CLuaFunctionDefinitions.h"
extern ILuaModuleManager10 *g_pModuleManager;
extern CResourceManager *g_pResourceManager;
CResource::CResource( CMonoInterface* pMono, lua_State *pLuaVM, string sName )
{
@ -36,6 +28,8 @@ CResource::CResource( CMonoInterface* pMono, lua_State *pLuaVM, string sName )
CResource::~CResource( void )
{
this->RemoveEvents();
if( this->m_uiGCHandle )
{
mono_gchandle_free( this->m_uiGCHandle );
@ -58,43 +52,62 @@ CResource::~CResource( void )
this->m_pLuaVM = nullptr;
}
bool CResource::CallEvent( string strEventName, void* pThis, void* pSource, void* pClient, void **args )
bool CResource::CallEvent( string strEventName, void* pThis, list< CLuaArgument* > argv )
{
MonoEvent* pEvent = nullptr;
MonoMethod* method = nullptr;
CMonoClass* pClass = this->GetDomain()->GetMTALib()->GetClass( "Element" );
MonoClass* klass = pClass->GetMonoPtr();
g_pModuleManager->DebugPrintf( this->GetLua(), "[%s] CResource::CallEvent::%s", this->m_sName.c_str(), strEventName.substr( 2 ).c_str() );
gpointer iter;
while( klass )
if( !pThis )
{
iter = nullptr;
while( pEvent = mono_class_get_events( klass, &iter ) )
{
if( !strcmp( strEventName.substr( 2 ).c_str(), mono_event_get_name( pEvent ) ) )
{
method = mono_event_get_raise_method( pEvent );
break;
}
}
klass = mono_class_get_parent( klass );
return false;
}
if( method )
CMonoMTALib* pMTALib = this->GetDomain()->GetMTALib();
CMonoClass* pClass = pMTALib->GetClass( "Element" );
CMonoEvent* pEvent = pClass->GetEvent( strEventName );
if( !pEvent )
{
mono_runtime_invoke( method, pThis, args, nullptr );
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 )
{
if( this->m_pLuaVM )
{
char szBuffer[ 128 ];
sprintf( szBuffer, "addEventHandler( '%s', %s, _mono_event_handler, true, 'normal' );", szName, szHandleElement );
luaL_dostring( this->m_pLuaVM, szBuffer );
return true;
}
else
return false;
}
bool CResource::RemoveEvent( const char* szName, const char* szHandleElement )
{
if( this->m_pLuaVM )
{
g_pModuleManager->ErrorPrintf( "mono: method not found\n" );
char szBuffer[ 128 ];
sprintf( szBuffer, "removeEventHandler( '%s', %s, _mono_event_handler );", szName, szHandleElement );
luaL_dostring( this->m_pLuaVM, szBuffer );
return true;
}
return false;
@ -106,12 +119,41 @@ void CResource::RegisterEvents( void )
{
if( g_pModuleManager->RegisterFunction( this->m_pLuaVM, "mono_event_handler", CFunctions::monoEventHandler ) )
{
luaL_dostring( this->m_pLuaVM, "addEventHandler( 'onElementDestroy', resourceRoot, \
function( ... ) \
mono_event_handler( eventName, this, source, client, ... );\
end \
)"
);
luaL_dostring( this->m_pLuaVM, "function _mono_event_handler( ... ) mono_event_handler( eventName, source, this, client, ... ); end" );
CMonoClass* pClass = this->GetDomain()->GetMTALib()->GetClass( "Element" );
if( pClass )
{
for( auto iter : pClass->GetAllEvents() )
{
string strEventName = iter.second->GetName();
strEventName[ 0 ] = tolower( strEventName[ 0 ] );
this->AddEvent( strEventName.c_str(), "root" );
}
}
}
}
}
void CResource::RemoveEvents( void )
{
if( this->m_pLuaVM )
{
CMonoClass* pClass = this->GetDomain()->GetMTALib()->GetClass( "Element" );
if( pClass )
{
for( auto iter : pClass->GetAllEvents() )
{
string strEventName = iter.second->GetName();
strEventName[ 0 ] = tolower( strEventName[ 0 ] );
this->RemoveEvent( strEventName.c_str(), "root" );
}
}
}
}
@ -166,6 +208,7 @@ bool CResource::Init( void )
void CResource::OnStopping( void )
{
}
void CResource::DoPulse( void )

View File

@ -17,9 +17,20 @@ class CResource;
#include "Common.h"
#include "CMonoClass.h"
#include "CMonoEvent.h"
#include "CMonoInterface.h"
#include "CResourceManager.h"
#include "CFunctions.h"
#include "extra/CLuaArgument.h"
#include "extra/CLuaArguments.h"
#include "include/ILuaModuleManager.h"
#include "lua/CLuaFunctionDefinitions.h"
extern ILuaModuleManager10 *g_pModuleManager;
class CResource
{
private:
@ -40,9 +51,12 @@ public:
CResource ( CMonoInterface* m_pMono, lua_State *pLuaVM, string sName );
~CResource ( void );
bool CallEvent ( string strEventName, void* pThis, void* pSource, void* pClient, void **args );
bool CallEvent ( string strEventName, void* pThis, list< CLuaArgument* > argv );
bool AddEvent ( const char* szName, const char* szHandleElement );
bool RemoveEvent ( const char* szName, const char* szHandleElement );
void RegisterEvents ( void );
void RemoveEvents ( void );
bool Init ( void );
void OnStopping ( void );
void DoPulse ( void );
@ -56,6 +70,9 @@ public:
lua_State* GetLua ( void ) { return this->m_pLuaVM; }
CMonoInterface* GetMono ( void ) { return this->m_pMono; }
CMonoDomain* GetDomain ( void ) { return this->m_pMonoDomain; }
private:
};
#endif