BsMonoManager.cpp 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102
  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. if(meta->scriptClass->hasField("mCachedPtr"))
  63. meta->thisPtrField = &meta->scriptClass->getField("mCachedPtr");
  64. else
  65. meta->thisPtrField = nullptr;
  66. meta->initCallback();
  67. }
  68. assembly->initialize(entryPoint); // Perform any initialization after everything is loaded
  69. }
  70. return *assembly;
  71. }
  72. void MonoManager::unloadAssembly(MonoAssembly& assembly)
  73. {
  74. ::MonoAssembly* monoAssembly = assembly.mMonoAssembly;
  75. assembly.unload();
  76. if(monoAssembly)
  77. mono_assembly_close(monoAssembly);
  78. }
  79. void MonoManager::registerScriptType(ScriptMeta* metaData)
  80. {
  81. Vector<ScriptMeta*>::type& mMetas = getTypesToInitialize()[metaData->assembly];
  82. mMetas.push_back(metaData);
  83. }
  84. }