6e8fbca745
match the genesis editor version 1.3.0.653.
1264 lines
39 KiB
C++
1264 lines
39 KiB
C++
/****************************************************************************
|
||
Copyright (c) 2011-2013,WebJet Business Division,CYOU
|
||
|
||
http://www.genesis-3d.com.cn
|
||
|
||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||
of this software and associated documentation files (the "Software"), to deal
|
||
in the Software without restriction, including without limitation the rights
|
||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||
copies of the Software, and to permit persons to whom the Software is
|
||
furnished to do so, subject to the following conditions:
|
||
|
||
The above copyright notice and this permission notice shall be included in
|
||
all copies or substantial portions of the Software.
|
||
|
||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||
THE SOFTWARE.
|
||
****************************************************************************/
|
||
#include "stdneb.h"
|
||
#include "foundation/util/stringconvert.h"
|
||
#include "scriptfeature/inc/script_utility.h"
|
||
#include "scriptfeature/mono_icall_registration.h"
|
||
#include "scriptfeature/script_general_manager.h"
|
||
#include "appframework/app_fwd_decl.h"
|
||
|
||
#include "app/scriptfeature/script_message_regist.h"
|
||
#include "app/scriptfeature/inc/script_message.h"
|
||
#include "app/scriptfeature/inc/script_instance.h"
|
||
#include "app/scriptfeature/mono_script.h"
|
||
#include "util/assetpath.h"
|
||
|
||
// - for RTTI
|
||
#include "graphicfeature/components/meshrendercomponent.h"
|
||
#include "graphicfeature/components/skinnedmeshrendercomponent.h"
|
||
#include "graphicfeature/components/projectorcomponent.h"
|
||
#include "graphicfeature/components/skeletoncomponent.h"
|
||
#include "graphicfeature/components/spriterendercomponent.h"
|
||
#include "graphicfeature/components/animationcomponent.h"
|
||
#include "particlefeature/components/particlerendercomponent.h"
|
||
#include "graphicfeature/components/cameracomponent.h"
|
||
#include "graphicfeature/components/lightcomponent.h"
|
||
#include "scriptfeature/inc/script_component.h"
|
||
#include "scriptfeature/editable_field_value.h"
|
||
#include "scriptfeature/script_root_instance.h"
|
||
#include <stdexcept>
|
||
|
||
#if __USE_PHYSX__ || __GENESIS_EDITOR__
|
||
#include "physXfeature/PhysicsBodyComponent.h"
|
||
#endif // __USE_PHYSX__ || __GENESIS_EDITOR__
|
||
|
||
#if __USE_AUDIO__ || __GENESIS_EDITOR__
|
||
#include "soundfeature/components/SoundSourceComponent.h"
|
||
#include "soundfeature/components/SoundEchoFilterComponent.h"
|
||
#include "soundfeature/components/SoundLowPassFilterComponent.h"
|
||
#include "soundfeature/components/SoundReverbFilterComponent.h"
|
||
#endif // __USE_AUDIO__ || __GENESIS_EDITOR__
|
||
|
||
#ifdef __WIN32__
|
||
#include "WinBase.h" // - for LoadLibrary and GetProcAddress
|
||
static HMODULE s_monoDllHandle = NULL;
|
||
#elif defined(__ANDROID__)
|
||
#include "dlfcn.h" // - for dlopen and dlsym
|
||
static void* s_monoSOHandle;
|
||
#endif
|
||
|
||
#define MONO_API_TYPE(ret, fun, params) typedef ret (*_fp_mono_##fun) params;
|
||
#define MONO_API_DECL(ret,fun, params) _fp_mono_##fun fun = NULL;
|
||
#define GET_MONO_API(ret, fun, params) fun = (_fp_mono_##fun) GetProcAddress(hMonoModule, #fun); if( NULL==fun ) { n_assert(false && "can't find " #fun " in mono dll"); }
|
||
#define GET_MONO_API_ANDROID(ret, fun, params) fun = (_fp_mono_##fun) dlsym(hMonoModule, #fun); if( NULL==fun ) { n_assert(false && "can't find " #fun " in mono so"); }
|
||
#define RESET_MONO_API(ret,fun,params) fun = NULL;
|
||
|
||
// - make a typedef for each function pointer
|
||
#ifndef __OSX__
|
||
ALL_MONO_API(MONO_API_TYPE)
|
||
ALL_MONO_API(MONO_API_DECL)
|
||
#endif
|
||
|
||
#ifdef __OSX__
|
||
#include "RegisterMonoModules.h"
|
||
#endif
|
||
|
||
static bool gEnableMonoDebugger = false;
|
||
|
||
//------------------------------------------------------------------------------
|
||
namespace App
|
||
{
|
||
static Util::String g_LastError = "";
|
||
|
||
bool StartupSciptSystem( const Util::String& monoDirPaths,
|
||
const Util::String& monoConfigsPath,
|
||
const Util::String& monoDllPath,
|
||
bool bEnableMonoDebugger )
|
||
{
|
||
//setenv(<#const char *#>, <#const char *#>, <#int#>)
|
||
#ifdef __OSX__
|
||
RegisterMonoModules();
|
||
#endif
|
||
bool bLoadDll = LoadMonoDll( monoDllPath );
|
||
n_assert( bLoadDll );
|
||
// - set mono dll search path
|
||
mono_set_assemblies_path( monoDirPaths.AsCharPtr() );
|
||
|
||
gEnableMonoDebugger = bEnableMonoDebugger;
|
||
|
||
if ( bEnableMonoDebugger )
|
||
{
|
||
static const char* options[] =
|
||
{
|
||
//"--soft-breakpoints" // action in higher version mono
|
||
"--debugger-agent=transport=dt_socket,address=127.0.0.1:52013,server=n",
|
||
};
|
||
mono_jit_parse_options( sizeof(options)/sizeof(char*), (char**)options );
|
||
mono_debug_init( 1 ); // 1 stands for MONO_DEBUG_FORMAT_MONO, for more detail see the mono source code mono-debug.g
|
||
|
||
n_dbgout( "Script system is in debug state!" );
|
||
}
|
||
// - init mono
|
||
MonoDomain* pDomain = mono_jit_init_version ( "MainMonoDomain", "v2.0.50727" );
|
||
script_fatal_error( NULL!=pDomain );
|
||
|
||
if ( bEnableMonoDebugger )
|
||
{
|
||
// - The mono soft debugger needs this
|
||
mono_thread_set_main( mono_thread_current() );
|
||
}
|
||
|
||
// - register internal call functions
|
||
RegisterInternalCalls();
|
||
|
||
// - init message generator
|
||
ScriptMessageCreator::CreateSingleton();
|
||
|
||
// - register all messages
|
||
Reg_ScriptRuntime_Message();
|
||
// - init script general manager
|
||
ScriptGeneralManager::CreateSingleton();
|
||
|
||
// - create a child domain,and run in this child domain
|
||
#ifndef __OSX__
|
||
MonoDomain* domain = Utility_CreateChildDomain();
|
||
script_fatal_error( NULL!=domain );
|
||
Utility_SetChildDomain( domain );
|
||
#endif
|
||
|
||
// - load runtime library
|
||
ScriptGeneralManager::Instance()->LoadAssemblies( bEnableMonoDebugger );
|
||
|
||
// - setup script global instance
|
||
ScriptRootInstance::CreateSingleton();
|
||
ScriptRootInstance::Instance()->Init();
|
||
return true;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
bool ShutDownScriptSystem()
|
||
{
|
||
// - release singletons
|
||
ScriptMessageCreator::DestorySingleton();
|
||
ScriptGeneralManager::DestorySingleton();
|
||
ScriptRootInstance::DestorySingleton();
|
||
|
||
// - unload child domain first
|
||
Utility_UnloadChildDomain();
|
||
// - make sure that there's only a root domain now
|
||
n_assert(mono_domain_get()==mono_get_root_domain());
|
||
mono_jit_cleanup( mono_domain_get() );
|
||
// - unload mono dll
|
||
UnloadMonoDll();
|
||
|
||
#if defined(__WIN32__) && (!defined(__GENESIS_EDITOR__))// hack __WIN32__<5F><5F><EFBFBD>˳<EFBFBD><CBB3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>⡣// && defined(_DEBUG)
|
||
HMODULE module_handle = GetModuleHandleW(L"mscoree.dll");
|
||
if (module_handle)
|
||
{
|
||
while(::FreeLibrary (module_handle));
|
||
}
|
||
#endif
|
||
return true;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
Util::String GetLastError()
|
||
{
|
||
return g_LastError;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
bool LoadMonoDll( const Util::String& monoDllPath )
|
||
{
|
||
#ifdef __WIN32__
|
||
// - dynamic load mono dll
|
||
char16_t path[512] = {0};
|
||
Util::StringConvert::UTF8ToWide(monoDllPath.AsCharPtr(), path, 512);
|
||
HMODULE hMonoModule = LoadLibraryW( (wchar_t*)path );
|
||
if (!hMonoModule)
|
||
{
|
||
g_LastError = monoDllPath + " not found!";
|
||
throw(0);
|
||
}
|
||
|
||
n_printf("\n mono dll path: %s\n",monoDllPath.AsCharPtr());
|
||
n_assert( NULL!=hMonoModule );
|
||
|
||
// - save this handle
|
||
s_monoDllHandle = hMonoModule;
|
||
|
||
// - assign value to the function pointer which we define before
|
||
|
||
ALL_MONO_API(GET_MONO_API)
|
||
|
||
#elif defined(__ANDROID__)
|
||
// - dynamic load mono dll
|
||
const char* loadInfo = NULL;
|
||
|
||
void* hMonoModule = dlopen( (char*)monoDllPath.AsCharPtr() ,RTLD_LAZY);
|
||
n_printf("\n monodllpath: %s\n",monoDllPath.AsCharPtr());
|
||
loadInfo = dlerror();
|
||
if(NULL != loadInfo)
|
||
n_printf("\n load_error: %s\n",loadInfo);
|
||
else
|
||
n_printf("\n load_successful\n");
|
||
|
||
n_printf("\n monodllpath: %s\n",monoDllPath.AsCharPtr());
|
||
n_assert( NULL!=hMonoModule );
|
||
|
||
// - save this handle
|
||
s_monoSOHandle = hMonoModule;
|
||
|
||
// - assign value to the function pointer which we define before
|
||
ALL_MONO_API(GET_MONO_API_ANDROID)
|
||
#endif
|
||
return true;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void UnloadMonoDll()
|
||
{
|
||
#ifndef __OSX__
|
||
ALL_MONO_API(RESET_MONO_API)
|
||
#endif
|
||
|
||
#ifdef __WIN32__
|
||
if( s_monoDllHandle )
|
||
{
|
||
::FreeLibrary( s_monoDllHandle );
|
||
s_monoDllHandle = NULL;
|
||
}
|
||
#elif defined(__ANDROID__)
|
||
if(s_monoSOHandle){
|
||
dlclose(s_monoSOHandle);
|
||
s_monoSOHandle = NULL;
|
||
}
|
||
#endif
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void Utility_RegularPath( Util::String& inout )
|
||
{
|
||
int len = inout.Length();
|
||
int dis = 'a' - 'A' ;
|
||
for( int i=0; i<len; i++ )
|
||
{
|
||
char ch = inout[i];
|
||
if( ch=='\\' )
|
||
{
|
||
inout[i] ='/';
|
||
}
|
||
|
||
if ( ch>='A' &&
|
||
ch<='Z' )
|
||
{
|
||
inout[i] = ch + dis;
|
||
}
|
||
}
|
||
}
|
||
//------------------------------------------------------------------------
|
||
Util::String Utility_ExtractExtension( const Util::String& sPath )
|
||
{
|
||
int p = sPath.BackwardFindChar( '.' );
|
||
|
||
if ( InvalidIndex==p )
|
||
{
|
||
return Util::String( "No Extension" );
|
||
}
|
||
else if ( p<sPath.Length()-1 )
|
||
{
|
||
return sPath.ExtractToEnd( p+1 );
|
||
}
|
||
else //( p==sPath.Size )
|
||
{
|
||
return Util::String( "No Extension" );
|
||
}
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void Utility_ChangeExtension( Util::String& sPath, const Util::String& newEx )
|
||
{
|
||
int p = sPath.BackwardFindChar( '.' );
|
||
if ( InvalidIndex==p )
|
||
{
|
||
sPath.Append( "." + newEx );
|
||
}
|
||
else if ( p<sPath.Length()-1 )
|
||
{
|
||
sPath.TerminateAtIndex( p );
|
||
sPath.Append( "." + newEx );
|
||
}
|
||
else //( p==sPath.Size )
|
||
{
|
||
sPath.Append( newEx );
|
||
}
|
||
}
|
||
//------------------------------------------------------------------------
|
||
void Utility_RemoveNameSpace( Util::String& inout )
|
||
{
|
||
IndexT idx = inout.BackwardFindChar( ':' );
|
||
if ( idx>=1 &&
|
||
':'==inout[idx-1] && // - make sure there is "::"
|
||
idx+1!=inout.Length() ) // - make sure it is not the last one
|
||
{
|
||
inout.SetCharPtr( &inout[idx+1] );
|
||
}
|
||
}
|
||
//------------------------------------------------------------------------
|
||
MonoClass* Utility_GetMonoClassByName( const Util::String& sClassName, const Util::String& sNamespace, const Util::String& sAssemblyName )
|
||
{
|
||
return App::ScriptGeneralManager::Instance()->GetMonoClassByName( sClassName, sNamespace, sAssemblyName );
|
||
}
|
||
//------------------------------------------------------------------------
|
||
MonoClass* Utility_GetRuntimeMonoClass( const Util::String& sClassName )
|
||
{
|
||
Util::String sTempClassName = sClassName;
|
||
Utility_RemoveNameSpace( sTempClassName );
|
||
return Utility_GetMonoClassByName( sTempClassName, s_csScriptRuntimeNamespace, s_csScriptRuntimeLibraryName );
|
||
}
|
||
//------------------------------------------------------------------------
|
||
MonoString* Utility_NewMonoString( const Util::String& string )
|
||
{
|
||
MonoString* monoStr = mono_string_new_wrapper( string.AsCharPtr() );
|
||
n_assert( NULL!=monoStr );
|
||
|
||
return monoStr;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
MonoObject* Utility_GetDummyObject( void )
|
||
{
|
||
static MonoObject* pDummyObj = NULL;
|
||
if ( NULL==pDummyObj )
|
||
{
|
||
MonoClass* pMonoClass = Utility_GetRuntimeMonoClass( "DummyClass__" );
|
||
n_assert( NULL!=pMonoClass );
|
||
|
||
MonoDomain* pMonoDomain = mono_domain_get();
|
||
pDummyObj = mono_object_new( pMonoDomain, pMonoClass ) ;
|
||
n_assert( NULL!=pDummyObj );
|
||
|
||
mono_runtime_object_init( pDummyObj );
|
||
}
|
||
|
||
return pDummyObj;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
MonoObject* Utility_CreateMonoObj( MonoClass* pMonoClass )
|
||
{
|
||
n_assert( NULL!=pMonoClass );
|
||
|
||
MonoObject* pMonoObj = NULL;
|
||
MonoDomain* pMonoDomain = mono_domain_get();
|
||
pMonoObj = mono_object_new( pMonoDomain, pMonoClass ) ;
|
||
|
||
n_assert( NULL!=pMonoObj );
|
||
MonoMethodDesc* pDesc = mono_method_desc_new( ":.ctor(DummyClass__)", c_iMonoBool_False );
|
||
MonoMethod *pConstructor = NULL;
|
||
pConstructor = mono_method_desc_search_in_class( pDesc, pMonoClass );
|
||
n_assert( NULL!=pConstructor && "No specify constructor!" );
|
||
mono_method_desc_free(pDesc);
|
||
|
||
MonoObject* pDummyObj = Utility_GetDummyObject();
|
||
void* params[1] ;
|
||
params[0] = &pDummyObj;
|
||
if ( mono_class_is_valuetype(pMonoClass) )
|
||
{
|
||
MonoObject* pUnboxObj = pMonoObj;
|
||
pUnboxObj = (MonoObject*)mono_object_unbox ( pUnboxObj );
|
||
|
||
Utility_MonoRuntimeInvoke ( pConstructor, pUnboxObj, params );
|
||
}
|
||
else
|
||
{
|
||
Utility_MonoRuntimeInvoke ( pConstructor, pMonoObj, params );
|
||
}
|
||
|
||
return pMonoObj;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> void Utility_MonoStringToCppString( MonoString* pMonoStr, Util::String& buffer)
|
||
// <20>ر<EFBFBD><D8B1><EFBFBD><EFBFBD>ַ<EFBFBD><D6B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܳ<EFBFBD><DCB3><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD>Լ<EFBFBD><D4BC><EFBFBD> Util::String <20><>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD>Ŀ<EFBFBD><C4BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ơ<EFBFBD>
|
||
Util::String Utility_MonoStringToCppString( MonoString* pMonoStr )
|
||
{
|
||
char* pStr = mono_string_to_utf8( pMonoStr );
|
||
Util::String cppString( pStr );
|
||
mono_free( pStr );
|
||
|
||
return cppString;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
/// convert a string to a MonoString
|
||
MonoString* Utility_CppStringToMonoString( const char* pStr )
|
||
{
|
||
MonoString* monoString = mono_string_new_wrapper( pStr );
|
||
n_assert( NULL!=monoString );
|
||
return monoString;
|
||
}
|
||
|
||
MonoString* Utility_CppStringToMonoStringSafe( const char* pStr )
|
||
{
|
||
MonoString* mono= Utility_CppStringToMonoString( pStr );
|
||
if (mono != NULL)
|
||
{
|
||
return mono;
|
||
}
|
||
else
|
||
{
|
||
mono = Utility_CppStringToMonoString("");
|
||
return mono;
|
||
}
|
||
}
|
||
//------------------------------------------------------------------------
|
||
Util::Guid Utility_MonoGuidToUtilGuid(MonoArray* guid_array)
|
||
{
|
||
n_assert(mono_array_length(guid_array) == sizeof(Util::Guid));
|
||
unsigned char* ptr = GetMonoArrayBegin<unsigned char>(guid_array);
|
||
return Util::Guid::FromBinary(ptr, sizeof(Util::Guid));
|
||
}
|
||
//------------------------------------------------------------------------
|
||
MonoArray* Utility_UtilGuidToMonoByteArray(const Util::Guid& guid )
|
||
{
|
||
Util::Array<ubyte> byteArr;
|
||
const ubyte* buffer;
|
||
guid.AsBinary(buffer);
|
||
int length = sizeof(Util::Guid);
|
||
|
||
for (int ii=0;ii<length;ii++)
|
||
{
|
||
byteArr.Append(buffer[ii]);
|
||
}
|
||
return Utility_CppByteArrToMonoByteArr(byteArr);
|
||
}
|
||
//------------------------------------------------------------------------
|
||
const Core::Rtti* Utility_GetComRttiByName( const Util::String& sName )
|
||
{
|
||
// - SunHao TODO:string compare is a bit expense,do we have better way to do this? 2012/04/23
|
||
if ( sName=="Render" ||
|
||
sName=="RenderComponent" )
|
||
{
|
||
return &( RenderComponent::RTTI );
|
||
}
|
||
else if ( sName=="MeshRender" ||
|
||
sName=="MeshRenderComponent" )
|
||
{
|
||
return &( MeshRenderComponent::RTTI );
|
||
}
|
||
else if ( sName=="SkinnedMeshRender" ||
|
||
sName=="SkinnedMeshRenderComponent" )
|
||
{
|
||
return &( SkinnedMeshRenderComponent::RTTI );
|
||
}
|
||
else if ( sName=="ProjectorRender" ||
|
||
sName=="ProjectorRenderComponent")
|
||
{
|
||
return &( ProjectorRenderComponent::RTTI);
|
||
}
|
||
else if ( sName=="Skeleton" ||
|
||
sName=="SkeletonComponent" )
|
||
{
|
||
return &( SkeletonComponent::RTTI );
|
||
}
|
||
else if ( sName=="ParticleRender" ||
|
||
sName=="ParticleRenderComponent" )
|
||
{
|
||
return &( ParticleRenderComponent::RTTI );
|
||
}
|
||
else if ( sName=="SpriteRender" ||
|
||
sName=="SpriteRenderComponent" )
|
||
{
|
||
return &( SpriteRenderComponent::RTTI );
|
||
}
|
||
else if ( sName=="Animation" ||
|
||
sName=="AnimationComponent" )
|
||
{
|
||
return &( AnimationComponent::RTTI );
|
||
}
|
||
else if ( sName=="Light" ||
|
||
sName=="LightComponent" )
|
||
{
|
||
return &( LightComponent::RTTI );
|
||
}
|
||
else if ( sName=="Script" ||
|
||
sName=="ScriptComponent")
|
||
{
|
||
return &( ScriptComponent::RTTI );
|
||
}
|
||
else if ( sName=="Camera" ||
|
||
sName=="CameraComponent")
|
||
{
|
||
return &( CameraComponent::RTTI );
|
||
}
|
||
#if __USE_AUDIO__ || __GENESIS_EDITOR__
|
||
else if ( sName=="SoundSource" ||
|
||
sName=="SoundSourceComponent")
|
||
{
|
||
return &( SoundSource::RTTI );
|
||
}
|
||
else if ( sName=="SoundEchoFilter" ||
|
||
sName=="SoundEchoFilterComponent")
|
||
{
|
||
return &( SoundEchoFilterComponent::RTTI );
|
||
}
|
||
else if ( sName=="SoundReverbFilter" ||
|
||
sName=="SoundReverbFilterComponent")
|
||
{
|
||
return &( SoundReverbFilterComponent::RTTI );
|
||
}
|
||
else if ( sName=="SoundLowPassFilter" ||
|
||
sName=="SoundLowPassFilterComponent")
|
||
{
|
||
return &( SoundLowPassFilterComponent::RTTI );
|
||
}
|
||
else if ( sName=="SoundListener" ||
|
||
sName=="SoundListenerComponent")
|
||
{
|
||
return &( SoundListener::RTTI );
|
||
}
|
||
#endif // __USE_AUDIO__ || __GENESIS_EDITOR__
|
||
#if __USE_PHYSX__ || __GENESIS_EDITOR__
|
||
else if ( sName=="PhysicsBody" ||
|
||
sName=="PhysicsBodyComponent")
|
||
{
|
||
return &( PhysicsBodyComponent::RTTI );
|
||
}
|
||
#endif
|
||
else
|
||
{
|
||
n_printf( "Error component type happen! Passing error component's name when getting component." );
|
||
return NULL;
|
||
}
|
||
}
|
||
//------------------------------------------------------------------------
|
||
Component* AddComponentByName( Actor* pActor, const Util::String& sName )
|
||
{
|
||
// - find the component's RTTI
|
||
const Core::Rtti* pRtti = Utility_GetComRttiByName( sName );
|
||
if ( NULL==pRtti )
|
||
{
|
||
return NULL;
|
||
}
|
||
|
||
// - to see if this component is already exist
|
||
const TComponentPtr& pCurrCom = pActor->FindComponentExactly( *pRtti );
|
||
if ( NULL!=pCurrCom )
|
||
{
|
||
return pCurrCom.get();
|
||
}
|
||
|
||
Core::RefCounted* pObj = Core::Factory::Instance()->Create( pRtti->GetFourCC() );
|
||
n_assert( NULL!=pObj );
|
||
GPtr<Component> pCom = static_cast<Component*>( pObj );
|
||
|
||
pActor->AttachComponent( pCom );
|
||
return pCom.get();
|
||
}
|
||
//------------------------------------------------------------------------
|
||
Component* GetComponentByName( Actor* pActor, const Util::String& sName )
|
||
{
|
||
const Core::Rtti* pRtti = Utility_GetComRttiByName( sName );
|
||
if ( NULL==pRtti )
|
||
{
|
||
return NULL;
|
||
}
|
||
|
||
GPtr<Component> pCom = pActor->FindComponentExactly( *pRtti );
|
||
if ( NULL==pCom )
|
||
{
|
||
pCom = pActor->FindComponent(*pRtti);
|
||
|
||
if(NULL==pCom)
|
||
{
|
||
return NULL;
|
||
}
|
||
}
|
||
|
||
return pCom.get();
|
||
}
|
||
//------------------------------------------------------------------------
|
||
MonoArray* Utility_CppStrArrToMonoStrArr( const Util::TStringArray& cppStrArr )
|
||
{
|
||
if ( cppStrArr.IsEmpty() )
|
||
{
|
||
return NULL;
|
||
}
|
||
|
||
MonoArray* pMonoArr = NULL;
|
||
MonoString* pMonoString = NULL;
|
||
MonoClass* pMonoClass = mono_get_string_class();
|
||
MonoDomain* pDomain = mono_domain_get();
|
||
size_t size = cppStrArr.Size();
|
||
|
||
// - create a byte array
|
||
pMonoArr = mono_array_new( pDomain, pMonoClass, size );
|
||
if ( NULL==pMonoArr )
|
||
{
|
||
return NULL;
|
||
}
|
||
|
||
// - convert string into mono string and add them to a mono string array
|
||
for ( uint32 ii=0; ii<size; ii++ )
|
||
{
|
||
pMonoString = Utility_NewMonoString ( cppStrArr[ii] );
|
||
mono_array_set ( pMonoArr, MonoString*, ii, pMonoString );
|
||
}
|
||
|
||
return pMonoArr;
|
||
}
|
||
//-----------------------------------------------------------------------
|
||
MonoArray* Utility_CppByteArrToMonoByteArr( const Util::Array<ubyte>& cppByteArr )
|
||
{
|
||
if ( cppByteArr.IsEmpty() )
|
||
{
|
||
return NULL;
|
||
}
|
||
|
||
MonoArray* pMonoArr = NULL;
|
||
MonoClass* pMonoClass = mono_get_byte_class();
|
||
MonoDomain* pDomain = mono_domain_get();
|
||
size_t size = cppByteArr.Size();
|
||
|
||
// - create a ubyte array
|
||
pMonoArr = mono_array_new( pDomain, pMonoClass, size );
|
||
if ( NULL==pMonoArr )
|
||
{
|
||
return NULL;
|
||
}
|
||
// - convert string into mono string and add them to a mono byte array
|
||
for ( uint32 ii=0; ii<size; ii++ )
|
||
{
|
||
mono_array_set ( pMonoArr, ubyte, ii, cppByteArr[ii] );
|
||
}
|
||
|
||
return pMonoArr;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
MonoArray* Utility_CppByteArrToMonoByteArr( const char* cppByteArr,unsigned int size )
|
||
{
|
||
if ( NULL == cppByteArr )
|
||
{
|
||
return NULL;
|
||
}
|
||
|
||
MonoArray* pMonoArr = NULL;
|
||
MonoClass* pMonoClass = mono_get_byte_class();
|
||
MonoDomain* pDomain = mono_domain_get();
|
||
|
||
// - create a ubyte array
|
||
pMonoArr = mono_array_new( pDomain, pMonoClass, size );
|
||
if ( NULL==pMonoArr )
|
||
{
|
||
return NULL;
|
||
}
|
||
// - convert string into mono string and add them to a mono byte array
|
||
unsigned int intsize = size/4;
|
||
unsigned int bytesize = size%4;
|
||
|
||
const int* intarr =(const int*) cppByteArr;
|
||
for ( uint32 ii=0; ii<intsize; ii++ )
|
||
{
|
||
mono_array_set ( pMonoArr, int, ii, intarr[ii] );
|
||
}
|
||
for ( uint32 ii=intsize*4; ii<intsize*4+bytesize; ii++ )
|
||
{
|
||
mono_array_set ( pMonoArr, char, ii, cppByteArr[ii] );
|
||
}
|
||
return pMonoArr;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
bool Utility_MonoStrArrToCppStrArr( MonoArray* pMonoStrArr, Util::TStringArray& cppStrArr )
|
||
{
|
||
if ( NULL==pMonoStrArr )
|
||
{
|
||
return false;
|
||
}
|
||
|
||
MonoString* pStr = NULL;
|
||
size_t size = mono_array_length( pMonoStrArr );
|
||
|
||
for ( uint32 ii=0; ii<size; ii++ )
|
||
{
|
||
pStr = mono_array_get( pMonoStrArr, MonoString*, ii );
|
||
Util::String str = Utility_MonoStringToCppString( pStr );
|
||
cppStrArr.Append( str );
|
||
}
|
||
|
||
return true;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
Util::String Utility_GetFieldStringValue( MonoObject* pMonoObj, MonoClassField* pClassField )
|
||
{
|
||
if ( NULL==pClassField ||
|
||
NULL==pMonoObj )
|
||
{
|
||
static Util::String s_sEmpty;
|
||
return s_sEmpty;
|
||
}
|
||
|
||
MonoString *strval = NULL;
|
||
mono_field_get_value( pMonoObj, pClassField, &strval );
|
||
|
||
return Utility_MonoStringToCppString( strval );
|
||
}
|
||
//------------------------------------------------------------------------
|
||
Util::TStringArray Utility_GetAllEditableFieldNames( TScriptInstancePtr& pInstance )
|
||
{
|
||
TMonoClassFieldMap* pFields = Utility_GetFields( pInstance );
|
||
n_assert( NULL!=pFields );
|
||
int size = pFields->Size();
|
||
|
||
Util::TStringArray arr( size, 0 );
|
||
for ( int ii=0; ii<size; ii++ )
|
||
{
|
||
arr.Append( pFields->KeyAtIndex(ii) );
|
||
}
|
||
|
||
return arr;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
int Utility_GetEditableFieldCount( TScriptInstancePtr& pInstance )
|
||
{
|
||
TMonoClassFieldMap* pFields = Utility_GetFields( pInstance );
|
||
n_assert( NULL!=pFields );
|
||
return pFields->Size();
|
||
}
|
||
//------------------------------------------------------------------------
|
||
MonoClassField* Utility_GetEditableField( TScriptInstancePtr& pInstance, const Util::String& sName )
|
||
{
|
||
if ( (NULL==pInstance) ||
|
||
!(pInstance.isvalid()) )
|
||
{
|
||
return NULL;
|
||
}
|
||
|
||
TMonoClassFieldMap* pFields = Utility_GetFields( pInstance );
|
||
IndexT idx = pFields->FindIndex( sName );
|
||
if ( InvalidIndex==idx )
|
||
{
|
||
return NULL;
|
||
}
|
||
|
||
return pFields->ValueAtIndex( idx );
|
||
}
|
||
//------------------------------------------------------------------------
|
||
MonoClassField* Utility_GetEditableField( TScriptInstancePtr& pInstance, IndexT iIdx )
|
||
{
|
||
if ( (NULL==pInstance) ||
|
||
!(pInstance.isvalid()) )
|
||
{
|
||
return NULL;
|
||
}
|
||
|
||
TMonoClassFieldMap* pFields = Utility_GetFields( pInstance );
|
||
if ( iIdx<0 ||
|
||
(iIdx>pFields->Size()) )
|
||
{
|
||
return NULL;
|
||
}
|
||
|
||
return pFields->ValueAtIndex( iIdx );
|
||
}
|
||
//------------------------------------------------------------------------
|
||
TMonoClassFieldMap* Utility_GetFields( TScriptInstancePtr& pInstance )
|
||
{
|
||
MonoScript* pMonoScript = pInstance->GetMonoScript();
|
||
n_assert( NULL!=pMonoScript );
|
||
TMonoClassFieldMap* pFields = pMonoScript->GetFileds();
|
||
n_assert( NULL!=pFields );
|
||
|
||
return pFields;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
int Utility_GetFieldType( MonoClassField* pClassField )
|
||
{
|
||
// - if null pointer, return a invalid type
|
||
if ( NULL==pClassField )
|
||
{
|
||
n_assert( false && "Utility_GetFieldType, null pointer!" );
|
||
return c_iInvalidMonoType;
|
||
}
|
||
|
||
MonoType* pFieldMonoType = mono_field_get_type( pClassField );
|
||
int iFieldType = mono_type_get_type( pFieldMonoType );
|
||
|
||
return iFieldType;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
bool Utility_SetFieldValue( TScriptInstancePtr& pInstance, const Util::String& sName, int iType, void* val )
|
||
{
|
||
if ( (NULL==val) ||
|
||
(NULL==pInstance) ||
|
||
!(pInstance.isvalid()) )
|
||
{
|
||
return false;
|
||
}
|
||
|
||
MonoObject* pMonoInstance = pInstance->GetMonoInstance();
|
||
|
||
// - check if it's a valid field
|
||
MonoClassField* pClassField = Utility_GetEditableField( pInstance, sName );
|
||
if ( NULL==pClassField )
|
||
{
|
||
return false;
|
||
}
|
||
|
||
// - check if the type is match
|
||
int iFieldType = Utility_GetFieldType( pClassField );
|
||
if ( iFieldType!=iType )
|
||
{
|
||
return false;
|
||
}
|
||
|
||
mono_field_set_value( pMonoInstance, pClassField, val );
|
||
|
||
return true;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
bool Utility_SetImagePathFieldValue( TScriptInstancePtr& pInstance, const Util::String& key, const Util::String& str, int iType)
|
||
{
|
||
MonoString* value = Utility_CppStringToMonoString(str.AsCharPtr());
|
||
|
||
if ( (NULL == value) || (NULL==pInstance) || !(pInstance.isvalid()) )
|
||
return false;
|
||
|
||
MonoObject* pMonoObj = pInstance->GetMonoInstance();
|
||
MonoClassField* pClassField = Utility_GetEditableField( pInstance, key);
|
||
if ( NULL == pClassField )
|
||
return false;
|
||
|
||
// - check if the type is match, for the reason that user may change their script when editor offline
|
||
int iFieldType = Utility_GetFieldType( pClassField );
|
||
if ( iFieldType != iType )
|
||
return false;
|
||
|
||
MonoObject* pMemMonoObj = Utility_GetFieldBuiltInTypeValue<MonoObject*>( pMonoObj, pClassField );
|
||
if ( pMemMonoObj == NULL )
|
||
return false;
|
||
|
||
MonoScript* pMonoScript = ScriptGeneralManager::Instance()->GetMonoScript( "ImagePath", "ScriptRuntime", "ScriptRuntimeLibrary.dll", true);
|
||
TMonoClassFieldMap* maps = pMonoScript->GetFileds();
|
||
for ( int i = 0; i < maps->Size(); ++i)
|
||
{
|
||
MonoClassField* pMemClassField = maps->ValueAtIndex(i);
|
||
mono_field_set_value( pMemMonoObj, pMemClassField, value);
|
||
}
|
||
return true;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
Util::String Utility_GetFieldImagePathValue( MonoObject* pMonoObj, MonoClassField* pField )
|
||
{
|
||
MonoObject* pMemMonoObj = Utility_GetFieldBuiltInTypeValue<MonoObject*>( pMonoObj, pField);
|
||
if ( pMemMonoObj == NULL || pField == NULL )
|
||
return "";
|
||
|
||
MonoScript* pMonoScript = ScriptGeneralManager::Instance()->GetMonoScript( "ImagePath", "ScriptRuntime", "ScriptRuntimeLibrary.dll", true);
|
||
TMonoClassFieldMap* maps = pMonoScript->GetFileds();
|
||
Util::String value;
|
||
for ( int i = 0; i < maps->Size(); ++i)
|
||
{
|
||
MonoClassField* pMemClassField = maps->ValueAtIndex(i);
|
||
value = Utility_GetFieldStringValue( pMemMonoObj, pMemClassField);
|
||
}
|
||
return value;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
bool Utility_SetAssetPathFieldValue( TScriptInstancePtr& pInstance, const Util::String& key, const Util::AssetPath& assetPath, int iType )
|
||
{
|
||
MonoString* valueStr = Utility_CppStringToMonoString(assetPath.path.AsCharPtr());
|
||
int32 type = assetPath.type;
|
||
|
||
if ( (NULL==pInstance) || !(pInstance.isvalid()) )
|
||
return false;
|
||
|
||
MonoObject* pMonoObj = pInstance->GetMonoInstance();
|
||
MonoClassField* pClassField = Utility_GetEditableField( pInstance, key);
|
||
if ( NULL == pClassField )
|
||
return false;
|
||
|
||
// - check if the type is match, for the reason that user may change their script when editor offline
|
||
int iFieldType = Utility_GetFieldType( pClassField );
|
||
if ( iFieldType != iType )
|
||
return false;
|
||
|
||
MonoObject* pMemMonoObj = Utility_GetFieldBuiltInTypeValue<MonoObject*>( pMonoObj, pClassField );
|
||
if ( pMemMonoObj == NULL )
|
||
return false;
|
||
|
||
MonoScript* pMonoScript = ScriptGeneralManager::Instance()->GetMonoScript( "AssetPath", "ScriptRuntime", "ScriptRuntimeLibrary.dll", true);
|
||
TMonoClassFieldMap* maps = pMonoScript->GetFileds();
|
||
for ( int i = 0; i < maps->Size(); ++i)
|
||
{
|
||
MonoClassField* pMemClassField = maps->ValueAtIndex(i);
|
||
int memType = Utility_GetFieldType( pMemClassField);
|
||
if ( memType == (int)MONO_TYPE_STRING )
|
||
mono_field_set_value( pMemMonoObj, pMemClassField, valueStr);
|
||
else if( memType == (int)MONO_TYPE_I4 )
|
||
continue;
|
||
}
|
||
|
||
return true;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
Util::AssetPath Utility_GetFieldAssetPathValue( MonoObject* pMonoObj, MonoClassField* pField )
|
||
{
|
||
Util::AssetPath assetPath;
|
||
MonoObject* pMemMonoObj = Utility_GetFieldBuiltInTypeValue<MonoObject*>( pMonoObj, pField);
|
||
if ( pMemMonoObj == NULL || pField == NULL )
|
||
return assetPath;
|
||
|
||
MonoScript* pMonoScript = ScriptGeneralManager::Instance()->GetMonoScript( "AssetPath", "ScriptRuntime", "ScriptRuntimeLibrary.dll", true);
|
||
TMonoClassFieldMap* maps = pMonoScript->GetFileds();
|
||
Util::String value;
|
||
for ( int i = 0; i < maps->Size(); ++i)
|
||
{
|
||
MonoClassField* pMemClassField = maps->ValueAtIndex(i);
|
||
int memType = Utility_GetFieldType( pMemClassField);
|
||
if ( memType == (int)MONO_TYPE_STRING )
|
||
{
|
||
Util::String str = Utility_GetFieldStringValue( pMemMonoObj, pMemClassField);
|
||
assetPath.path = str;
|
||
}
|
||
else if( memType == (int)MONO_TYPE_I4 )
|
||
{
|
||
int32 type = Utility_GetFieldBuiltInTypeValue<int32>( pMemMonoObj, pMemClassField);
|
||
assetPath.type = type;
|
||
}
|
||
}
|
||
return assetPath;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
bool Utility_SetFieldValue( GPtr<ScriptComponent>& com , int index, const Util::String& sName, int iType, void* val )
|
||
{
|
||
GPtr<App::ScriptInstance> pScriptInstance = com->GetScriptInstance( index );
|
||
EditableFeilValue& feildValue = com->GetEditableFeildValue();
|
||
|
||
// string type need special pricess;
|
||
if ( iType==MONO_TYPE_STRING )
|
||
{
|
||
MonoString* monostring = Utility_CppStringToMonoString( static_cast<Util::String*>(val)->AsCharPtr() );
|
||
if ( !App::Utility_SetFieldValue( pScriptInstance, sName, iType, monostring ) )
|
||
{
|
||
return false;
|
||
}
|
||
feildValue.SetString(index,sName,*static_cast<Util::String*>(val));
|
||
return true;
|
||
}
|
||
|
||
//other types;
|
||
switch(iType)
|
||
{
|
||
case MONO_TYPE_I4:
|
||
{
|
||
App::Utility_SetFieldValue( pScriptInstance, sName, iType, val);
|
||
feildValue.SetInt( index, sName, *static_cast<int*>(val) );
|
||
break;
|
||
}
|
||
case MONO_TYPE_R4:
|
||
{
|
||
App::Utility_SetFieldValue( pScriptInstance, sName, iType, val);
|
||
feildValue.SetFloat( index, sName, *static_cast<float*>(val) );
|
||
break;
|
||
}
|
||
case MONO_TYPE_VALUETYPE:
|
||
{
|
||
MonoClassField* pClassField = Utility_GetEditableField( pScriptInstance, sName );
|
||
Util::String className = Utility_GetTypeClassName( pClassField );
|
||
if( className==s_csFloat2ClassName )
|
||
{
|
||
App::Utility_SetFieldValue( pScriptInstance, sName, iType, val);
|
||
feildValue.SetFloat2( index, sName, *static_cast<Math::float2*>(val) );
|
||
}
|
||
else if( className==s_csFloat3ClassName )
|
||
{
|
||
App::Utility_SetFieldValue( pScriptInstance, sName, iType, val);
|
||
feildValue.SetFloat3( index, sName, *static_cast<Math::float3*>(val) );
|
||
}
|
||
else if ( className==s_csFloat4ClassName )
|
||
{
|
||
App::Utility_SetFieldValue( pScriptInstance, sName, iType, val);
|
||
feildValue.SetFloat4( index, sName, *static_cast<Math::float4*>(val));
|
||
}
|
||
else if( className == s_csColor32ClassName )
|
||
{
|
||
App::Utility_SetFieldValue( pScriptInstance, sName, iType, val);
|
||
feildValue.SetColor32( index, sName, *static_cast<Math::Color32*>(val));
|
||
}
|
||
break;
|
||
}
|
||
case MONO_TYPE_CLASS:
|
||
{
|
||
MonoClassField* pClassField = Utility_GetEditableField( pScriptInstance, sName );
|
||
Util::String className = Utility_GetTypeClassName( pClassField );
|
||
if( className == s_csImagePathClassName )
|
||
{
|
||
Util::String* str = static_cast<Util::String*>(val);
|
||
App::Utility_SetImagePathFieldValue( pScriptInstance, sName, *str, iType);
|
||
feildValue.SetImagePath( index, sName, *str);
|
||
}
|
||
else if ( className == s_csAssetPathClassName )
|
||
{
|
||
Util::AssetPath* assetPath = static_cast<Util::AssetPath*>(val);
|
||
App::Utility_SetAssetPathFieldValue( pScriptInstance, sName, *assetPath, iType);
|
||
feildValue.SetAssetPath( index, sName, *assetPath);
|
||
}
|
||
break;
|
||
}
|
||
return true;
|
||
} // switch(iType) end
|
||
return false;
|
||
}
|
||
//------------------------------------------------------------------------
|
||
bool Utility_SetFieldValue( GPtr<ScriptComponent>& com , const Util::String& sInstanceName, const Util::String& sName, int iType, void* val)
|
||
{
|
||
int idx = com->GetClassNames().FindIndex( sInstanceName );
|
||
return Utility_SetFieldValue( com, idx, sName, iType, val );
|
||
}
|
||
//------------------------------------------------------------------------
|
||
MonoDomain* Utility_CreateChildDomain()
|
||
{
|
||
MonoDomain* newDomain = mono_domain_create_appdomain("Genesis Child Domain", NULL);
|
||
n_assert( newDomain!=NULL );
|
||
MonoDomain* old_domain = mono_domain_get();
|
||
n_assert( old_domain!=NULL );
|
||
MonoDomain* rootDomaain = mono_get_root_domain();
|
||
n_assert( rootDomaain!=NULL );
|
||
if(rootDomaain != old_domain)
|
||
{
|
||
n_error("already have a child domain\n");
|
||
}
|
||
return newDomain;
|
||
|
||
}
|
||
void Utility_SetChildDomain(MonoDomain* newDomain)
|
||
{
|
||
if (newDomain)
|
||
{
|
||
if (!mono_domain_set (newDomain, false))
|
||
{
|
||
n_error("Utility_SetChildDomain: mono_domain_set failed\n");
|
||
return;
|
||
}
|
||
|
||
if(mono_domain_get() == mono_get_root_domain())
|
||
{
|
||
n_error("Utility_SetChildDomain: root domain\n");
|
||
}
|
||
|
||
return;
|
||
}
|
||
|
||
n_error("Utility_SetChildDomain: newDomain is null\n");
|
||
}
|
||
//----------------------------------------------------------------------
|
||
const char* Utility_GetTypeClassName(MonoType *type)
|
||
{
|
||
MonoClass* pClass = mono_type_get_class(type);
|
||
|
||
return mono_class_get_name(pClass);
|
||
}
|
||
|
||
//-----------------------------------------------------------------------
|
||
const char* Utility_GetTypeClassName(MonoClassField *pClassField)
|
||
{
|
||
MonoType* pFieldMonoType = mono_field_get_type( pClassField );
|
||
|
||
return Utility_GetTypeClassName(pFieldMonoType);
|
||
}
|
||
|
||
void Utility_UnloadChildDomain()
|
||
{
|
||
MonoDomain* domain = mono_domain_get();
|
||
if (domain)
|
||
{
|
||
MonoDomain* rootDomain = mono_get_root_domain();
|
||
if (domain != rootDomain)
|
||
{
|
||
//-we can't unload the domain that is running now,so we set the root domain as active domain
|
||
mono_domain_set(rootDomain, false);
|
||
mono_domain_unload(domain);
|
||
}
|
||
}
|
||
mono_gc_collect(mono_gc_max_generation());
|
||
}
|
||
|
||
//--------------------------------------------------------------------------
|
||
void Utility_ScriptRootLoad()
|
||
{
|
||
ScriptRootInstance::Instance()->OnLoad();
|
||
}
|
||
//--------------------------------------------------------------------------
|
||
void Utility_ScriptRootTick()
|
||
{
|
||
ScriptRootInstance::Instance()->OnTick();
|
||
}
|
||
//--------------------------------------------------------------------------
|
||
void Utility_ScriptRootStop()
|
||
{
|
||
if(ScriptRootInstance::HasInstance())
|
||
{
|
||
ScriptRootInstance::Instance()->OnStopped();
|
||
}
|
||
}
|
||
//--------------------------------------------------------------------------
|
||
void Utility_ScriptRootResume()
|
||
{
|
||
if(ScriptRootInstance::HasInstance())
|
||
{
|
||
ScriptRootInstance::Instance()->OnResumed();
|
||
}
|
||
}
|
||
//--------------------------------------------------------------------------
|
||
void Utility_ScriptRootExit()
|
||
{
|
||
if(ScriptRootInstance::HasInstance())
|
||
{
|
||
ScriptRootInstance::Instance()->OnExit();
|
||
}
|
||
}
|
||
//--------------------------------------------------------------------------
|
||
|
||
Util::String Utility_ExceptionToString( MonoObject* ecx )
|
||
{
|
||
MonoMethodDesc* pDesc = NULL;
|
||
MonoMethod* pMethod = NULL;
|
||
MonoClass* pExcClass = NULL;
|
||
|
||
ScriptGeneralManager* manager = ScriptGeneralManager::Instance();
|
||
n_assert(manager);
|
||
MonoString* monoStringMessage = NULL;
|
||
|
||
pExcClass = manager->GetMonoClassByName( s_csExceptionConverterName, s_csScriptRuntimeNamespace, s_cpScriptRuntimeLibraryName );
|
||
n_assert(pExcClass);
|
||
|
||
pDesc = mono_method_desc_new( s_csExceptionToStringMethodSig.AsCharPtr(), false );
|
||
n_assert(pDesc);
|
||
pMethod = mono_method_desc_search_in_class( pDesc, pExcClass );
|
||
n_assert(pMethod);
|
||
mono_method_desc_free(pDesc);
|
||
|
||
void* args[] = { ecx, &monoStringMessage };
|
||
|
||
MonoObject* tempException = NULL;
|
||
mono_runtime_invoke( pMethod, NULL, args, &tempException );
|
||
if( tempException )
|
||
{
|
||
const char* exceptionClassName = mono_class_get_name(mono_object_get_class( tempException ) );
|
||
|
||
Util::String errorString;
|
||
errorString.Append("This exception string can't output because there is another exception of class '");
|
||
errorString.Append( exceptionClassName );
|
||
errorString.Append("' is thrown in the process\n");
|
||
|
||
n_error( errorString.AsCharPtr() );
|
||
return NULL;
|
||
}
|
||
return Utility_MonoStringToCppString(monoStringMessage);
|
||
}
|
||
//--------------------------------------------------------------------------
|
||
|
||
MonoObject* Utility_MonoRuntimeInvoke( MonoMethod* method, void* obj, void** params )
|
||
{
|
||
MonoObject* ret = NULL;
|
||
if (gEnableMonoDebugger)
|
||
{
|
||
ret = mono_runtime_invoke( method, obj, params , NULL );
|
||
}
|
||
else
|
||
{
|
||
|
||
MonoObject* exc = NULL;
|
||
ret = mono_runtime_invoke( method, obj, params , &exc );
|
||
if ( exc!=NULL )
|
||
{
|
||
Util::String error("User Defined Script Error!\nPlease check your C# script with monodevelop to debug.\nHere is the exception:\n");
|
||
error += Utility_ExceptionToString( exc );
|
||
|
||
#if __WIN32__&&!__GENESIS_EDITOR__
|
||
Core::SysFunc::Error(error.AsCharPtr());
|
||
#else
|
||
n_warning( error.AsCharPtr() );
|
||
#endif
|
||
}
|
||
}
|
||
return ret;
|
||
}
|
||
//--------------------------------------------------------------------------
|
||
|
||
GPtr<ScriptInstance> Utility_CreateScriptInstance( const Util::String& className,const Util::String& nameSpaceName,const Util::String& assemblyName )
|
||
{
|
||
|
||
TMonoScriptPtr pMonoScript = ScriptGeneralManager::Instance()->GetMonoScript( className,nameSpaceName,assemblyName );
|
||
|
||
if ( !(pMonoScript.isvalid()) ||
|
||
!(pMonoScript->IsValid()) )
|
||
{
|
||
#ifdef __GENESIS_EDITOR__
|
||
return NULL;
|
||
#endif
|
||
script_fatal_error( false && "Utility_CreateScriptInstance,Can't find monoScript!" );
|
||
}
|
||
|
||
TScriptInstancePtr _pScriptInstance;
|
||
_pScriptInstance = MonoScript::CreateInstance( pMonoScript );
|
||
return _pScriptInstance;
|
||
}
|
||
//--------------------------------------------------------------------------
|
||
|
||
#ifdef __GENESIS_EDITOR__
|
||
bool Utility_DetectDotNetDll(const char* pathName )
|
||
{
|
||
if( mono_image_open_from_data_full==NULL )
|
||
{
|
||
return false;
|
||
}
|
||
// - load the assemblies to memory
|
||
GPtr<IO::Stream> srcStream = IO::IoServer::Instance()->ReadFileFromDisk( pathName );
|
||
srcStream->SetAccessMode( IO::Stream::ReadAccess );
|
||
|
||
void* dllData = NULL;
|
||
int dataSize = 0;
|
||
|
||
if ( !srcStream->Open() )
|
||
{
|
||
n_warning("dll open failed,it may be locked by other process,or not existed\n");
|
||
return false;
|
||
}
|
||
dllData = srcStream->Map();
|
||
n_assert( dllData!=NULL );
|
||
dataSize = srcStream->GetSize();
|
||
|
||
int status = 0;
|
||
MonoImage* pImage = NULL;
|
||
pImage = mono_image_open_from_data_full ( dllData, dataSize, true, &status, false);
|
||
// - if this is not a dot net's dll,mono_image_open_from_data_full() function will return a null value
|
||
|
||
if (pImage == NULL)
|
||
{
|
||
return false;
|
||
}
|
||
else
|
||
{
|
||
// release the dll
|
||
mono_image_close(pImage);
|
||
return true;
|
||
}
|
||
srcStream->Close();
|
||
}
|
||
#endif
|
||
}
|
||
|