diff options
author | danieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7> | 2009-11-16 17:59:06 +0000 |
---|---|---|
committer | danieldg <danieldg@e03df62e-2008-0410-955e-edbf42e46eb7> | 2009-11-16 17:59:06 +0000 |
commit | 54fb0cd5aa7d090d5c3da5ab54988c86ba8a2e8e (patch) | |
tree | bc20ce6dca41b2d16349ae4c8212861c10e3685e /src/modules.cpp | |
parent | 3bfd0db65ff01c026e968af4de074cc1155a4061 (diff) |
Use ServiceProvider for inter-module dependencies
This will stop dependency chains from preventing module reloads when
it is not actually needed; however, it removes some failsafes that will
need to be reimplemented in order to avoid unmapped vtables.
This deprecates Request as an inter-module signaling mechanism, although
SQL still uses it.
git-svn-id: http://svn.inspircd.org/repository/trunk/inspircd@12140 e03df62e-2008-0410-955e-edbf42e46eb7
Diffstat (limited to 'src/modules.cpp')
-rw-r--r-- | src/modules.cpp | 199 |
1 files changed, 69 insertions, 130 deletions
diff --git a/src/modules.cpp b/src/modules.cpp index d86dc6270..f4751ad11 100644 --- a/src/modules.cpp +++ b/src/modules.cpp @@ -322,178 +322,117 @@ std::string& ModuleManager::LastError() return LastModuleError; } -bool ModuleManager::PublishFeature(const std::string &FeatureName, Module* Mod) -{ - if (Features.find(FeatureName) == Features.end()) - { - Features[FeatureName] = Mod; - return true; - } - return false; -} - -bool ModuleManager::UnpublishFeature(const std::string &FeatureName) +CmdResult InspIRCd::CallCommandHandler(const std::string &commandname, const std::vector<std::string>& parameters, User* user) { - featurelist::iterator iter = Features.find(FeatureName); - - if (iter == Features.end()) - return false; - - Features.erase(iter); - return true; + return this->Parser->CallHandler(commandname, parameters, user); } -Module* ModuleManager::FindFeature(const std::string &FeatureName) +bool InspIRCd::IsValidModuleCommand(const std::string &commandname, int pcnt, User* user) { - featurelist::iterator iter = Features.find(FeatureName); - - if (iter == Features.end()) - return NULL; - - return iter->second; + return this->Parser->IsValidCommand(commandname, pcnt, user); } -bool ModuleManager::PublishInterface(const std::string &InterfaceName, Module* Mod) +void InspIRCd::AddCommand(Command *f) { - interfacelist::iterator iter = Interfaces.find(InterfaceName); - - if (iter == Interfaces.end()) - { - modulelist ml; - ml.push_back(Mod); - Interfaces[InterfaceName] = std::make_pair(0, ml); - } - else + if (!this->Parser->AddCommand(f)) { - iter->second.second.push_back(Mod); + throw ModuleException("Command "+std::string(f->name)+" already exists."); } - return true; } -bool ModuleManager::UnpublishInterface(const std::string &InterfaceName, Module* Mod) +void ModuleManager::AddService(ServiceProvider& item) { - interfacelist::iterator iter = Interfaces.find(InterfaceName); - - if (iter == Interfaces.end()) - return false; - - for (modulelist::iterator x = iter->second.second.begin(); x != iter->second.second.end(); x++) + switch (item.service) { - if (*x == Mod) + case SERVICE_COMMAND: + if (!ServerInstance->Parser->AddCommand(static_cast<Command*>(&item))) + throw ModuleException("Command "+std::string(item.name)+" already exists."); + return; + case SERVICE_CMODE: + case SERVICE_UMODE: + if (!ServerInstance->Modes->AddMode(static_cast<ModeHandler*>(&item))) + throw ModuleException("Mode "+std::string(item.name)+" already exists."); + return; + case SERVICE_METADATA: + ServerInstance->Extensions.Register(static_cast<ExtensionItem*>(&item)); + return; + case SERVICE_DATA: + case SERVICE_IOHOOK: { - iter->second.second.erase(x); - if (iter->second.second.empty()) - Interfaces.erase(InterfaceName); - return true; + DataProviders.insert(std::make_pair(item.name, &item)); + std::string::size_type slash = item.name.find('/'); + if (slash != std::string::npos) + { + DataProviders.insert(std::make_pair(item.name.substr(0, slash), &item)); + DataProviders.insert(std::make_pair(item.name.substr(slash + 1), &item)); + } + return; } + default: + throw ModuleException("Cannot add unknown service type"); } - return false; } -modulelist* ModuleManager::FindInterface(const std::string &InterfaceName) +ServiceProvider* ModuleManager::FindService(ServiceType type, const std::string& name) { - interfacelist::iterator iter = Interfaces.find(InterfaceName); - if (iter == Interfaces.end()) - return NULL; - else - return &(iter->second.second); -} - -bool ModuleManager::ModuleHasInterface(Module* mod, const std::string& InterfaceName) -{ - interfacelist::iterator iter = Interfaces.find(InterfaceName); - if (iter == Interfaces.end()) - return false; - else + switch (type) { - modulelist& ml = iter->second.second; - modulelist::iterator mi = std::find(ml.begin(), ml.end(), mod); - return (mi != ml.end()); + case SERVICE_DATA: + case SERVICE_IOHOOK: + { + std::multimap<std::string, ServiceProvider*>::iterator i = DataProviders.find(name); + if (i != DataProviders.end() && i->second->service == type) + return i->second; + return NULL; + } + // TODO implement finding of the other types + default: + throw ModuleException("Cannot find unknown service type"); } } -void ModuleManager::UseInterface(const std::string &InterfaceName) -{ - interfacelist::iterator iter = Interfaces.find(InterfaceName); - if (iter != Interfaces.end()) - iter->second.first++; - -} - -void ModuleManager::DoneWithInterface(const std::string &InterfaceName) +dynamic_reference_base::dynamic_reference_base(Module* Creator, const std::string& Name) + : name(Name), value(NULL), creator(Creator) { - interfacelist::iterator iter = Interfaces.find(InterfaceName); - if (iter != Interfaces.end()) - iter->second.first--; + ServerInstance->Modules->ActiveDynrefs.push_back(this); } -std::pair<int,std::string> ModuleManager::GetInterfaceInstanceCount(Module* m) +dynamic_reference_base::~dynamic_reference_base() { - for (interfacelist::iterator iter = Interfaces.begin(); iter != Interfaces.end(); iter++) + for(unsigned int i = 0; i < ServerInstance->Modules->ActiveDynrefs.size(); i++) { - for (modulelist::iterator x = iter->second.second.begin(); x != iter->second.second.end(); x++) + if (ServerInstance->Modules->ActiveDynrefs[i] == this) { - if (*x == m) - { - return std::make_pair(iter->second.first, iter->first); - } + unsigned int last = ServerInstance->Modules->ActiveDynrefs.size() - 1; + if (i != last) + ServerInstance->Modules->ActiveDynrefs[i] = ServerInstance->Modules->ActiveDynrefs[last]; + ServerInstance->Modules->ActiveDynrefs.erase(ServerInstance->Modules->ActiveDynrefs.begin() + last); + return; } } - return std::make_pair(0, ""); -} - -const std::string& ModuleManager::GetModuleName(Module* m) -{ - static std::string nothing; - - for (std::map<std::string, Module*>::iterator n = Modules.begin(); n != Modules.end(); ++n) - { - if (n->second == m) - return n->first; - } - - return nothing; -} - -CmdResult InspIRCd::CallCommandHandler(const std::string &commandname, const std::vector<std::string>& parameters, User* user) -{ - return this->Parser->CallHandler(commandname, parameters, user); } -bool InspIRCd::IsValidModuleCommand(const std::string &commandname, int pcnt, User* user) +void dynamic_reference_base::SetProvider(const std::string& newname) { - return this->Parser->IsValidCommand(commandname, pcnt, user); + name = newname; + ClearCache(); } -void InspIRCd::AddCommand(Command *f) +void dynamic_reference_base::lookup() { - if (!this->Parser->AddCommand(f)) - { - throw ModuleException("Command "+std::string(f->name)+" already exists."); - } + if (!*this) + throw ModuleException("Dynamic reference to '" + name + "' failed to resolve"); } -void InspIRCd::AddService(providerbase& item) +dynamic_reference_base::operator bool() { - switch (item.service) + if (!value) { - case SERVICE_COMMAND: - if (!Parser->AddCommand(static_cast<Command*>(&item))) - throw ModuleException("Command "+std::string(item.name)+" already exists."); - return; - case SERVICE_CMODE: - case SERVICE_UMODE: - if (!Modes->AddMode(static_cast<ModeHandler*>(&item))) - throw ModuleException("Mode "+std::string(item.name)+" already exists."); - return; - case SERVICE_METADATA: - Extensions.Register(static_cast<ExtensionItem*>(&item)); - return; - case SERVICE_DATA: - case SERVICE_IOHOOK: - default: - throw ModuleException("Cannot add unknown service type"); + std::multimap<std::string, ServiceProvider*>::iterator i = ServerInstance->Modules->DataProviders.find(name); + if (i != ServerInstance->Modules->DataProviders.end()) + value = static_cast<DataProvider*>(i->second); } + return value; } void InspIRCd::SendMode(const std::vector<std::string>& parameters, User *user) |