1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
|
/*
* Value.h: interface for the CValue class.
* Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
*
* Permission to use, copy, modify, distribute and sell this software
* and its documentation for any purpose is hereby granted without fee,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear
* in supporting documentation. Erwin Coumans makes no
* representations about the suitability of this software for any
* purpose. It is provided "as is" without express or implied warranty.
*/
/** \file EXP_Value.h
* \ingroup expressions
*/
#ifndef __EXP_VALUE_H__
#define __EXP_VALUE_H__
#ifdef _MSC_VER
# pragma warning (disable:4786)
#endif
#include <map> // array functionality for the propertylist
#include "STR_String.h" // STR_String class
using namespace std;
#ifdef WITH_CXX_GUARDEDALLOC
#include "MEM_guardedalloc.h"
#endif
#ifndef GEN_NO_ASSERT
#undef assert
#define assert(exp) ((void)NULL)
#endif
#ifndef GEN_NO_TRACE
#undef trace
#define trace(exp) ((void)NULL)
#endif
#ifndef GEN_NO_DEBUG
#undef debug
#define debug(exp) ((void)NULL)
#endif
#ifndef GEN_NO_ASSERTD
#undef assertd
#define assertd(exp) ((void)NULL)
#endif
enum VALUE_OPERATOR {
VALUE_MOD_OPERATOR, // %
VALUE_ADD_OPERATOR, // +
VALUE_SUB_OPERATOR, // -
VALUE_MUL_OPERATOR, // *
VALUE_DIV_OPERATOR, // /
VALUE_NEG_OPERATOR, // -
VALUE_POS_OPERATOR, // +
VALUE_AND_OPERATOR, // &&
VALUE_OR_OPERATOR, // ||
VALUE_EQL_OPERATOR, // ==
VALUE_NEQ_OPERATOR, // !=
VALUE_GRE_OPERATOR, // >
VALUE_LES_OPERATOR, // <
VALUE_GEQ_OPERATOR, // >=
VALUE_LEQ_OPERATOR, // <=
VALUE_NOT_OPERATOR, // !
VALUE_NO_OPERATOR // no operation at all
};
enum VALUE_DATA_TYPE {
VALUE_NO_TYPE, // abstract baseclass
VALUE_INT_TYPE,
VALUE_FLOAT_TYPE,
VALUE_STRING_TYPE,
VALUE_BOOL_TYPE,
VALUE_ERROR_TYPE,
VALUE_EMPTY_TYPE,
VALUE_LIST_TYPE,
VALUE_VOID_TYPE,
VALUE_VECTOR_TYPE,
VALUE_MAX_TYPE //only here to provide number of types
};
#ifdef DEBUG
//extern int gRefCountValue; // debugonly variable to check if all CValue Refences are Dereferenced at programexit
#endif
struct HashableInt
{
HashableInt(int id) : mData(id) { }
unsigned long Hash() const { return 0;} ////}gHash(&mData, sizeof(int));}
bool operator==(HashableInt rhs) { return mData == rhs.mData; }
int mData;
};
//
// Bitfield that stores the flags for each CValue derived class
//
struct ValueFlags {
ValueFlags() :
Modified(true),
Selected(false),
Affected(false),
ReleaseRequested(false),
Error(false),
RefCountDisabled(false),
HasProperties(false),
HasName(false),
Visible(true),
CustomFlag1(false),
CustomFlag2(false)
{
}
unsigned short Modified : 1;
unsigned short Selected : 1;
unsigned short Affected : 1;
unsigned short ReleaseRequested : 1;
unsigned short Error : 1;
unsigned short RefCountDisabled : 1;
unsigned short HasProperties : 1;
unsigned short HasName : 1;
unsigned short Visible : 1;
unsigned short CustomFlag1 : 1;
unsigned short CustomFlag2 : 1;
};
/**
* Base Class for all Actions performed on CValue's. Can be extended for undo/redo system in future.
*/
class CAction
{
public:
CAction() {
};
virtual ~CAction() {
};
virtual void Execute() const =0;
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GE:CAction")
#endif
};
#include "EXP_PyObjectPlus.h"
#ifdef WITH_PYTHON
#include "object.h"
#endif
/**
* Baseclass CValue
*
* Together with CExpression, CValue and it's derived classes can be used to
* parse expressions into a parsetree with error detecting/correcting capabilities
* also expandable by a CFactory pluginsystem
*
* Base class for all editor functionality, flexible object type that allows
* calculations and uses reference counting for memory management.
*
* Features:
* - Reference Counting (AddRef() / Release())
* - Calculations (Calc() / CalcFinal())
* - Configuration (Configure())
* - Serialization (EdSerialize() / EdIdSerialize() / EdPtrSerialize() and macro PLUGIN_DECLARE_SERIAL
* - Property system (SetProperty() / GetProperty() / FindIdentifier())
* - Replication (GetReplica())
* - Flags (IsSelected() / IsModified() / SetSelected()...)
*
* - Some small editor-specific things added
* - A helperclass CompressorArchive handles the serialization
*/
class CValue : public PyObjectPlus
{
Py_Header
public:
enum AllocationTYPE {
STACKVALUE = 0,
HEAPVALUE = 1
};
enum DrawTYPE {
STARTFRAME = 0,
ENDFRAME = 1,
INTERFRAME = 2
};
// Construction / Destruction
CValue();
#ifdef WITH_PYTHON
//static PyObject *PyMake(PyObject *, PyObject *);
virtual PyObject *py_repr(void)
{
return PyUnicode_From_STR_String(GetText());
}
virtual PyObject *ConvertValueToPython() {
return NULL;
}
virtual CValue *ConvertPythonToValue(PyObject *pyobj, const bool do_type_exception, const char *error_prefix);
static PyObject *pyattr_get_name(void *self, const KX_PYATTRIBUTE_DEF *attrdef);
virtual PyObject *ConvertKeysToPython( void );
#endif /* WITH_PYTHON */
// Expression Calculation
virtual CValue* Calc(VALUE_OPERATOR op, CValue *val) = 0;
virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val) = 0;
virtual void SetOwnerExpression(class CExpression* expr);
void Execute(const CAction& a)
{
a.Execute();
};
/// Reference Counting
int GetRefCount()
{
return m_refcount;
}
// Add a reference to this value
CValue *AddRef()
{
// Increase global reference count, used to see at the end of the program
// if all CValue-derived classes have been dereferenced to 0
//debug(gRefCountValue++);
#ifdef DEBUG
//gRefCountValue++;
#endif
m_refcount++;
return this;
}
// Release a reference to this value (when reference count reaches 0, the value is removed from the heap)
int Release()
{
// Decrease global reference count, used to see at the end of the program
// if all CValue-derived classes have been dereferenced to 0
//debug(gRefCountValue--);
#ifdef DEBUG
//gRefCountValue--;
#endif
// Decrease local reference count, if it reaches 0 the object should be freed
if (--m_refcount > 0)
{
// Reference count normal, return new reference count
return m_refcount;
}
else
{
// Reference count reached 0, delete ourselves and return 0
// MT_assert(m_refcount==0, "Reference count reached sub-zero, object released too much");
delete this;
return 0;
}
}
/// Property Management
virtual void SetProperty(const STR_String& name,CValue* ioProperty); // Set property <ioProperty>, overwrites and releases a previous property with the same name if needed
virtual void SetProperty(const char* name,CValue* ioProperty);
virtual CValue* GetProperty(const char* inName); // Get pointer to a property with name <inName>, returns NULL if there is no property named <inName>
virtual CValue* GetProperty(const STR_String & inName);
const STR_String& GetPropertyText(const STR_String & inName); // Get text description of property with name <inName>, returns an empty string if there is no property named <inName>
float GetPropertyNumber(const STR_String& inName,float defnumber);
virtual bool RemoveProperty(const char *inName); // Remove the property named <inName>, returns true if the property was succesfully removed, false if property was not found or could not be removed
virtual vector<STR_String> GetPropertyNames();
virtual void ClearProperties(); // Clear all properties
virtual void SetPropertiesModified(bool inModified); // Set all properties' modified flag to <inModified>
virtual bool IsAnyPropertyModified(); // Check if any of the properties in this value have been modified
virtual CValue* GetProperty(int inIndex); // Get property number <inIndex>
virtual int GetPropertyCount(); // Get the amount of properties assiocated with this value
virtual CValue* FindIdentifier(const STR_String& identifiername);
/** Set the wireframe color of this value depending on the CSG
* operator type <op>
* \attention: not implemented */
virtual void SetColorOperator(VALUE_OPERATOR op);
virtual const STR_String & GetText() = 0;
virtual double GetNumber() = 0;
virtual int GetValueType(); // Get Prop value type
double* ZeroVector() { return m_sZeroVec; }
virtual double* GetVector3(bool bGetTransformedVec = false);
virtual STR_String& GetName() = 0; // Retrieve the name of the value
virtual void SetName(const char *name) = 0; // Set the name of the value
/** Sets the value to this cvalue.
* \attention this particular function should never be called. Why not abstract? */
virtual void SetValue(CValue* newval);
virtual CValue* GetReplica() =0;
virtual void ProcessReplica();
//virtual CValue* Copy() = 0;
STR_String op2str(VALUE_OPERATOR op);
// setting / getting flags
inline void SetSelected(bool bSelected) { m_ValFlags.Selected = bSelected; }
virtual void SetModified(bool bModified) { m_ValFlags.Modified = bModified; }
virtual void SetAffected(bool bAffected=true) { m_ValFlags.Affected = bAffected; }
inline void SetReleaseRequested(bool bReleaseRequested) { m_ValFlags.ReleaseRequested=bReleaseRequested; }
inline void SetError(bool err) { m_ValFlags.Error=err; }
inline void SetVisible (bool vis) { m_ValFlags.Visible=vis; }
virtual bool IsModified() { return m_ValFlags.Modified; }
inline bool IsError() { return m_ValFlags.Error; }
virtual bool IsAffected() { return m_ValFlags.Affected || m_ValFlags.Modified; }
virtual bool IsSelected() { return m_ValFlags.Selected; }
inline bool IsReleaseRequested() { return m_ValFlags.ReleaseRequested; }
virtual bool IsVisible() { return m_ValFlags.Visible;}
virtual void SetCustomFlag1(bool bCustomFlag) { m_ValFlags.CustomFlag1 = bCustomFlag;}
virtual bool IsCustomFlag1() { return m_ValFlags.CustomFlag1;}
virtual void SetCustomFlag2(bool bCustomFlag) { m_ValFlags.CustomFlag2 = bCustomFlag;}
virtual bool IsCustomFlag2() { return m_ValFlags.CustomFlag2;}
protected:
virtual void DisableRefCount(); // Disable reference counting for this value
//virtual void AddDataToReplica(CValue* replica);
virtual ~CValue();
private:
// Member variables
std::map<STR_String,CValue*>* m_pNamedPropertyArray; // Properties for user/game etc
ValueFlags m_ValFlags; // Frequently used flags in a bitfield (low memoryusage)
int m_refcount; // Reference Counter
static double m_sZeroVec[3];
};
//
// Declare a CValue or CExpression or CWhatever to be serialized by the editor.
//
// This macro introduces the EdSerialize() function (which must be implemented by
// the client) and the EdIdSerialize() function (which is implemented by this macro).
//
// The generated Copy() function returns a pointer to <root_base_class_name> type
// of object. So, for *any* CValue-derived object this should be set to CValue,
// for *any* CExpression-derived object this should be set to CExpression.
//
#define PLUGIN_DECLARE_SERIAL(class_name, root_base_class_name) \
public: \
virtual root_base_class_name *Copy() { \
return new class_name; \
} \
virtual bool EdSerialize(CompressorArchive& arch, \
class CFactoryManager* facmgr, \
bool bIsStoring); \
virtual bool EdIdSerialize(CompressorArchive& arch, \
class CFactoryManager* facmgr, \
bool bIsStoring) \
{ \
if (bIsStoring) \
arch.StoreString(#class_name); \
return false; \
} \
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////////////
// CPropValue is a CValue derived class, that implements the identification (String name)
// SetName() / GetName(),
// normal classes should derive from CPropValue, real lightweight classes straight from CValue
class CPropValue : public CValue
{
public:
CPropValue() :
CValue(),
m_strNewName()
{
}
virtual ~CPropValue()
{
}
virtual void SetName(const char *name) {
m_strNewName = name;
}
virtual STR_String& GetName() {
//STR_String namefromprop = GetPropertyText("Name");
//if (namefromprop.Length() > 0)
// return namefromprop;
return m_strNewName;
} // name of Value
protected:
STR_String m_strNewName; // Identification
#ifdef WITH_CXX_GUARDEDALLOC
MEM_CXX_CLASS_ALLOC_FUNCS("GE:CPropValue")
#endif
};
#endif /* __EXP_VALUE_H__ */
|