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