]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - src/modmanager_static.cpp
Fix mode Z being in the wrong section of the CHANMODES list
[user/henk/code/inspircd.git] / src / modmanager_static.cpp
1 #include "inspircd.h"
2
3 #ifdef PURE_STATIC
4
5 static std::vector<AllCommandList::fn>* cmdlist = NULL;
6 static std::vector<AllModuleList*>* modlist = NULL;
7
8 AllCommandList::AllCommandList(fn cmd)
9 {
10         if (!cmdlist)
11                 cmdlist = new std::vector<AllCommandList::fn>();
12         cmdlist->push_back(cmd);
13 }
14
15 AllModuleList::AllModuleList(AllModuleList::fn mod, const std::string& Name) : init(mod), name(Name)
16 {
17         if (!modlist)
18                 modlist = new std::vector<AllModuleList*>();
19         modlist->push_back(this);
20 }
21
22 class AllModule : public Module
23 {
24         std::vector<Command*> cmds;
25  public:
26         AllModule()
27         {
28                 if (!cmdlist)
29                         return;
30                 try
31                 {
32                         cmds.reserve(cmdlist->size());
33                         for(std::vector<AllCommandList::fn>::iterator i = cmdlist->begin(); i != cmdlist->end(); ++i)
34                         {
35                                 Command* c = (*i)(this);
36                                 cmds.push_back(c);
37                                 ServerInstance->AddCommand(c);
38                         }
39                 }
40                 catch (...)
41                 {
42                         this->AllModule::~AllModule();
43                         throw;
44                 }
45         }
46
47         ~AllModule()
48         {
49                 for(std::vector<Command*>::iterator i = cmds.begin(); i != cmds.end(); ++i)
50                         delete *i;
51         }
52
53         Version GetVersion()
54         {
55                 return Version("All commands", VF_VENDOR|VF_CORE);
56         }
57 };
58
59 MODULE_INIT(AllModule)
60
61 bool ModuleManager::Load(const std::string& name, bool)
62 {
63         for(std::vector<AllModuleList*>::iterator i = modlist->begin(); i != modlist->end(); ++i)
64         {
65                 if ((**i).name == name)
66                 {
67                         Module* c = NULL;
68                         try
69                         {
70                                 c = (*(**i).init)();
71                                 Modules[name] = c;
72                                 c->init();
73                                 FOREACH_MOD(I_OnLoadModule,OnLoadModule(c));
74                                 return true;
75                         }
76                         catch (CoreException& modexcept)
77                         {
78                                 if (c)
79                                         DoSafeUnload(c);
80                                 delete c;
81                                 ServerInstance->Logs->Log("MODULE", DEFAULT, "Unable to load " + (**i).name + ": " + modexcept.GetReason());
82                         }
83                 }
84         }
85         return false;
86 }
87
88 namespace {
89         struct UnloadAction : public HandlerBase0<void>
90         {
91                 Module* const mod;
92                 UnloadAction(Module* m) : mod(m) {}
93                 void Call()
94                 {
95                         ServerInstance->Modules->DoSafeUnload(mod);
96                         ServerInstance->GlobalCulls.Apply();
97                         ServerInstance->GlobalCulls.AddItem(this);
98                 }
99         };
100
101         struct ReloadAction : public HandlerBase0<void>
102         {
103                 Module* const mod;
104                 HandlerBase1<void, bool>* const callback;
105                 ReloadAction(Module* m, HandlerBase1<void, bool>* c)
106                         : mod(m), callback(c) {}
107                 void Call()
108                 {
109                         std::string name = mod->ModuleSourceFile;
110                         ServerInstance->Modules->DoSafeUnload(mod);
111                         ServerInstance->GlobalCulls.Apply();
112                         bool rv = ServerInstance->Modules->Load(name.c_str());
113                         callback->Call(rv);
114                         ServerInstance->GlobalCulls.AddItem(this);
115                 }
116         };
117 }
118
119 bool ModuleManager::Unload(Module* mod)
120 {
121         if (!CanUnload(mod))
122                 return false;
123         ServerInstance->AtomicActions.AddAction(new UnloadAction(mod));
124         return true;
125 }
126
127 void ModuleManager::Reload(Module* mod, HandlerBase1<void, bool>* callback)
128 {
129         if (CanUnload(mod))
130                 ServerInstance->AtomicActions.AddAction(new ReloadAction(mod, callback));
131         else
132                 callback->Call(false);
133 }
134
135 void ModuleManager::LoadAll()
136 {
137         ModCount = 0;
138         for(std::vector<AllModuleList*>::iterator i = modlist->begin(); i != modlist->end(); ++i)
139         {
140                 Module* c = NULL;
141                 try
142                 {
143                         c = (*(**i).init)();
144                         c->ModuleSourceFile = (**i).name;
145                         c->ModuleDLLManager = NULL;
146                         Modules[(**i).name] = c;
147                         c->init();
148                 }
149                 catch (CoreException& modexcept)
150                 {
151                         if (c)
152                                 DoSafeUnload(c);
153                         delete c;
154                         ServerInstance->Logs->Log("MODULE", DEFAULT, "Unable to load " + (**i).name + ": " + modexcept.GetReason());
155                 }
156         }
157
158         /* We give every module a chance to re-prioritize when we introduce a new one,
159          * not just the one thats loading, as the new module could affect the preference
160          * of others
161          */
162         for(int tries = 0; tries < 20; tries++)
163         {
164                 prioritizationState = tries > 0 ? PRIO_STATE_LAST : PRIO_STATE_FIRST;
165                 for (std::map<std::string, Module*>::iterator n = Modules.begin(); n != Modules.end(); ++n)
166                         n->second->Prioritize();
167
168                 if (prioritizationState == PRIO_STATE_LAST)
169                         break;
170                 if (tries == 19)
171                         ServerInstance->Logs->Log("MODULE", DEFAULT, "Hook priority dependency loop detected");
172         }
173
174         ServerInstance->BuildISupport();
175 }
176
177 void ModuleManager::UnloadAll()
178 {
179 }
180
181 #endif