Code: Select all
1 /********************************************************************
2 created: 2010/01/28
3 created: 28:1:2010 9:57
4 filename: nrpConfig.h
5 file base: nrpConfig
6 file ext: h
7 author: Dalerank
8
9 purpose: Îïèñàíèå ñâîéñòâ îáúåêòà
10 *********************************************************************/
11 #pragma once
12
13 #include <map>
14 #include <typeinfo.h>
15 #include <assert.h>
16 #include <memory>
17
18 #include "INrpObject.h"
19 #include "SectionNames.h"
20 #include "OptionNames.h"
21 #include "nrptext.h"
22
23 #define _self (*this)
24
25 using namespace irr;
26
27 namespace nrp
28 {
29
30 bool CheckClassesType( const type_info& type1, const type_info& type2 );
31
32 class IParam
33 {
34 public:
35
36 virtual const type_info& GetType() = 0;
37 virtual std::auto_ptr<IParam> Duplicate() const = 0;
38 virtual void Reset() = 0;
39 };
40
41 typedef std::auto_ptr<IParam> APtrParam;
42
43 class INotification
44 {
45 public:
46 virtual void Exec() = 0;
47 };
48
49 class NParam;
50
51
52 template< class T>
53 class NNotification : public INotification
54 {
55 typedef void (T::*Method)( NParam& );
56
57 public:
58 NNotification( NParam* parent, T* object, Method objMethod ) :
59 _object( object ),
60 _objMethod( objMethod ),
61 _parent( parent )
62 {
63
64 }
65
66 void Exec() { (_object->*_objMethod )( *_parent ); }
67 private:
68
69 T* _object;
70 Method _objMethod;
71 NParam* _parent;
72 };
73
74 template<typename T>
75 class NProxyParam : public IParam
76 {
77 public:
78 NProxyParam(const T& value) : _value(value) {}
79 NProxyParam(const NProxyParam& copy) : _value(copy._value){}
80 /// Get the stored data
81 operator T& () { return _value; }
82 /// Get the stored data
83 /**
84 * @return the reference to the stored data element
85 */
86 T& Get() { return _value; }
87 /// Get the stored data
88 /**
89 * @return the constant reference to the stored data element
90 */
91 const int& Get() const { return _value; }
92 virtual const type_info& GetType() { return typeid(T); }
93
94 IParam& operator=(const NProxyParam& copy)
95 {
96 _value = copy._value;
97 return *this;
98 }
99
100 IParam& operator+=(const NProxyParam& copy)
101 {
102 _value += copy._value;
103 return *this;
104 }
105
106 bool operator<(const NProxyParam& copy)
107 {
108 return _value < copy._value;
109 }
110
111 bool operator==(const NProxyParam& copy)
112 {
113 return _value == copy._value;
114 }
115
116 std::auto_ptr<IParam> Duplicate() const
117 {
118 std::auto_ptr<IParam> sobjCopy( new NProxyParam<T>(_value) );
119 return sobjCopy;
120 }
121
122 void Reset() {};
123
124 ~NProxyParam(){}
125 private:
126 NProxyParam(){}
127 T _value;
128 };
129
130 class NParam
131 {
132 NParam() {}
133
134 public:
135 NParam(const NParam& copy) : _value(copy._value) {}
136
137 NParam& operator=(const NParam& copy)
138 {
139 assert( CheckClassesType( typeid( copy._value ) , typeid( _value ) ) );
140 _value = copy._value->Duplicate();
141 return *this;
142 }
143
144 NParam(const char* str );
145 /// Template for constructing a NParam object from any type. Creates a copy of the object by using its copy constructor.
146 template<typename T> NParam( const NrpText& name, const T& val ) : _name( name )
147 {
148 _value = std::auto_ptr< IParam >( new NProxyParam<T>(val) );
149 }
150
151 /// Assigns the Value instance with object of any type by using its copy constructor.
152 template<typename T> NParam& operator=(const T& val)
153 {
154 if( _value.get() )
155 assert( CheckClassesType( typeid(T), _value->GetType() ) );
156
157 As<T>() = val;
158
159 _CheckNotifications();
160 return *this;
161 }
162 /// Assigns the NParam instance with object of type std::string constructed from char*.
163 /**
164 * Note, that in spite of type of the parameter (const char*) it's std::string which is really
165 * stored in the current NParam! Type char* doesn't match the requirements to types which can be
166 * stored inside Value
167 */
168 NParam& operator=(const char* val);
169
170 /// Accessor to the Structure element by its name.
171 /**
172 * If current Value is empty, it is initialised as a Structure.
173 * If it is not empty and it's not a Structure, an exception of type Exception arises.
174 * If Structure doesn't contain an entry with specified key, it is created
175 * and initialised with an empty Value.
176 * @param key - unique name (identifier) of the element
177 * @return reference to Value stored in the Structure
178 */
179 /// These two casts are necessary only for old gcc 4.1.2 (fc8)
180 operator NParam&() { return *this; }
181 operator const NParam&() const { return *this; }
182 /// Makes a copy of the current instance. Returns an instance of Value that references to a newly created copy.
183
184 template<typename T> T& As()
185 {
186 assert( _value.get() != NULL );
187 assert( CheckClassesType( typeid(T), _value.get()->GetType() ) );
188 if( typeid(T)==typeid(NParam) ) return *this;
189
190 return ((NProxyParam<T>*)(_value.get()))->Get();
191 }
192
193 template<typename T> T& As() const
194 {
195 assert( _value.get() != NULL );
196 assert( CheckClassesType( typeid(T), _value.get()->GetType() ) );
197 return const_cast<NParam *>(this)->As<T>();
198 }
199
200 operator int() { return As<int>(); }
201 operator const int&() const { return As<int>(); }
202 operator bool() { return As<bool>(); }
203 operator float() { return As<float>(); }
204 operator const float&() const { return As<float>(); }
205 operator const NrpText&() const { return As<NrpText>(); }
206
207 bool operator < ( const NParam& a ) const { return _value.get() < a._value.get(); }
208 bool operator == ( const NParam& a ) const { return _value.get() == a._value.get(); }
209
210 template<typename T> bool operator !=( const T& a ) const { return As<T>() != a; }
211 template<typename T> bool operator >=( const T& b ) const { return As<T>() >= b; }
212
213 template<typename T> T operator*( const T& b ) const { return As<T>() * b; }
214 template<typename T> T operator-( const T& b ) const { return As<T>() - b; }
215
216 template<typename T> operator T() const { return As<T>(); }
217 template<typename T> operator const T&() const { return As<T>(); }
218 template<typename T> operator const T&() { return As<T>(); }
219 template<typename T> operator T&() { return As<T>(); }
220
221 template<typename T> bool operator ==( const T& a ) const { return As<T>() == a; }
222 template<typename T> NParam& operator +=( const T& a ) { As<T>() += a; return *this; }
223 template<typename T> NParam& operator -=( const T& a ) { As<T>() -= a; return *this; }
224
225 /// Safe (no-exception-throwing) Value type checker
226 /**
227 * Compares specified type info (template parameter) and type name with stored value type.
228 * @param typeName - serialized type name (e.g. "int", "double", "Structure", etc).
229 * @return true if type info <b>or</b> type name matches, and false if both checks fail.
230 */
231 template<typename T>
232 bool Is()
233 {
234 if( _value.get() )
235 {
236 if (typeid(T) == typeid(void)) return true;
237 return false;
238 }
239 return ( _value->GetType() == typeid(T) );
240 }
241
242 bool IsNull() const;
243
244 /// Erase current Value
245 void Reset()
246 {
247 _value.release();// = std::auto_ptr<INrpProperty>();
248 }
249
250 NrpText GetType()
251 {
252 if( _value.get() )
253 return NrpText( L"void" );
254
255 return NrpText( _value->GetType().name() );
256 }
257
258 const NrpText& GetName() { return _name; }
259
260 template< class OBJ_CLASS >
261 void AddNotification( const NrpText& key, OBJ_CLASS* obj, void (OBJ_CLASS::*Method)( NParam& ) )
262 {
263 _notifications[ key ] = new NNotification< OBJ_CLASS >( this, obj, Method );
264 }
265
266 virtual ~NParam(){}
267 private:
268 mutable APtrParam _value;
269 NrpText _name;
270
271 void _CheckNotifications();
272
273 typedef std::map< NrpText, INotification* > NOTIFICATIONS;
274 NOTIFICATIONS _notifications;
275 };
276
277 class INrpConfig : public INrpObject
278 {
279 friend class CNrpConfigLooder;
280 typedef std::map< OPTION_NAME, NParam* > PARAMS;
281 public:
282 INrpConfig( CLASS_NAME className, SYSTEM_NAME sysName ) : INrpObject( className, sysName )
283 {
284
285 }
286
287 INrpConfig(const INrpConfig& copy);
288
289 virtual NParam& operator[](OPTION_NAME& key);
290
291 /// Const accessor to the Structure element by its name.
292 virtual const NParam& operator[](OPTION_NAME& key) const;
293
294 bool IsExist(const NrpText& key) const;
295 /// Tests whether the index is in bounds of the Array.
296
297 void UpdatedParam( NParam& ) {};
298
299 NParam& Param( OPTION_NAME& key ) { return operator[](key); }
300 NrpText Text( OPTION_NAME& key ) { return operator[](key).As<NrpText>(); }
301
302 protected:
303 virtual NrpText Save( const NrpText& fileName );
304 virtual void Load( const NrpText& fileName );
305
306 template< class B > void Add( OPTION_NAME& name, const B& valuel )
307 {
308 NrpText fName = name.ToLower();
309
310 if( _params.find( fName ) != _params.end() )
311 *_params[ fName ] = valuel;
312 else
313 _params[ fName ] = new NParam( fName, valuel );
314 }
315
316 unsigned Remove(const NrpText& key);
317 /// Erase the specified element of the Array
318 private:
319 //! îïðåäåëåíèå ìàññèâà ñâîéñòâ
320 INrpConfig() : INrpObject( "error", "error" ) {}
321 mutable PARAMS _params;
322 };
323
324 } //namespace nrp
Howto using:
Code: Select all
class SimpleConf : public INrpConfig
{
};
SimpleConf conf;
NParam a, b, c, d;
a=5; // now type of a is int
!!!!!a = 5.4; // Assert only equale type must operation!!!!!
a = static_cast< int >( 5.4 ); // no error
b= NrpText( "Hello, world!" ); // NrpText in my project is core::stringw
core::array< core::stringc > someList;
lst.push_back("A");
lst.push_back("B");
c = lst;
d = 0.4f;
int sum=1+a+2;
int prod=2*(int)a*3;
int result = 1 + (float)d * (int)a;
conf.Add( "name", "John" ); //here i create new param as text
conf.Add( "class", new SomeClass() ); //and new param as SomeClass
conf.Add( "old", 45 ); //and new param as int
conf.Add( "PropGroup", INrpConfig() ); //add new props group
conf[ "PropGroup" ].Add( "Number" , 12345 ); //new int prop in group
conf[ "PropGroup" ].Add("Balance" , 123.45f ); //new double prop in group
//but if i want get not real props i get assert:
int someProp = conf[ "SomeProp" ]; /// assert - invalid prop
//using config:
int result = conf[ "old" ];
SomeClass* obj = conf[ "class" ].As<SomeClass>();
NrpText name = conf[ "name" ];
http://gameinc.svn.sourceforge.net/view ... iew=markup