mirror of
https://github.com/ChronosX88/mta-mono.git
synced 2024-12-22 17:01:47 +00:00
Добавлена поддержка событий MTA
This commit is contained in:
parent
5bd91b1c98
commit
07e2feba72
@ -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" />
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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 ];
|
||||
}
|
||||
|
@ -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; }
|
||||
};
|
||||
|
@ -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
331
mta-mono/src/CMonoEvent.cpp
Normal 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
52
mta-mono/src/CMonoEvent.h
Normal 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
|
@ -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;
|
||||
}
|
@ -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; }
|
||||
};
|
||||
|
||||
|
65
mta-mono/src/CMonoMethod.cpp
Normal file
65
mta-mono/src/CMonoMethod.cpp
Normal 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 );
|
||||
}
|
58
mta-mono/src/CMonoMethod.h
Normal file
58
mta-mono/src/CMonoMethod.h
Normal 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
|
@ -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 )
|
||||
|
@ -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
|
Loading…
Reference in New Issue
Block a user