fixed eol-style
[xonotic/netradiant.git] / libs / modulesystem / modulesmap.h
1 /*
2 Copyright (C) 2001-2006, William Joseph.
3 All Rights Reserved.
4
5 This file is part of GtkRadiant.
6
7 GtkRadiant is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2 of the License, or
10 (at your option) any later version.
11
12 GtkRadiant is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GtkRadiant; if not, write to the Free Software
19 Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
20 */
21
22 #if !defined(INCLUDED_MODULESYSTEM_MODULESMAP_H)
23 #define INCLUDED_MODULESYSTEM_MODULESMAP_H
24
25 #include "modulesystem.h"
26 #include "string/string.h"
27 #include <map>
28 #include <set>
29
30 template<typename Type>
31 class ModulesMap : public Modules<Type>
32 {
33   typedef std::map<CopiedString, Module*> modules_t;
34   modules_t m_modules;
35 public:
36   ~ModulesMap()
37   {
38     for(modules_t::iterator i = m_modules.begin(); i != m_modules.end(); ++i) 
39     {
40       (*i).second->release();
41     }
42   }
43
44   typedef modules_t::const_iterator iterator;
45
46   iterator begin() const
47   {
48     return m_modules.begin();
49   }
50   iterator end() const
51   {
52     return m_modules.end();
53   }
54
55   void insert(const char* name, Module& module)
56   {
57     module.capture();
58     if(globalModuleServer().getError())
59     {
60       module.release();
61       globalModuleServer().setError(false);
62     }
63     else
64     {
65       m_modules.insert(modules_t::value_type(name, &module));
66     }
67   }
68
69   Type* find(const char* name)
70   {
71     modules_t::iterator i = m_modules.find(name);
72     if(i != m_modules.end())
73     {
74       return static_cast<Type*>(Module_getTable(*(*i).second));
75     }
76     return 0;
77   }
78
79   Type* findModule(const char* name)
80   {
81     return find(name);
82   }
83   void foreachModule(typename Modules<Type>::Visitor& visitor)
84   {
85     for(modules_t::iterator i = m_modules.begin(); i != m_modules.end(); ++i)
86     {
87       visitor.visit((*i).first.c_str(), *static_cast<const Type*>(Module_getTable(*(*i).second)));
88     }
89   }
90 };
91
92 template<typename Type>
93 class InsertModules : public ModuleServer::Visitor
94 {
95   ModulesMap<Type>& m_modules;
96 public:
97   InsertModules(ModulesMap<Type>& modules)
98     : m_modules(modules)
99   {
100   }
101   void visit(const char* name, Module& module)
102   {
103     m_modules.insert(name, module);
104   }
105 };
106
107 template<typename Type>
108 class ModulesRef
109 {
110   ModulesMap<Type> m_modules;
111 public:
112   ModulesRef(const char* names)
113   {
114     if(!globalModuleServer().getError())
115     {
116       if(string_equal(names, "*"))
117       {
118         InsertModules<Type> visitor(m_modules);
119         globalModuleServer().foreachModule(typename Type::Name(), typename Type::Version(), visitor);
120       }
121       else
122       {
123         StringTokeniser tokeniser(names);
124         for(;;)
125         {
126           const char* name = tokeniser.getToken();
127           if(string_empty(name))
128           {
129             break;
130           }
131           Module* module = globalModuleServer().findModule(typename Type::Name(), typename Type::Version(), name);
132           if(module == 0)
133           {
134             globalModuleServer().setError(true);
135             globalErrorStream() << "ModulesRef::initialise: type=" << makeQuoted(typename Type::Name()) << " version=" << makeQuoted(typename Type::Version()) << " name=" << makeQuoted(name) << " - not found\n";
136             break;
137           }
138           else
139           {
140             m_modules.insert(name, *module);
141           }
142         }
143       }
144     }
145   }
146   ModulesMap<Type>& get()
147   {
148     return m_modules;
149   }
150 };
151
152 #endif