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