From 457aa93ec4fe5d17bf924b3a1596cde52624306e Mon Sep 17 00:00:00 2001 From: Kernell Date: Tue, 1 Dec 2015 15:50:50 +0300 Subject: [PATCH] =?UTF-8?q?Resolved=20#3=20(=D0=98=D0=B7=D0=BC=D0=B5=D0=BD?= =?UTF-8?q?=D0=B8=D1=82=D1=8C=20=D1=82=D0=BE=D1=87=D0=BA=D1=83=20=D0=B4?= =?UTF-8?q?=D0=BE=D1=81=D1=82=D1=83=D0=BF=D0=B0=20=D0=BD=D0=B0=20Program::?= =?UTF-8?q?Main)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- Test/Program.cs | 26 +++++++++ mta-mono/src/CMonoClass.cpp | 10 ++-- mta-mono/src/CMonoDomain.cpp | 95 +++++++++++++++++++++++++++++---- mta-mono/src/CMonoDomain.h | 17 ++++-- mta-mono/src/CMonoInterface.cpp | 2 +- mta-mono/src/CMonoMTALib.cpp | 8 +-- mta-mono/src/CMonoMethod.cpp | 2 + mta-mono/src/CResource.cpp | 42 +-------------- mta-mono/src/CResource.h | 6 --- 9 files changed, 139 insertions(+), 69 deletions(-) create mode 100644 Test/Program.cs diff --git a/Test/Program.cs b/Test/Program.cs new file mode 100644 index 0000000..576ec5f --- /dev/null +++ b/Test/Program.cs @@ -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() ); + } + } +} diff --git a/mta-mono/src/CMonoClass.cpp b/mta-mono/src/CMonoClass.cpp index 7a9c490..f859ae6 100644 --- a/mta-mono/src/CMonoClass.cpp +++ b/mta-mono/src/CMonoClass.cpp @@ -63,8 +63,6 @@ CMonoClass::CMonoClass( MonoClass* pMonoClass, CMonoDomain* pDomain ) CMonoClass::~CMonoClass( void ) { - this->m_pDomain->ReleaseClass( this ); - this->m_pDomain = nullptr; this->m_pClass = nullptr; @@ -84,14 +82,16 @@ CMonoClass::~CMonoClass( void ) 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; } - iter.second.clear(); + iter->second.clear(); } this->m_Methods.clear(); diff --git a/mta-mono/src/CMonoDomain.cpp b/mta-mono/src/CMonoDomain.cpp index ab2fc9e..ec54e43 100644 --- a/mta-mono/src/CMonoDomain.cpp +++ b/mta-mono/src/CMonoDomain.cpp @@ -12,14 +12,20 @@ #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_pDomain = pDomain; this->m_pResource = pResource; + this->m_strName = szName; + this->m_pCorlib = nullptr; this->m_pMTALib = nullptr; + + this->m_pMonoAssembly = nullptr; + this->m_pMonoImage = nullptr; + this->m_pMonoClass = nullptr; } CMonoDomain::~CMonoDomain( void ) @@ -35,6 +41,18 @@ CMonoDomain::~CMonoDomain( void ) this->m_ClassPool.clear(); 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 ) @@ -64,20 +82,79 @@ CMonoClass* CMonoDomain::FindOrAdd( MonoClass* klass ) return nullptr; } -void CMonoDomain::ReleaseClass( CMonoClass* pClass ) -{ - if( !this->m_ClassPool.empty() ) - { - this->m_ClassPool.remove( pClass ); - } -} - void CMonoDomain::Init( void ) { this->m_pCorlib = new CMonoCorlib( 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 ) { mono_domain_unload( this->m_pDomain ); diff --git a/mta-mono/src/CMonoDomain.h b/mta-mono/src/CMonoDomain.h index a5d877e..683becd 100644 --- a/mta-mono/src/CMonoDomain.h +++ b/mta-mono/src/CMonoDomain.h @@ -30,20 +30,27 @@ private: CResource* m_pResource; CMonoInterface* m_pMono; + MonoAssembly* m_pMonoAssembly; + MonoImage* m_pMonoImage; + CMonoClass* m_pMonoClass; + CMonoCorlib* m_pCorlib; CMonoMTALib* m_pMTALib; - list< CMonoClass* > m_ClassPool; + vector< CMonoClass* > m_ClassPool; + + string m_strName; public: - CMonoDomain ( CMonoInterface* pMono, MonoDomain* pDomain, CResource* pResource ); + CMonoDomain ( CMonoInterface* pMono, MonoDomain* pDomain, CResource* pResource, char* szName ); ~CMonoDomain ( void ); + void HandleException ( MonoObject* pException ); + CMonoClass* FindOrAdd ( MonoClass* klass ); - void ReleaseClass ( CMonoClass* pClass ); void Init ( void ); - + bool Start ( void ); void Unload ( void ); bool Set ( bool bForce ); MonoAssembly* OpenAssembly ( const char *szName ); @@ -96,6 +103,8 @@ public: CMonoCorlib* GetCorlib ( void ) { return this->m_pCorlib; } CMonoMTALib* GetMTALib ( void ) { return this->m_pMTALib; } + + string GetName ( void ) { return this->m_strName; } }; #endif \ No newline at end of file diff --git a/mta-mono/src/CMonoInterface.cpp b/mta-mono/src/CMonoInterface.cpp index a8e1ed8..2ce8065 100644 --- a/mta-mono/src/CMonoInterface.cpp +++ b/mta-mono/src/CMonoInterface.cpp @@ -43,7 +43,7 @@ CMonoDomain* CMonoInterface::CreateAppdomain( CResource* pResource, char* szName if( pMonoDomain ) { - return new CMonoDomain( this, pMonoDomain, pResource ); + return new CMonoDomain( this, pMonoDomain, pResource, szName ); } return nullptr; diff --git a/mta-mono/src/CMonoMTALib.cpp b/mta-mono/src/CMonoMTALib.cpp index 4182c36..3ec28be 100644 --- a/mta-mono/src/CMonoMTALib.cpp +++ b/mta-mono/src/CMonoMTALib.cpp @@ -47,10 +47,10 @@ CMonoMTALib::CMonoMTALib( CMonoDomain* pDomain ) CMonoMTALib::~CMonoMTALib( void ) { - SAFE_DELETE( this->Color ); - SAFE_DELETE( this->Vector2 ); - SAFE_DELETE( this->Vector3 ); - SAFE_DELETE( this->m_pClass ); + this->Color = nullptr; + this->Vector2 = nullptr; + this->Vector3 = nullptr; + this->m_pClass = nullptr; this->m_pDomain = nullptr; this->m_pAssembly = nullptr; diff --git a/mta-mono/src/CMonoMethod.cpp b/mta-mono/src/CMonoMethod.cpp index 520b4e1..cee8bcf 100644 --- a/mta-mono/src/CMonoMethod.cpp +++ b/mta-mono/src/CMonoMethod.cpp @@ -24,6 +24,8 @@ CMonoMethod::CMonoMethod( CMonoClass* pClass, MonoMethod* pMethod ) CMonoMethod::~CMonoMethod( void ) { + this->m_ArgList.clear(); + this->m_pClass = nullptr; this->m_pMethod = nullptr; } diff --git a/mta-mono/src/CResource.cpp b/mta-mono/src/CResource.cpp index 0046e4f..bac6465 100644 --- a/mta-mono/src/CResource.cpp +++ b/mta-mono/src/CResource.cpp @@ -18,35 +18,20 @@ CResource::CResource( CMonoInterface* pMono, lua_State *pLuaVM, string sName ) this->m_pLuaVM = pLuaVM; this->m_sName = sName; - this->m_pMonoAssembly = nullptr; this->m_pMonoDomain = nullptr; - this->m_pMonoImage = nullptr; - this->m_pMonoClass = nullptr; - - this->m_uiGCHandle = 0; } CResource::~CResource( void ) { this->RemoveEvents(); - if( this->m_uiGCHandle ) - { - mono_gchandle_free( this->m_uiGCHandle ); - - this->m_uiGCHandle = 0; - } - this->GetMono()->GetGC()->Collect( this->GetMono()->GetGC()->GetMaxGeneration() ); mono_domain_set( mono_get_root_domain(), true ); g_pResourceManager->RemoveFromList( this ); - this->m_pMonoAssembly = nullptr; - this->m_pMonoDomain = nullptr; - this->m_pMonoImage = nullptr; - this->m_pMonoClass = nullptr; + SAFE_DELETE( this->m_pMonoDomain ); this->m_pMono = nullptr; this->m_pLuaVM = nullptr; @@ -162,11 +147,6 @@ bool CResource::Init( void ) { 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 ); if( !this->m_pMonoDomain ) @@ -180,25 +160,7 @@ bool CResource::Init( void ) this->m_pMonoDomain->Init(); - this->m_pMonoAssembly = this->m_pMonoDomain->OpenAssembly( sPath.c_str() ); - - 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 ); + this->m_pMonoDomain->Start(); return true; } diff --git a/mta-mono/src/CResource.h b/mta-mono/src/CResource.h index 94bccb4..4c41116 100644 --- a/mta-mono/src/CResource.h +++ b/mta-mono/src/CResource.h @@ -36,12 +36,6 @@ class CResource private: string m_sName; - MonoAssembly* m_pMonoAssembly; - MonoImage* m_pMonoImage; - MonoClass* m_pMonoClass; - - uint32_t m_uiGCHandle; - lua_State* m_pLuaVM; CMonoInterface* m_pMono;