]> git.netwichtig.de Git - user/henk/code/inspircd.git/blob - include/extensible.h
Change Extensible to use strongly typed entries
[user/henk/code/inspircd.git] / include / extensible.h
1 class Extensible;
2 class Module;
3
4 /** Class represnting an extension of some object
5  */
6 class CoreExport ExtensionItem
7 {
8  public:
9         const std::string key;
10         Module* const owner;
11         ExtensionItem(const std::string& key, Module* owner);
12         /** Serialize this item into a string */
13         virtual std::string serialize(Module* requestor, const Extensible* container, void* item) = 0;
14         /** Convert the string form back into an item */
15         virtual void unserialize(Module* requestor, Extensible* container, const std::string& value) = 0;
16         /** Free the item */
17         virtual void free(void* item) = 0;
18
19  protected:
20         /** Get the item from the internal map */
21         void* get_raw(const Extensible* container);
22         /** Set the item in the internal map; returns old value */
23         void* set_raw(Extensible* container, void* value);
24         /** Remove the item from the internal map; returns old value */
25         void* unset_raw(Extensible* container);
26 };
27
28 /** A private data store for an Extensible class */
29 typedef std::map<std::string,void*> ExtensibleStore;
30
31 /** class Extensible is the parent class of many classes such as User and Channel.
32  * class Extensible implements a system which allows modules to 'extend' the class by attaching data within
33  * a map associated with the object. In this way modules can store their own custom information within user
34  * objects, channel objects and server objects, without breaking other modules (this is more sensible than using
35  * a flags variable, and each module defining bits within the flag as 'theirs' as it is less prone to conflict and
36  * supports arbitary data storage).
37  */
38 class CoreExport Extensible : public classbase
39 {
40         /** Private data store.
41          * Holds all extensible metadata for the class.
42          */
43         ExtensibleStore extensions;
44         typedef std::map<std::string, ExtensionItem*> ExtensibleTypes;
45         static ExtensibleTypes extension_types;
46  public:
47         /**
48          * Get the extension items for iteraton (i.e. for metadata sync during netburst)
49          */
50         inline const ExtensibleStore& GetExtList() const { return extensions; }
51         static inline const ExtensibleTypes& GetTypeList() { return extension_types; }
52         static inline ExtensionItem* GetItem(const std::string& name)
53         {
54                 ExtensibleTypes::iterator i = extension_types.find(name);
55                 if (i == extension_types.end())
56                         return NULL;
57                 return i->second;
58         }
59
60         virtual ~Extensible();
61
62         static bool Register(ExtensionItem* item);
63         static void UnRegister(Module* module);
64         
65         // Friend access for the protected getter/setter
66         friend class ExtensionItem;
67 };
68
69 /** Base class for items that are NOT synchronized between servers */
70 class CoreExport LocalExtItem : public ExtensionItem
71 {
72  public:
73         LocalExtItem(const std::string& key, Module* owner);
74         // this is deliberately NOT virtual; don't subclass LocalExtItem if you want to sync data!
75         std::string serialize(Module* requestor, const Extensible* container, void* item);
76         void unserialize(Module* requestor, Extensible* container, const std::string& value);
77         virtual void free(void* item) = 0;
78 };
79
80 template<typename T>
81 class CoreExport SimpleExtItem : public LocalExtItem
82 {
83  public:
84         SimpleExtItem(const std::string& Key, Module* parent) : LocalExtItem(Key, parent)
85         {
86         }
87
88         inline T* get(const Extensible* container)
89         {
90                 return static_cast<T*>(get_raw(container));
91         }
92
93         inline T* getNew(Extensible* container)
94         {
95                 T* ptr = get(container);
96                 if (!ptr)
97                 {
98                         ptr = new T;
99                         set_raw(container, ptr);
100                 }
101                 return ptr;
102         }
103
104         inline void set(Extensible* container, const T& value)
105         {
106                 T* ptr = new T(value);
107                 T* old = static_cast<T*>(set_raw(container, ptr));
108                 delete old;
109         }
110
111         inline void set(Extensible* container, T* value)
112         {
113                 T* old = static_cast<T*>(set_raw(container, value));
114                 delete old;
115         }
116
117         inline void unset(Extensible* container)
118         {
119                 T* old = static_cast<T*>(unset_raw(container));
120                 delete old;
121         }
122
123         virtual void free(void* item)
124         {
125                 delete static_cast<T*>(item);
126         }
127 };
128
129 typedef SimpleExtItem<std::string> LocalStringExt;
130
131 class CoreExport LocalIntExt : public LocalExtItem
132 {
133  public:
134         LocalIntExt(const std::string& key, Module* owner);
135         intptr_t get(const Extensible* container);
136         intptr_t set(Extensible* container, intptr_t value);
137         void free(void* item);
138 };
139
140 class CoreExport StringExtItem : public ExtensionItem
141 {
142  public:
143         StringExtItem(const std::string& key, Module* owner);
144         std::string* get(const Extensible* container);
145         std::string serialize(Module* requestor, const Extensible* container, void* item);
146         void unserialize(Module* requestor, Extensible* container, const std::string& value);
147         void set(Extensible* container, const std::string& value);
148         void unset(Extensible* container);
149         void free(void* item);
150 };