Resolved #3 (Изменить точку доступа на Program::Main)

This commit is contained in:
Kernell 2015-12-01 15:50:50 +03:00
parent 42914cd9e4
commit 457aa93ec4
9 changed files with 139 additions and 69 deletions

26
Test/Program.cs Normal file
View File

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using MultiTheftAuto;
using MultiTheftAuto.EventArgs;
namespace Test
{
public class Program
{
static void Main( string[] args )
{
Element.Root.OnElementDestroy += Root_ElementDestroy;
Vehicle vehicle = new Vehicle( VehicleModel.ADMIRAL, Vector3.Zero, Vector3.Zero );
vehicle.OnElementDestroy += Root_ElementDestroy;
vehicle.Destroy();
}
public static void Root_ElementDestroy( Element sender, ElementEventArgs e )
{
Debug.Info( "Root_ElementDestroy {0} {1}", sender.GetType(), e.This.GetType() );
}
}
}

View File

@ -63,8 +63,6 @@ CMonoClass::CMonoClass( MonoClass* pMonoClass, CMonoDomain* pDomain )
CMonoClass::~CMonoClass( void ) CMonoClass::~CMonoClass( void )
{ {
this->m_pDomain->ReleaseClass( this );
this->m_pDomain = nullptr; this->m_pDomain = nullptr;
this->m_pClass = nullptr; this->m_pClass = nullptr;
@ -84,14 +82,16 @@ CMonoClass::~CMonoClass( void )
this->m_Properties.clear(); this->m_Properties.clear();
for( auto iter : this->m_Methods ) auto iter = this->m_Methods.begin();
for( ; iter != this->m_Methods.end(); iter++ )
{ {
for( auto method : iter.second ) for( CMonoMethod* method : iter->second )
{ {
delete method; delete method;
} }
iter.second.clear(); iter->second.clear();
} }
this->m_Methods.clear(); this->m_Methods.clear();

View File

@ -12,14 +12,20 @@
#include "CMonoDomain.h" #include "CMonoDomain.h"
CMonoDomain::CMonoDomain( CMonoInterface* pMono, MonoDomain* pDomain, CResource* pResource ) CMonoDomain::CMonoDomain( CMonoInterface* pMono, MonoDomain* pDomain, CResource* pResource, char* szName )
{ {
this->m_pMono = pMono; this->m_pMono = pMono;
this->m_pDomain = pDomain; this->m_pDomain = pDomain;
this->m_pResource = pResource; this->m_pResource = pResource;
this->m_strName = szName;
this->m_pCorlib = nullptr; this->m_pCorlib = nullptr;
this->m_pMTALib = nullptr; this->m_pMTALib = nullptr;
this->m_pMonoAssembly = nullptr;
this->m_pMonoImage = nullptr;
this->m_pMonoClass = nullptr;
} }
CMonoDomain::~CMonoDomain( void ) CMonoDomain::~CMonoDomain( void )
@ -35,6 +41,18 @@ CMonoDomain::~CMonoDomain( void )
this->m_ClassPool.clear(); this->m_ClassPool.clear();
this->m_pDomain = nullptr; this->m_pDomain = nullptr;
this->m_pMonoAssembly = nullptr;
this->m_pMonoImage = nullptr;
this->m_pMonoClass = nullptr;
}
void CMonoDomain::HandleException( MonoObject* pException )
{
if( pException )
{
g_pModuleManager->ErrorPrintf( "%s\n", mono_string_to_utf8( mono_object_to_string( pException, nullptr ) ) );
}
} }
CMonoClass* CMonoDomain::FindOrAdd( MonoClass* klass ) CMonoClass* CMonoDomain::FindOrAdd( MonoClass* klass )
@ -64,20 +82,79 @@ CMonoClass* CMonoDomain::FindOrAdd( MonoClass* klass )
return nullptr; return nullptr;
} }
void CMonoDomain::ReleaseClass( CMonoClass* pClass )
{
if( !this->m_ClassPool.empty() )
{
this->m_ClassPool.remove( pClass );
}
}
void CMonoDomain::Init( void ) void CMonoDomain::Init( void )
{ {
this->m_pCorlib = new CMonoCorlib( this ); this->m_pCorlib = new CMonoCorlib( this );
this->m_pMTALib = new CMonoMTALib( this ); this->m_pMTALib = new CMonoMTALib( this );
} }
bool CMonoDomain::Start( void )
{
string sDirectory ( CMonoInterface::GetBinariesDirectory() + "/" + this->m_strName + "/" );
string sPath ( sDirectory + this->m_strName + ".dll" );
string sNamespace ( this->m_strName );
string sClass ( "Program" );
this->m_pMonoAssembly = this->OpenAssembly( sPath.c_str() );
if( !this->m_pMonoAssembly )
{
g_pModuleManager->ErrorPrintf( "failed to open assembly '%s.dll'\n", this->m_strName.c_str() );
return false;
}
this->GetResource()->RegisterEvents();
this->m_pMonoImage = mono_assembly_get_image( this->m_pMonoAssembly );
if( !this->m_pMonoImage )
{
g_pModuleManager->ErrorPrintf( "failed to get image '%s.dll'\n", this->m_strName.c_str() );
return false;
}
this->m_pMonoClass = this->FindOrAdd( mono_class_from_name( this->m_pMonoImage, sNamespace.c_str(), sClass.c_str() ) );
if( !this->m_pMonoClass )
{
g_pModuleManager->ErrorPrintf( "class '%s' not found in '%s.dll'\n", sClass.c_str(), this->m_strName.c_str() );
return false;
}
CMonoMethod* pMethod = this->m_pMonoClass->GetMethod( "Main", 0 );
if( !pMethod )
{
g_pModuleManager->ErrorPrintf( "static method '%s::Main' not found in '%s.dll'\n", sClass.c_str(), this->m_strName.c_str() );
return false;
}
MonoString* pString1 = this->NewString( this->m_strName.c_str() );
MonoArray* pArray = mono_array_new( this->m_pDomain, mono_get_string_class(), 1 );
mono_array_set( pArray, MonoString*, 0, pString1 );
void* params[ 1 ];
params[ 0 ] = pArray;
MonoObject* pException = nullptr;
pMethod->Invoke( nullptr, params, pException );
if( pException )
{
this->HandleException( pException );
}
return true;
}
void CMonoDomain::Unload( void ) void CMonoDomain::Unload( void )
{ {
mono_domain_unload( this->m_pDomain ); mono_domain_unload( this->m_pDomain );

View File

@ -30,20 +30,27 @@ private:
CResource* m_pResource; CResource* m_pResource;
CMonoInterface* m_pMono; CMonoInterface* m_pMono;
MonoAssembly* m_pMonoAssembly;
MonoImage* m_pMonoImage;
CMonoClass* m_pMonoClass;
CMonoCorlib* m_pCorlib; CMonoCorlib* m_pCorlib;
CMonoMTALib* m_pMTALib; CMonoMTALib* m_pMTALib;
list< CMonoClass* > m_ClassPool; vector< CMonoClass* > m_ClassPool;
string m_strName;
public: public:
CMonoDomain ( CMonoInterface* pMono, MonoDomain* pDomain, CResource* pResource ); CMonoDomain ( CMonoInterface* pMono, MonoDomain* pDomain, CResource* pResource, char* szName );
~CMonoDomain ( void ); ~CMonoDomain ( void );
void HandleException ( MonoObject* pException );
CMonoClass* FindOrAdd ( MonoClass* klass ); CMonoClass* FindOrAdd ( MonoClass* klass );
void ReleaseClass ( CMonoClass* pClass );
void Init ( void ); void Init ( void );
bool Start ( void );
void Unload ( void ); void Unload ( void );
bool Set ( bool bForce ); bool Set ( bool bForce );
MonoAssembly* OpenAssembly ( const char *szName ); MonoAssembly* OpenAssembly ( const char *szName );
@ -96,6 +103,8 @@ public:
CMonoCorlib* GetCorlib ( void ) { return this->m_pCorlib; } CMonoCorlib* GetCorlib ( void ) { return this->m_pCorlib; }
CMonoMTALib* GetMTALib ( void ) { return this->m_pMTALib; } CMonoMTALib* GetMTALib ( void ) { return this->m_pMTALib; }
string GetName ( void ) { return this->m_strName; }
}; };
#endif #endif

View File

@ -43,7 +43,7 @@ CMonoDomain* CMonoInterface::CreateAppdomain( CResource* pResource, char* szName
if( pMonoDomain ) if( pMonoDomain )
{ {
return new CMonoDomain( this, pMonoDomain, pResource ); return new CMonoDomain( this, pMonoDomain, pResource, szName );
} }
return nullptr; return nullptr;

View File

@ -47,10 +47,10 @@ CMonoMTALib::CMonoMTALib( CMonoDomain* pDomain )
CMonoMTALib::~CMonoMTALib( void ) CMonoMTALib::~CMonoMTALib( void )
{ {
SAFE_DELETE( this->Color ); this->Color = nullptr;
SAFE_DELETE( this->Vector2 ); this->Vector2 = nullptr;
SAFE_DELETE( this->Vector3 ); this->Vector3 = nullptr;
SAFE_DELETE( this->m_pClass ); this->m_pClass = nullptr;
this->m_pDomain = nullptr; this->m_pDomain = nullptr;
this->m_pAssembly = nullptr; this->m_pAssembly = nullptr;

View File

@ -24,6 +24,8 @@ CMonoMethod::CMonoMethod( CMonoClass* pClass, MonoMethod* pMethod )
CMonoMethod::~CMonoMethod( void ) CMonoMethod::~CMonoMethod( void )
{ {
this->m_ArgList.clear();
this->m_pClass = nullptr; this->m_pClass = nullptr;
this->m_pMethod = nullptr; this->m_pMethod = nullptr;
} }

View File

@ -18,35 +18,20 @@ CResource::CResource( CMonoInterface* pMono, lua_State *pLuaVM, string sName )
this->m_pLuaVM = pLuaVM; this->m_pLuaVM = pLuaVM;
this->m_sName = sName; this->m_sName = sName;
this->m_pMonoAssembly = nullptr;
this->m_pMonoDomain = nullptr; this->m_pMonoDomain = nullptr;
this->m_pMonoImage = nullptr;
this->m_pMonoClass = nullptr;
this->m_uiGCHandle = 0;
} }
CResource::~CResource( void ) CResource::~CResource( void )
{ {
this->RemoveEvents(); this->RemoveEvents();
if( this->m_uiGCHandle )
{
mono_gchandle_free( this->m_uiGCHandle );
this->m_uiGCHandle = 0;
}
this->GetMono()->GetGC()->Collect( this->GetMono()->GetGC()->GetMaxGeneration() ); this->GetMono()->GetGC()->Collect( this->GetMono()->GetGC()->GetMaxGeneration() );
mono_domain_set( mono_get_root_domain(), true ); mono_domain_set( mono_get_root_domain(), true );
g_pResourceManager->RemoveFromList( this ); g_pResourceManager->RemoveFromList( this );
this->m_pMonoAssembly = nullptr; SAFE_DELETE( this->m_pMonoDomain );
this->m_pMonoDomain = nullptr;
this->m_pMonoImage = nullptr;
this->m_pMonoClass = nullptr;
this->m_pMono = nullptr; this->m_pMono = nullptr;
this->m_pLuaVM = nullptr; this->m_pLuaVM = nullptr;
@ -162,11 +147,6 @@ bool CResource::Init( void )
{ {
if( this->m_pLuaVM ) if( this->m_pLuaVM )
{ {
string sDirectory ( CMonoInterface::GetBinariesDirectory() + "/" + this->m_sName + "/" );
string sPath ( sDirectory + this->m_sName + ".dll" );
string sNamespace ( this->m_sName );
string sClass ( "Program" );
this->m_pMonoDomain = this->GetMono()->CreateAppdomain( this, const_cast< char* >( this->m_sName.c_str() ), nullptr ); this->m_pMonoDomain = this->GetMono()->CreateAppdomain( this, const_cast< char* >( this->m_sName.c_str() ), nullptr );
if( !this->m_pMonoDomain ) if( !this->m_pMonoDomain )
@ -180,25 +160,7 @@ bool CResource::Init( void )
this->m_pMonoDomain->Init(); this->m_pMonoDomain->Init();
this->m_pMonoAssembly = this->m_pMonoDomain->OpenAssembly( sPath.c_str() ); this->m_pMonoDomain->Start();
if( !this->m_pMonoAssembly )
{
g_pModuleManager->ErrorPrintf( "failed to open assembly '%s.dll'\n", this->m_sName.c_str() );
return false;
}
this->RegisterEvents();
this->m_pMonoImage = mono_assembly_get_image( this->m_pMonoAssembly );
this->m_pMonoClass = mono_class_from_name( this->m_pMonoImage, sNamespace.c_str(), sClass.c_str() );
MonoObject *pMonoObject = this->m_pMonoDomain->CreateObject( this->m_pMonoClass );
mono_runtime_object_init( pMonoObject );
this->m_uiGCHandle = mono_gchandle_new( pMonoObject, true );
return true; return true;
} }

View File

@ -36,12 +36,6 @@ class CResource
private: private:
string m_sName; string m_sName;
MonoAssembly* m_pMonoAssembly;
MonoImage* m_pMonoImage;
MonoClass* m_pMonoClass;
uint32_t m_uiGCHandle;
lua_State* m_pLuaVM; lua_State* m_pLuaVM;
CMonoInterface* m_pMono; CMonoInterface* m_pMono;