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