BsMonoManager.cpp 2.3 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798
  1. #include "BsMonoManager.h"
  2. #include "CmException.h"
  3. #include "BsScriptMeta.h"
  4. #include "BsMonoAssembly.h"
  5. #include "BsMonoClass.h"
  6. #include <mono/metadata/assembly.h>
  7. #include <mono/metadata/mono-config.h>
  8. using namespace CamelotFramework;
  9. namespace BansheeEngine
  10. {
  11. const String MonoManager::MONO_LIB_DIR = "..\\..\\Mono\\lib";
  12. const String MonoManager::MONO_ETC_DIR = "..\\..\\Mono\\etc";
  13. MonoManager::MonoManager()
  14. :mDomain(nullptr)
  15. {
  16. mono_set_dirs(MONO_LIB_DIR.c_str(), MONO_ETC_DIR.c_str());
  17. mono_config_parse(nullptr);
  18. }
  19. MonoManager::~MonoManager()
  20. {
  21. for(auto& entry : mAssemblies)
  22. {
  23. unloadAssembly(*entry.second);
  24. cm_delete(entry.second);
  25. }
  26. mAssemblies.clear();
  27. if(mDomain != nullptr)
  28. {
  29. mono_jit_cleanup(mDomain);
  30. mDomain = nullptr;
  31. }
  32. }
  33. MonoAssembly& MonoManager::loadAssembly(const String& path, const String& name, const String& entryPoint)
  34. {
  35. MonoAssembly* assembly = nullptr;
  36. if(mDomain == nullptr)
  37. {
  38. mDomain = mono_jit_init (path.c_str());
  39. if(mDomain == nullptr)
  40. {
  41. CM_EXCEPT(InternalErrorException, "Cannot initialize Mono runtime.");
  42. }
  43. }
  44. auto iterFind = mAssemblies.find(name);
  45. if(iterFind != mAssemblies.end())
  46. {
  47. assembly = iterFind->second;
  48. }
  49. else
  50. {
  51. assembly = new (cm_alloc<MonoAssembly>()) MonoAssembly();
  52. mAssemblies[name] = assembly;
  53. }
  54. if(!assembly->mIsLoaded)
  55. {
  56. assembly->load(path, name);
  57. // Fully initialize all types that use this assembly
  58. Vector<ScriptMeta*>::type& mTypeMetas = getTypesToInitialize()[name];
  59. for(auto& meta : mTypeMetas)
  60. {
  61. meta->scriptClass = &assembly->getClass(meta->ns, meta->name);
  62. meta->thisPtrField = &meta->scriptClass->getField("mCachedPtr");
  63. meta->initCallback();
  64. }
  65. assembly->initialize(entryPoint); // Perform any initialization after everything is loaded
  66. }
  67. return *assembly;
  68. }
  69. void MonoManager::unloadAssembly(MonoAssembly& assembly)
  70. {
  71. ::MonoAssembly* monoAssembly = assembly.mMonoAssembly;
  72. assembly.unload();
  73. if(monoAssembly)
  74. mono_assembly_close(monoAssembly);
  75. }
  76. void MonoManager::registerScriptType(ScriptMeta* metaData)
  77. {
  78. Vector<ScriptMeta*>::type& mMetas = getTypesToInitialize()[metaData->assembly];
  79. mMetas.push_back(metaData);
  80. }
  81. }