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