#include "BsScriptFolderMonitor.h" #include "BsScriptMeta.h" #include "BsMonoField.h" #include "BsMonoClass.h" #include "BsMonoManager.h" #include "BsMonoMethod.h" #include "BsMonoUtil.h" using namespace std::placeholders; namespace BansheeEngine { ScriptFolderMonitor::OnModifiedThunkDef ScriptFolderMonitor::OnModifiedThunk; ScriptFolderMonitor::OnModifiedThunkDef ScriptFolderMonitor::OnAddedThunk; ScriptFolderMonitor::OnModifiedThunkDef ScriptFolderMonitor::OnRemovedThunk; ScriptFolderMonitor::OnRenamedThunkDef ScriptFolderMonitor::OnRenamedThunk; ScriptFolderMonitor::ScriptFolderMonitor(MonoObject* instance, FolderMonitor* monitor) :ScriptObject(instance), mMonitor(monitor) { if (mMonitor != nullptr) { ScriptFolderMonitorManager::instance()._registerMonitor(this); mMonitor->onAdded.connect(std::bind(&ScriptFolderMonitor::onMonitorFileAdded, this, _1)); mMonitor->onRemoved.connect(std::bind(&ScriptFolderMonitor::onMonitorFileRemoved, this, _1)); mMonitor->onModified.connect(std::bind(&ScriptFolderMonitor::onMonitorFileModified, this, _1)); mMonitor->onRenamed.connect(std::bind(&ScriptFolderMonitor::onMonitorFileRenamed, this, _1, _2)); } } ScriptFolderMonitor::~ScriptFolderMonitor() { destroy(); } void ScriptFolderMonitor::initRuntimeData() { metaData.scriptClass->addInternalCall("Internal_CreateInstance", &ScriptFolderMonitor::internal_CreateInstance); metaData.scriptClass->addInternalCall("Internal_Destroy", &ScriptFolderMonitor::internal_Destroy); OnModifiedThunk = (OnModifiedThunkDef)metaData.scriptClass->getMethod("Internal_DoOnModified", 1)->getThunk(); OnAddedThunk = (OnModifiedThunkDef)metaData.scriptClass->getMethod("Internal_DoOnAdded", 1)->getThunk(); OnRemovedThunk = (OnModifiedThunkDef)metaData.scriptClass->getMethod("Internal_DoOnRemoved", 1)->getThunk(); OnRenamedThunk = (OnRenamedThunkDef)metaData.scriptClass->getMethod("Internal_DoOnRenamed", 2)->getThunk(); } void ScriptFolderMonitor::internal_CreateInstance(MonoObject* instance, MonoString* folder) { FolderMonitor* monitor = nullptr; if (folder != nullptr) { Path folderPath = MonoUtil::monoToWString(folder); FolderChange folderChanges = (FolderChange)((UINT32)FolderChange::FileName | (UINT32)FolderChange::DirName | (UINT32)FolderChange::Creation | (UINT32)FolderChange::LastWrite); monitor = bs_new(); monitor->startMonitor(folderPath, true, folderChanges); } new (bs_alloc()) ScriptFolderMonitor(instance, monitor); } void ScriptFolderMonitor::internal_Destroy(ScriptFolderMonitor* thisPtr) { thisPtr->destroy(); } void ScriptFolderMonitor::onMonitorFileModified(const Path& path) { MonoString* monoPath = MonoUtil::wstringToMono(MonoManager::instance().getDomain(), path.toWString()); MonoUtil::invokeThunk(OnModifiedThunk, getManagedInstance(), monoPath); } void ScriptFolderMonitor::onMonitorFileAdded(const Path& path) { MonoString* monoPath = MonoUtil::wstringToMono(MonoManager::instance().getDomain(), path.toWString()); MonoUtil::invokeThunk(OnAddedThunk, getManagedInstance(), monoPath); } void ScriptFolderMonitor::onMonitorFileRemoved(const Path& path) { MonoString* monoPath = MonoUtil::wstringToMono(MonoManager::instance().getDomain(), path.toWString()); MonoUtil::invokeThunk(OnRemovedThunk, getManagedInstance(), monoPath); } void ScriptFolderMonitor::onMonitorFileRenamed(const Path& from, const Path& to) { MonoString* monoPathFrom = MonoUtil::wstringToMono(MonoManager::instance().getDomain(), from.toWString()); MonoString* monoPathTo = MonoUtil::wstringToMono(MonoManager::instance().getDomain(), to.toWString()); MonoUtil::invokeThunk(OnRenamedThunk, getManagedInstance(), monoPathFrom, monoPathTo); } void ScriptFolderMonitor::update() { mMonitor->_update(); } void ScriptFolderMonitor::destroy() { if (mMonitor != nullptr) { mMonitor->stopMonitorAll(); bs_delete(mMonitor); mMonitor = nullptr; ScriptFolderMonitorManager::instance()._unregisterMonitor(this); } } void ScriptFolderMonitorManager::update() { for (auto& monitor : mMonitors) monitor->update(); } void ScriptFolderMonitorManager::_registerMonitor(ScriptFolderMonitor* monitor) { mMonitors.insert(monitor); } void ScriptFolderMonitorManager::_unregisterMonitor(ScriptFolderMonitor* monitor) { mMonitors.erase(monitor); } }