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