svn merge -r 21041:21243 https://svn.blender.org/svnroot/bf-blender/branches/blender2...
[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 #include "FloatValue.h"
16 #include "IntValue.h"
17 #include "StringValue.h"
18 #include "BoolValue.h"
19 #include "ErrorValue.h"
20 #include "VoidValue.h"
21
22 #ifdef HAVE_CONFIG_H
23 #include <config.h>
24 #endif
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,const char *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_MOD_OPERATOR:
131                                 ret = new CFloatValue(fmod(((CIntValue *) val)->GetInt(), m_float));
132                                 break;
133                         case VALUE_ADD_OPERATOR:
134                                 ret = new CFloatValue(((CIntValue *) val)->GetInt() + m_float);
135                                 break;
136                         case VALUE_SUB_OPERATOR:
137                                 ret = new CFloatValue(((CIntValue *) val)->GetInt() - m_float);
138                                 break;
139                         case VALUE_MUL_OPERATOR:
140                                 ret = new CFloatValue(((CIntValue *) val)->GetInt() * m_float);
141                                 break;
142                         case VALUE_DIV_OPERATOR:
143                                 if (m_float == 0)
144                                         ret = new CErrorValue("Division by zero");
145                                 else
146                                         ret = new CFloatValue (((CIntValue *) val)->GetInt() / m_float);
147                                 break;
148                         case VALUE_EQL_OPERATOR:
149                                 ret = new CBoolValue(((CIntValue *) val)->GetInt() == m_float);
150                                 break;
151                         case VALUE_NEQ_OPERATOR:
152                                 ret = new CBoolValue(((CIntValue *) val)->GetInt() != m_float);
153                                 break;
154                         case VALUE_GRE_OPERATOR:
155                                 ret = new CBoolValue(((CIntValue *) val)->GetInt() > m_float);
156                                 break;
157                         case VALUE_LES_OPERATOR:
158                                 ret = new CBoolValue(((CIntValue *) val)->GetInt() < m_float);
159                                 break;
160                         case VALUE_GEQ_OPERATOR:
161                                 ret = new CBoolValue(((CIntValue *) val)->GetInt() >= m_float);
162                                 break;
163                         case VALUE_LEQ_OPERATOR:
164                                 ret = new CBoolValue(((CIntValue *) val)->GetInt() <= m_float);
165                                 break;
166                         default:
167                                 ret = new CErrorValue("illegal operator. please send a bug report.");
168                                 break;
169                         }
170                         break;
171                 }
172         case VALUE_EMPTY_TYPE:
173         case VALUE_FLOAT_TYPE:
174                 {
175                         switch (op)
176                         {
177                         case VALUE_MOD_OPERATOR:
178                                 ret = new CFloatValue(fmod(((CFloatValue *) val)->GetFloat(), m_float));
179                                 break;
180                         case VALUE_ADD_OPERATOR:
181                                 ret = new CFloatValue(((CFloatValue *) val)->GetFloat() + m_float);
182                                 break;
183                         case VALUE_SUB_OPERATOR:
184                                 ret = new CFloatValue(((CFloatValue *) val)->GetFloat() - m_float);
185                                 break;
186                         case VALUE_MUL_OPERATOR:
187                                 ret = new CFloatValue(((CFloatValue *) val)->GetFloat() * m_float);
188                                 break;
189                         case VALUE_DIV_OPERATOR:
190                                 if (m_float == 0)
191                                         ret = new CErrorValue("Division by zero");
192                                 else
193                                         ret = new CFloatValue (((CFloatValue *) val)->GetFloat() / m_float);
194                                 break;
195                         case VALUE_EQL_OPERATOR:
196                                 ret = new CBoolValue(((CFloatValue *) val)->GetFloat() == m_float);
197                                 break;
198                         case VALUE_NEQ_OPERATOR:
199                                 ret = new CBoolValue(((CFloatValue *) val)->GetFloat() != m_float);
200                                 break;
201                         case VALUE_GRE_OPERATOR:
202                                 ret = new CBoolValue(((CFloatValue *) val)->GetFloat() > m_float);
203                                 break;
204                         case VALUE_LES_OPERATOR:
205                                 ret = new CBoolValue(((CFloatValue *) val)->GetFloat() < m_float);
206                                 break;
207                         case VALUE_GEQ_OPERATOR:
208                                 ret = new CBoolValue(((CFloatValue *) val)->GetFloat() >= m_float);
209                                 break;
210                         case VALUE_LEQ_OPERATOR:
211                                 ret = new CBoolValue(((CFloatValue *) val)->GetFloat() <= m_float);
212                                 break;
213                         case VALUE_NEG_OPERATOR:
214                                 ret = new CFloatValue (-m_float);
215                                 break;
216                         case VALUE_POS_OPERATOR:
217                                 ret = new CFloatValue (m_float);
218                                 break;
219                                 
220                         default:
221                                 ret = new CErrorValue("illegal operator. please send a bug report.");
222                                 break;
223                         }
224                         break;
225                 }
226         case VALUE_STRING_TYPE:
227                 {
228                         switch(op)
229                         {
230                         case VALUE_ADD_OPERATOR:
231                                 ret = new CStringValue(val->GetText() + GetText(),"");
232                                 break;
233                         case VALUE_EQL_OPERATOR:
234                         case VALUE_NEQ_OPERATOR:
235                         case VALUE_GRE_OPERATOR:
236                         case VALUE_LES_OPERATOR:
237                         case VALUE_GEQ_OPERATOR:
238                         case VALUE_LEQ_OPERATOR:
239                                 ret = new CErrorValue("[Cannot compare string with float]" + op2str(op) + GetText());
240                                 break;
241                         default:
242                                 ret =  new CErrorValue("[operator not allowed on strings]" + op2str(op) + GetText());
243                                 break;
244                         }
245                         break;
246                 }
247         case VALUE_BOOL_TYPE:
248                 ret =  new CErrorValue("[operator not valid on boolean and float]" + op2str(op) + GetText());
249                 break;
250         case VALUE_ERROR_TYPE:
251                 ret = new CErrorValue(val->GetText() + op2str(op) + GetText());
252                 break;
253         default:
254                 ret = new CErrorValue("illegal type. contact your dealer (if any)");
255                 break;
256         }
257         return ret;
258 }
259
260
261
262 void CFloatValue::SetFloat(float fl)
263 {
264         m_float = fl;
265         SetModified(true);
266 }
267
268
269
270 float CFloatValue::GetFloat()
271 /*
272 pre:
273 ret: the float stored in the object
274 */
275 {
276         return m_float;
277 }
278
279
280
281 double CFloatValue::GetNumber()
282 {
283         return m_float;
284 }
285
286
287
288 void CFloatValue::SetValue(CValue* newval)
289 {       
290         m_float = (float)newval->GetNumber(); 
291         SetModified(true);
292 }
293
294
295
296 const STR_String & CFloatValue::GetText()
297 {
298         if (!m_pstrRep)
299                 m_pstrRep = new STR_String();
300
301         m_pstrRep->Format("%f",m_float);
302         return *m_pstrRep;
303 }
304
305
306
307 CValue* CFloatValue::GetReplica()
308
309         CFloatValue* replica = new CFloatValue(*this);
310         replica->m_pstrRep = NULL; /* should be in CFloatValue::ProcessReplica() but its not defined, no matter */
311         replica->ProcessReplica();
312
313         return replica;
314 }
315
316
317
318 PyObject* CFloatValue::ConvertValueToPython()
319 {
320         return PyFloat_FromDouble(m_float);
321 }
322