server/state: Fix module modification watching and use MultiFileWatch instead of FileWatch
This commit is contained in:
parent
15e9dbcc95
commit
cd5cb5acee
@ -216,9 +216,14 @@ struct CState: public State, public interface::Server
|
|||||||
// crash.
|
// crash.
|
||||||
interface::Mutex m_magic_mutex; // Lock for all of Urho3D
|
interface::Mutex m_magic_mutex; // Lock for all of Urho3D
|
||||||
|
|
||||||
sm_<ss_, ModuleContainer> m_modules;
|
sm_<ss_, interface::ModuleInfo> m_module_info; // Info of every seen module
|
||||||
|
sm_<ss_, ModuleContainer> m_modules; // Currently loaded modules
|
||||||
set_<ss_> m_unloads_requested;
|
set_<ss_> m_unloads_requested;
|
||||||
sm_<ss_, sp_<interface::FileWatch>> m_module_file_watches;
|
sm_<ss_, sp_<interface::MultiFileWatch>> m_module_file_watches;
|
||||||
|
// Module modifications are accumulated here and core:module_modified events
|
||||||
|
// are fired every event loop based on this to lump multiple modifications
|
||||||
|
// into one (generally a modification causes many notifications)
|
||||||
|
set_<ss_> m_modified_modules; // Module names
|
||||||
// TODO: Handle properly in reloads (unload by popping from top, then reload
|
// TODO: Handle properly in reloads (unload by popping from top, then reload
|
||||||
// everything until top)
|
// everything until top)
|
||||||
sv_<ss_> m_module_load_order;
|
sv_<ss_> m_module_load_order;
|
||||||
@ -356,6 +361,8 @@ struct CState: public State, public interface::Server
|
|||||||
|
|
||||||
log_i(MODULE, "Loading module %s from %s", cs(info.name), cs(info.path));
|
log_i(MODULE, "Loading module %s from %s", cs(info.name), cs(info.path));
|
||||||
|
|
||||||
|
m_module_info[info.name] = info;
|
||||||
|
|
||||||
ss_ build_dst = g_server_config.rccpp_build_path +
|
ss_ build_dst = g_server_config.rccpp_build_path +
|
||||||
"/"+info.name+"."+MODULE_EXTENSION;
|
"/"+info.name+"."+MODULE_EXTENSION;
|
||||||
ss_ init_cpp_path = info.path+"/"+info.name+".cpp";
|
ss_ init_cpp_path = info.path+"/"+info.name+".cpp";
|
||||||
@ -370,16 +377,18 @@ struct CState: public State, public interface::Server
|
|||||||
files_to_watch.insert(files_to_watch.end(), includes.begin(), includes.end());
|
files_to_watch.insert(files_to_watch.end(), includes.begin(), includes.end());
|
||||||
|
|
||||||
if(m_module_file_watches.count(info.name) == 0){
|
if(m_module_file_watches.count(info.name) == 0){
|
||||||
m_module_file_watches[info.name] = sp_<interface::FileWatch>(
|
sp_<interface::MultiFileWatch> w(interface::createMultiFileWatch());
|
||||||
interface::createFileWatch(files_to_watch,
|
for(const ss_ &watch_path : files_to_watch){
|
||||||
[this, info]()
|
ss_ dir_path = interface::Filesystem::strip_file_name(watch_path);
|
||||||
{
|
w->add(dir_path, [this, info, watch_path](const ss_ &modified_path){
|
||||||
|
if(modified_path != watch_path)
|
||||||
|
return;
|
||||||
log_i(MODULE, "Module modified: %s: %s",
|
log_i(MODULE, "Module modified: %s: %s",
|
||||||
cs(info.name), cs(info.path));
|
cs(info.name), cs(info.path));
|
||||||
emit_event(Event("core:module_modified",
|
m_modified_modules.insert(info.name);
|
||||||
new interface::ModuleModifiedEvent(info.name, info.path)));
|
});
|
||||||
handle_events();
|
}
|
||||||
}));
|
m_module_file_watches[info.name] = w;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Build
|
// Build
|
||||||
@ -526,14 +535,13 @@ struct CState: public State, public interface::Server
|
|||||||
interface::ModuleInfo info;
|
interface::ModuleInfo info;
|
||||||
{
|
{
|
||||||
interface::MutexScope ms(m_modules_mutex);
|
interface::MutexScope ms(m_modules_mutex);
|
||||||
auto it = m_modules.find(module_name);
|
auto it = m_module_info.find(module_name);
|
||||||
if(it == m_modules.end()){
|
if(it == m_module_info.end()){
|
||||||
log_w(MODULE, "reload_module: Module not found: %s",
|
log_w(MODULE, "reload_module: Module info not found: %s",
|
||||||
cs(module_name));
|
cs(module_name));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ModuleContainer *mc = &it->second;
|
info = it->second;
|
||||||
info = mc->info;
|
|
||||||
}
|
}
|
||||||
reload_module(info);
|
reload_module(info);
|
||||||
}
|
}
|
||||||
@ -711,6 +719,21 @@ struct CState: public State, public interface::Server
|
|||||||
|
|
||||||
void handle_events()
|
void handle_events()
|
||||||
{
|
{
|
||||||
|
// Get modified modules and push events to queue
|
||||||
|
{
|
||||||
|
interface::MutexScope ms(m_modules_mutex);
|
||||||
|
set_<ss_> modified_modules;
|
||||||
|
modified_modules.swap(m_modified_modules);
|
||||||
|
for(const ss_ &name : modified_modules){
|
||||||
|
auto it = m_module_info.find(name);
|
||||||
|
if(it == m_module_info.end())
|
||||||
|
throw Exception("Info of modified module not available");
|
||||||
|
interface::ModuleInfo &info = it->second;
|
||||||
|
emit_event(Event("core:module_modified",
|
||||||
|
new interface::ModuleModifiedEvent(
|
||||||
|
info.name, info.path)));
|
||||||
|
}
|
||||||
|
}
|
||||||
// Note: Locking m_modules_mutex here is not needed because no modules
|
// Note: Locking m_modules_mutex here is not needed because no modules
|
||||||
// can be deleted while this is running, because modules are deleted
|
// can be deleted while this is running, because modules are deleted
|
||||||
// only by this same thread.
|
// only by this same thread.
|
||||||
|
Loading…
x
Reference in New Issue
Block a user