BsScriptFolderMonitor.cpp 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
  1. //********************************** Banshee Engine (www.banshee3d.com) **************************************************//
  2. //**************** Copyright (c) 2016 Marko Pintera ([email protected]). All rights reserved. **********************//
  3. #include "Wrappers/BsScriptFolderMonitor.h"
  4. #include "BsScriptMeta.h"
  5. #include "BsMonoField.h"
  6. #include "BsMonoClass.h"
  7. #include "BsMonoManager.h"
  8. #include "BsMonoMethod.h"
  9. #include "BsMonoUtil.h"
  10. using namespace std::placeholders;
  11. namespace bs
  12. {
  13. ScriptFolderMonitor::OnModifiedThunkDef ScriptFolderMonitor::OnModifiedThunk;
  14. ScriptFolderMonitor::OnModifiedThunkDef ScriptFolderMonitor::OnAddedThunk;
  15. ScriptFolderMonitor::OnModifiedThunkDef ScriptFolderMonitor::OnRemovedThunk;
  16. ScriptFolderMonitor::OnRenamedThunkDef ScriptFolderMonitor::OnRenamedThunk;
  17. ScriptFolderMonitor::ScriptFolderMonitor(MonoObject* instance, FolderMonitor* monitor)
  18. :ScriptObject(instance), mMonitor(monitor)
  19. {
  20. mGCHandle = MonoUtil::newWeakGCHandle(instance);
  21. if (mMonitor != nullptr)
  22. {
  23. ScriptFolderMonitorManager::instance()._registerMonitor(this);
  24. mMonitor->onAdded.connect(std::bind(&ScriptFolderMonitor::onMonitorFileAdded, this, _1));
  25. mMonitor->onRemoved.connect(std::bind(&ScriptFolderMonitor::onMonitorFileRemoved, this, _1));
  26. mMonitor->onModified.connect(std::bind(&ScriptFolderMonitor::onMonitorFileModified, this, _1));
  27. mMonitor->onRenamed.connect(std::bind(&ScriptFolderMonitor::onMonitorFileRenamed, this, _1, _2));
  28. }
  29. }
  30. ScriptFolderMonitor::~ScriptFolderMonitor()
  31. {
  32. destroy();
  33. }
  34. void ScriptFolderMonitor::initRuntimeData()
  35. {
  36. metaData.scriptClass->addInternalCall("Internal_CreateInstance", (void*)&ScriptFolderMonitor::internal_CreateInstance);
  37. metaData.scriptClass->addInternalCall("Internal_Destroy", (void*)&ScriptFolderMonitor::internal_Destroy);
  38. OnModifiedThunk = (OnModifiedThunkDef)metaData.scriptClass->getMethod("Internal_DoOnModified", 1)->getThunk();
  39. OnAddedThunk = (OnModifiedThunkDef)metaData.scriptClass->getMethod("Internal_DoOnAdded", 1)->getThunk();
  40. OnRemovedThunk = (OnModifiedThunkDef)metaData.scriptClass->getMethod("Internal_DoOnRemoved", 1)->getThunk();
  41. OnRenamedThunk = (OnRenamedThunkDef)metaData.scriptClass->getMethod("Internal_DoOnRenamed", 2)->getThunk();
  42. }
  43. void ScriptFolderMonitor::internal_CreateInstance(MonoObject* instance, MonoString* folder)
  44. {
  45. FolderMonitor* monitor = nullptr;
  46. if (folder != nullptr)
  47. {
  48. Path folderPath = MonoUtil::monoToString(folder);
  49. FolderChangeBits folderChanges;
  50. folderChanges |= FolderChangeBit::FileName;
  51. folderChanges |= FolderChangeBit::DirName;
  52. folderChanges |= FolderChangeBit::FileWrite;
  53. monitor = bs_new<FolderMonitor>();
  54. monitor->startMonitor(folderPath, true, folderChanges);
  55. }
  56. new (bs_alloc<ScriptFolderMonitor>()) ScriptFolderMonitor(instance, monitor);
  57. }
  58. void ScriptFolderMonitor::internal_Destroy(ScriptFolderMonitor* thisPtr)
  59. {
  60. thisPtr->destroy();
  61. }
  62. void ScriptFolderMonitor::onMonitorFileModified(const Path& path)
  63. {
  64. MonoObject* instance = MonoUtil::getObjectFromGCHandle(mGCHandle);
  65. MonoString* monoPath = MonoUtil::stringToMono(path.toString());
  66. MonoUtil::invokeThunk(OnModifiedThunk, instance, monoPath);
  67. }
  68. void ScriptFolderMonitor::onMonitorFileAdded(const Path& path)
  69. {
  70. MonoObject* instance = MonoUtil::getObjectFromGCHandle(mGCHandle);
  71. MonoString* monoPath = MonoUtil::stringToMono(path.toString());
  72. MonoUtil::invokeThunk(OnAddedThunk, instance, monoPath);
  73. }
  74. void ScriptFolderMonitor::onMonitorFileRemoved(const Path& path)
  75. {
  76. MonoObject* instance = MonoUtil::getObjectFromGCHandle(mGCHandle);
  77. MonoString* monoPath = MonoUtil::stringToMono(path.toString());
  78. MonoUtil::invokeThunk(OnRemovedThunk, instance, monoPath);
  79. }
  80. void ScriptFolderMonitor::onMonitorFileRenamed(const Path& from, const Path& to)
  81. {
  82. MonoObject* instance = MonoUtil::getObjectFromGCHandle(mGCHandle);
  83. MonoString* monoPathFrom = MonoUtil::stringToMono(from.toString());
  84. MonoString* monoPathTo = MonoUtil::stringToMono(to.toString());
  85. MonoUtil::invokeThunk(OnRenamedThunk, instance, monoPathFrom, monoPathTo);
  86. }
  87. void ScriptFolderMonitor::update()
  88. {
  89. mMonitor->_update();
  90. }
  91. void ScriptFolderMonitor::destroy()
  92. {
  93. if (mMonitor != nullptr)
  94. {
  95. mMonitor->stopMonitorAll();
  96. bs_delete(mMonitor);
  97. mMonitor = nullptr;
  98. ScriptFolderMonitorManager::instance()._unregisterMonitor(this);
  99. }
  100. mGCHandle = 0;
  101. }
  102. void ScriptFolderMonitorManager::update()
  103. {
  104. for (auto& monitor : mMonitors)
  105. monitor->update();
  106. }
  107. void ScriptFolderMonitorManager::_registerMonitor(ScriptFolderMonitor* monitor)
  108. {
  109. mMonitors.insert(monitor);
  110. }
  111. void ScriptFolderMonitorManager::_unregisterMonitor(ScriptFolderMonitor* monitor)
  112. {
  113. mMonitors.erase(monitor);
  114. }
  115. }