doxygen: gameengine/Expressions tagged.
[blender-staging.git] / source / gameengine / Expressions / IntValue.cpp
1 /** \file gameengine/Expressions/IntValue.cpp
2  *  \ingroup expressions
3  */
4 // IntValue.cpp: implementation of the CIntValue class.
5 /*
6 * Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
7 *
8 * Permission to use, copy, modify, distribute and sell this software
9 * and its documentation for any purpose is hereby granted without fee,
10 * provided that the above copyright notice appear in all copies and
11 * that both that copyright notice and this permission notice appear
12 * in supporting documentation.  Erwin Coumans makes no
13 * representations about the suitability of this software for any
14 * purpose.  It is provided "as is" without express or implied warranty.
15 *
16 */
17
18 #include "IntValue.h"
19 #include "ErrorValue.h"
20 #include "FloatValue.h"
21 #include "BoolValue.h"
22 #include "StringValue.h"
23 #include "VoidValue.h"
24
25 //////////////////////////////////////////////////////////////////////
26 // Construction/Destruction
27 //////////////////////////////////////////////////////////////////////
28
29 CIntValue::CIntValue()
30 /*
31 pre: false
32 effect: constructs a new CIntValue
33 */
34 {
35         
36 #ifdef _DEBUG_
37         m_textval = "Int illegal constructor";
38 #endif
39         m_pstrRep=NULL;
40 }
41
42
43
44 CIntValue::CIntValue(cInt innie)
45 /*
46 pre:
47 effect: constructs a new CIntValue containing cInt innie
48 */
49 {
50         m_int = innie;
51         m_pstrRep=NULL;
52 }
53
54
55
56 CIntValue::CIntValue(cInt innie,const char *name,AllocationTYPE alloctype)
57 {
58         m_int = innie;
59         SetName(name);
60         
61         if (alloctype==CValue::STACKVALUE)
62         {
63                 CValue::DisableRefCount();
64         }
65         m_pstrRep=NULL;
66         
67 }
68
69
70
71 CIntValue::~CIntValue()
72 /*
73 pre:
74 effect: deletes the object
75 */
76 {
77         if (m_pstrRep)
78                 delete m_pstrRep;
79 }
80
81
82
83 CValue* CIntValue::Calc(VALUE_OPERATOR op, CValue *val)
84 /*
85 pre:
86 ret: a new object containing the result of applying operator op to this
87 object and val
88 */
89 {
90         //return val->CalcInt(op, this);
91         switch (op) {
92         case VALUE_POS_OPERATOR:
93                 return new CIntValue (m_int);
94                 break;
95         case VALUE_NEG_OPERATOR:
96                 return new CIntValue (-m_int);
97                 break;
98         case VALUE_NOT_OPERATOR:
99                 return new CErrorValue (op2str(op) + "only allowed on booleans");
100                 break;
101         case VALUE_AND_OPERATOR:
102         case VALUE_OR_OPERATOR:
103                 return new CErrorValue(val->GetText() + op2str(op) + "only allowed on booleans");
104                 break;
105         default:
106                 return val->CalcFinal(VALUE_INT_TYPE, op, this);
107                 break;
108         }
109 }
110
111
112
113 CValue* CIntValue::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val)
114 /*
115 pre: the type of val is dtype
116 ret: a new object containing the result of applying operator op to val and
117 this object
118 */
119 {
120         CValue *ret;
121         
122         switch(dtype) {
123         case VALUE_EMPTY_TYPE:
124         case VALUE_INT_TYPE:
125                 {
126                         switch (op) {
127                         case VALUE_MOD_OPERATOR:
128                                 ret = new CIntValue (((CIntValue *) val)->GetInt() % m_int);
129                                 break;
130                         case VALUE_ADD_OPERATOR:
131                                 ret = new CIntValue (((CIntValue *) val)->GetInt() + m_int);
132                                 break;
133                         case VALUE_SUB_OPERATOR:
134                                 ret = new CIntValue (((CIntValue *) val)->GetInt() - m_int);
135                                 break;
136                         case VALUE_MUL_OPERATOR:
137                                 ret = new CIntValue (((CIntValue *) val)->GetInt() * m_int);
138                                 break;
139                         case VALUE_DIV_OPERATOR:
140                                 if (m_int == 0)
141                                 {
142                                         if (val->GetNumber() == 0)
143                                         {
144                                                 ret = new CErrorValue("Not a Number");
145                                         } else
146                                         {
147                                                 ret = new CErrorValue("Division by zero");
148                                         }
149                                 }
150                                 else
151                                         ret = new CIntValue (((CIntValue *) val)->GetInt() / m_int);
152                                 break;
153                         case VALUE_EQL_OPERATOR:
154                                 ret = new CBoolValue(((CIntValue *) val)->GetInt() == m_int);
155                                 break;
156                         case VALUE_NEQ_OPERATOR:
157                                 ret = new CBoolValue(((CIntValue *) val)->GetInt() != m_int);
158                                 break;
159                         case VALUE_GRE_OPERATOR:
160                                 ret = new CBoolValue(((CIntValue *) val)->GetInt() > m_int);
161                                 break;
162                         case VALUE_LES_OPERATOR:
163                                 ret = new CBoolValue(((CIntValue *) val)->GetInt() < m_int);
164                                 break;
165                         case VALUE_GEQ_OPERATOR:
166                                 ret = new CBoolValue(((CIntValue *) val)->GetInt() >= m_int);
167                                 break;
168                         case VALUE_LEQ_OPERATOR:
169                                 ret = new CBoolValue(((CIntValue *) val)->GetInt() <= m_int);
170                                 break;
171                         case VALUE_NEG_OPERATOR:
172                                 ret = new CIntValue (-m_int);
173                                 break;
174                         case VALUE_POS_OPERATOR:
175                                 ret = new CIntValue (m_int);
176                                 break;
177                         default:
178                                 ret = new CErrorValue("illegal operator. please send a bug report.");
179                                 break;
180                         }
181                         break;
182                 }
183         case VALUE_FLOAT_TYPE:
184                 {
185                         switch (op) {
186                         case VALUE_MOD_OPERATOR:
187                                 ret = new CFloatValue(fmod(((CFloatValue *) val)->GetFloat(), m_int));
188                                 break;
189                         case VALUE_ADD_OPERATOR:
190                                 ret = new CFloatValue (((CFloatValue *) val)->GetFloat() + m_int);
191                                 break;
192                         case VALUE_SUB_OPERATOR:
193                                 ret = new CFloatValue (((CFloatValue *) val)->GetFloat() - m_int);
194                                 break;
195                         case VALUE_MUL_OPERATOR:
196                                 ret = new CFloatValue (((CFloatValue *) val)->GetFloat() * m_int);
197                                 break;
198                         case VALUE_DIV_OPERATOR:
199                                 if (m_int == 0)
200                                         ret = new CErrorValue("Division by zero");
201                                 else
202                                         ret = new CFloatValue (((CFloatValue *) val)->GetFloat() / m_int);
203                                 break;
204                         case VALUE_EQL_OPERATOR:
205                                 ret = new CBoolValue(((CFloatValue *) val)->GetFloat() == m_int);
206                                 break;
207                         case VALUE_NEQ_OPERATOR:
208                                 ret = new CBoolValue(((CFloatValue *) val)->GetFloat() != m_int);
209                                 break;
210                         case VALUE_GRE_OPERATOR:
211                                 ret = new CBoolValue(((CFloatValue *) val)->GetFloat() > m_int);
212                                 break;
213                         case VALUE_LES_OPERATOR:
214                                 ret = new CBoolValue(((CFloatValue *) val)->GetFloat() < m_int);
215                                 break;
216                         case VALUE_GEQ_OPERATOR:
217                                 ret = new CBoolValue(((CFloatValue *) val)->GetFloat() >= m_int);
218                                 break;
219                         case VALUE_LEQ_OPERATOR:
220                                 ret = new CBoolValue(((CFloatValue *) val)->GetFloat() <= m_int);
221                                 break;
222                         default:
223                                 ret = new CErrorValue("illegal operator. please send a bug report.");
224                                 break;
225                         }
226                         break;
227                 }
228         case VALUE_STRING_TYPE:
229                 {
230                         switch(op) {
231                         case VALUE_ADD_OPERATOR:
232                                 ret = new CStringValue(val->GetText() + GetText(),"");
233                                 break;
234                         case VALUE_EQL_OPERATOR:
235                         case VALUE_NEQ_OPERATOR:
236                         case VALUE_GRE_OPERATOR:
237                         case VALUE_LES_OPERATOR:
238                         case VALUE_GEQ_OPERATOR:
239                         case VALUE_LEQ_OPERATOR:
240                                 ret = new CErrorValue("[Cannot compare string with integer]" + op2str(op) + GetText());
241                                 break;
242                         default:
243                                 ret =  new CErrorValue("[operator not allowed on strings]" + op2str(op) + GetText());
244                                 break;
245                         }
246                         break;
247                 }
248         case VALUE_BOOL_TYPE:
249                 ret =  new CErrorValue("[operator not valid on boolean and integer]" + op2str(op) + GetText());
250                 break;
251                 /*
252                 case VALUE_EMPTY_TYPE:
253                 {
254                 switch(op) {
255                 
256                   case VALUE_ADD_OPERATOR:
257                   ret = new CIntValue (m_int);
258                   break;
259                   case VALUE_SUB_OPERATOR:
260                   ret = new CIntValue (-m_int);
261                   break;
262                   default:
263                   {
264                   ret = new CErrorValue(op2str(op) +    GetText());
265                   }
266                   }
267                   break;
268                   }
269                 */
270         case VALUE_ERROR_TYPE:
271                 ret = new CErrorValue(val->GetText() + op2str(op) +     GetText());
272                 break;
273         default:
274                 ret = new CErrorValue("illegal type. contact your dealer (if any)");
275                 break;
276         }
277         return ret;
278 }
279
280
281
282 cInt CIntValue::GetInt()
283 /*
284 pre:
285 ret: the cInt stored in the object
286 */
287 {
288         return m_int;
289 }
290
291
292
293 double CIntValue::GetNumber()
294 {
295         return (float) m_int;
296 }
297
298
299
300 const STR_String & CIntValue::GetText()
301 {
302         if (!m_pstrRep)
303                 m_pstrRep=new STR_String();
304         m_pstrRep->Format("%lld",m_int);
305         
306         return *m_pstrRep;
307 }
308
309
310
311 CValue* CIntValue::GetReplica() { 
312         CIntValue* replica = new CIntValue(*this);
313         replica->ProcessReplica();
314         replica->m_pstrRep = NULL;
315         
316         return replica;
317 }
318
319
320
321 void CIntValue::SetValue(CValue* newval)
322 {       
323         m_int = (cInt)newval->GetNumber(); 
324         SetModified(true);
325 }
326
327
328 #ifdef WITH_PYTHON
329 PyObject* CIntValue::ConvertValueToPython()
330 {
331         if((m_int > INT_MIN) && (m_int < INT_MAX))
332                 return PyLong_FromSsize_t(m_int);
333         else
334                 return PyLong_FromLongLong(m_int);
335 }
336 #endif // WITH_PYTHON