1a09123c107a3742dead9ba3e020e1d5ae825b5e
[blender.git] / source / gameengine / Expressions / Value.cpp
1 // Value.cpp: implementation of the CValue class.
2 // developed at Eindhoven University of Technology, 1997
3 // by the OOPS team
4 //////////////////////////////////////////////////////////////////////
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 "Value.h"
19 #include "FloatValue.h"
20 #include "IntValue.h"
21 #include "VectorValue.h"
22 #include "VoidValue.h"
23 #include "StringValue.h"
24 #include "ErrorValue.h"
25 #include "ListValue.h"
26
27 #ifdef HAVE_CONFIG_H
28 #include <config.h>
29 #endif
30
31 //////////////////////////////////////////////////////////////////////
32 // Construction/Destruction
33 //////////////////////////////////////////////////////////////////////
34
35 double CValue::m_sZeroVec[3] = {0.0,0.0,0.0};
36
37 #ifndef NO_EXP_PYTHON_EMBEDDING
38
39 PyObject* cvalue_add(PyObject*v, PyObject*w)
40 {
41         return  ((CValue*)v)->Calc(VALUE_ADD_OPERATOR,(CValue*)w);
42 }
43 PyObject* cvalue_sub(PyObject*v, PyObject*w)
44 {
45         return  ((CValue*)v)->Calc(VALUE_SUB_OPERATOR,(CValue*)w);
46 }
47 PyObject* cvalue_mul(PyObject*v, PyObject*w)
48 {
49         return  ((CValue*)v)->Calc(VALUE_MUL_OPERATOR,(CValue*)w);
50 }
51 PyObject* cvalue_div(PyObject*v, PyObject*w)
52 {
53         return  ((CValue*)v)->Calc(VALUE_DIV_OPERATOR,(CValue*)w);
54 }
55 PyObject* cvalue_neg(PyObject*v)
56 {
57         return  ((CValue*)v)->Calc(VALUE_NEG_OPERATOR,(CValue*)v);
58 }
59 PyObject* cvalue_pos(PyObject*v)
60 {
61         return  ((CValue*)v)->Calc(VALUE_POS_OPERATOR,(CValue*)v);
62 }
63
64
65 int MyPyCompare (PyObject* v,PyObject* w)
66 {
67         CValue* eqval =  ((CValue*)v)->Calc(VALUE_EQL_OPERATOR,(CValue*)w);
68         STR_String txt = eqval->GetText();
69         eqval->Release();
70         if (txt=="TRUE")
71                 return 0;
72         CValue* lessval =  ((CValue*)v)->Calc(VALUE_LES_OPERATOR,(CValue*)w);
73         txt = lessval->GetText();
74         lessval->Release();
75         if (txt=="TRUE")
76                 return -1;
77
78         return 1;
79 }
80
81
82 int cvalue_coerce(PyObject** pv,PyObject** pw)
83 {
84         if (PyInt_Check(*pw)) {
85                 double db  = (double)PyInt_AsLong(*pw);
86                 *pw = new CIntValue((int) db);
87                 Py_INCREF(*pv);
88                 return 0;
89         }
90         else if (PyLong_Check(*pw)) {
91                 double db = PyLong_AsDouble(*pw);
92                 *pw = new CFloatValue(db);
93                 Py_INCREF(*pv);
94                 return 0;
95         }
96         else if (PyFloat_Check(*pw)) {
97                 double db = PyFloat_AsDouble(*pw);
98                 *pw = new CFloatValue(db);
99                 Py_INCREF(*pv);
100                 return 0;
101         } else if (PyString_Check(*pw)) {
102                 const STR_String str = PyString_AsString(*pw);
103                 *pw = new CStringValue(str,"");
104                 Py_INCREF(*pv);
105                 return 0;
106         }
107         return 1; /* Can't do it */
108
109 }
110 static PyNumberMethods cvalue_as_number = {
111         (binaryfunc)cvalue_add, /*nb_add*/
112         (binaryfunc)cvalue_sub, /*nb_subtract*/
113         (binaryfunc)cvalue_mul, /*nb_multiply*/
114         (binaryfunc)cvalue_div, /*nb_divide*/
115         0,//(binaryfunc)cvalue_remainder,       /*nb_remainder*/
116         0,//(binaryfunc)cvalue_divmod,  /*nb_divmod*/
117         0,//0,//0,//0,//(ternaryfunc)cvalue_pow, /*nb_power*/
118         (unaryfunc)cvalue_neg, /*nb_negative*/
119         0,//(unaryfunc)cvalue_pos, /*nb_positive*/
120         0,//(unaryfunc)cvalue_abs, /*nb_absolute*/
121         0,//(inquiry)cvalue_nonzero, /*nb_nonzero*/
122         0,              /*nb_invert*/
123         0,              /*nb_lshift*/
124         0,              /*nb_rshift*/
125         0,              /*nb_and*/
126         0,              /*nb_xor*/
127         0,              /*nb_or*/
128         (coercion)cvalue_coerce, /*nb_coerce*/
129         0,//(unaryfunc)cvalue_int, /*nb_int*/
130         0,//(unaryfunc)cvalue_long, /*nb_long*/
131         0,//(unaryfunc)cvalue_float, /*nb_float*/
132         0,              /*nb_oct*/
133         0,              /*nb_hex*/
134 };
135
136
137 PyTypeObject CValue::Type = {
138         PyObject_HEAD_INIT(&PyType_Type)
139         0,
140         "CValue",
141         sizeof(CValue),
142         0,
143         PyDestructor,
144         0,
145         __getattr,
146         __setattr,
147         &MyPyCompare,
148         __repr,
149         &cvalue_as_number,
150         0,
151         0,
152         0,
153         0
154 };
155
156 PyParentObject CValue::Parents[] = {
157         &CValue::Type,
158                 NULL
159 };
160
161 PyMethodDef CValue::Methods[] = {
162 //      { "printHello", (PyCFunction) CValue::sPyPrintHello, Py_NEWARGS},
163         { "getName", (PyCFunction) CValue::sPyGetName, Py_NEWARGS},
164         {NULL,NULL} //Sentinel
165 };
166
167 PyObject* CValue::PyGetName(PyObject* self,PyObject* args,PyObject* kwds)
168 {
169         PyObject* pyname = PyString_FromString(this->GetName());
170         return pyname;
171 }
172
173
174
175 CValue::CValue(PyTypeObject *T)
176                 : PyObjectPlus(T),
177 #else
178 CValue::CValue()
179
180 #endif //NO_EXP_PYTHON_EMBEDDING
181         
182 m_pNamedPropertyArray(NULL),
183 m_refcount(1)
184 /*
185 pre: false
186 effect: constucts a CValue
187 */
188 {
189         //debug(gRefCountValue++)       // debugging
190 }
191
192
193
194 CValue::~CValue()
195 /*
196 pre:
197 effect: deletes the object
198 */
199 {
200         ClearProperties();
201
202         assertd (m_refcount==0);
203 }
204
205
206
207
208 #define VALUE_SUB(val1, val2) (val1)->Calc(VALUE_SUB_OPERATOR, val2)
209 #define VALUE_MUL(val1, val2) (val1)->Calc(VALUE_MUL_OPERATOR, val2)
210 #define VALUE_DIV(val1, val2) (val1)->Calc(VALUE_DIV_OPERATOR, val2)
211 #define VALUE_NEG(val1)       (val1)->Calc(VALUE_NEG_OPERATOR, val1)
212 #define VALUE_POS(val1)       (val1)->Calc(VALUE_POS_OPERATOR, val1)
213
214
215 STR_String CValue::op2str (VALUE_OPERATOR op)
216 {
217         //pre:
218         //ret: the stringrepresentation of operator op
219         
220         STR_String opmsg;
221         switch (op) {
222         case VALUE_ADD_OPERATOR:
223                 opmsg = " + ";
224                 break;
225         case VALUE_SUB_OPERATOR:
226                 opmsg = " - ";
227                 break;
228         case VALUE_MUL_OPERATOR:
229                 opmsg = " * ";
230                 break;
231         case VALUE_DIV_OPERATOR:
232                 opmsg = " / ";
233                 break;
234         case VALUE_NEG_OPERATOR:
235                 opmsg = " -";
236                 break;
237         case VALUE_POS_OPERATOR:
238                 opmsg = " +";
239                 break;
240         case VALUE_AND_OPERATOR:
241                 opmsg = " & ";
242                 break;
243         case VALUE_OR_OPERATOR:
244                 opmsg = " | ";
245                 break;
246         case VALUE_EQL_OPERATOR:
247                 opmsg = " = ";
248                 break;
249         case VALUE_NEQ_OPERATOR:
250                 opmsg = " != ";
251                 break;
252         case VALUE_NOT_OPERATOR:
253                 opmsg = " !";
254                 break;
255         default:
256                 opmsg="Error in Errorhandling routine.";
257                 //              AfxMessageBox("Invalid operator");
258                 break;
259         }
260         return opmsg;
261 }
262
263
264
265
266
267 //---------------------------------------------------------------------------------------------------------------------
268 //      Property Management
269 //---------------------------------------------------------------------------------------------------------------------
270
271
272
273 //
274 // Set property <ioProperty>, overwrites and releases a previous property with the same name if needed
275 //
276 void CValue::SetProperty(const STR_String & name,CValue* ioProperty)
277 {
278         // Check if somebody is setting an empty property
279         if (ioProperty==NULL)
280         {
281                 trace("Warning:trying to set empty property!");
282                 return;
283         }
284
285         // Make sure we have a property array
286         if (m_pNamedPropertyArray == NULL)
287                 m_pNamedPropertyArray = new std::map<STR_String,CValue *>;
288
289         // Try to replace property (if so -> exit as soon as we replaced it)
290         CValue* oldval = (*m_pNamedPropertyArray)[name];
291         if (oldval)
292         {
293                 oldval->Release();
294         }
295         
296         // Add property at end of array
297         (*m_pNamedPropertyArray)[name] = ioProperty;//->Add(ioProperty);
298 }
299
300
301
302 //
303 // Get pointer to a property with name <inName>, returns NULL if there is no property named <inName>
304 //
305 CValue* CValue::GetProperty(const STR_String & inName)
306 {
307         // Check properties, as soon as we found it -> Return a pointer to the property
308         CValue* result = NULL;
309         if (m_pNamedPropertyArray)
310         {
311                 std::map<STR_String,CValue*>::iterator it = (*m_pNamedPropertyArray).find(inName);
312                 if (!( it==m_pNamedPropertyArray->end()))
313                 {
314                         result = (*it).second;
315                 }
316
317         }
318                 //for (int i=0; i<m_pValuePropertyArray->size(); i++)
319                 //      if ((*m_pValuePropertyArray)[i]->GetName() == inName)
320                 //              return (*m_pValuePropertyArray)[i];
321         
322         // Did not find property with name <inName>, return NULL property pointer
323         return result;
324 }
325
326
327
328 //
329 // Get text description of property with name <inName>, returns an empty string if there is no property named <inName>
330 //
331 STR_String CValue::GetPropertyText(const STR_String & inName,const STR_String& deftext)
332 {
333         CValue *property = GetProperty(inName);
334         if (property)
335                 return property->GetText();
336         else
337                 return deftext;//String::sEmpty;
338 }
339
340 float CValue::GetPropertyNumber(const STR_String& inName,float defnumber)
341 {
342         CValue *property = GetProperty(inName);
343         if (property)
344                 return property->GetNumber();
345         else
346                 return defnumber;
347 }
348
349
350
351 //
352 // Remove the property named <inName>, returns true if the property was succesfully removed, false if property was not found or could not be removed
353 //
354 bool CValue::RemoveProperty(const STR_String & inName)
355 {
356         // Check if there are properties at all which can be removed
357         if (m_pNamedPropertyArray == NULL)
358                 return false;
359
360         // Scan all properties, as soon as we find one with <inName> -> Remove it
361 //      CValue* val = (*m_pNamedPropertyArray)[inName];
362         if (m_pNamedPropertyArray->erase(inName)) return true;
363         
364         return false;
365 }
366
367
368
369 //
370 // Clear all properties
371 //
372 void CValue::ClearProperties()
373 {               
374         // Check if we have any properties
375         if (m_pNamedPropertyArray == NULL)
376                 return;
377
378         // Remove all properties
379         for ( std::map<STR_String,CValue*>::iterator it = m_pNamedPropertyArray->begin();
380         !(it == m_pNamedPropertyArray->end());it++)
381         {
382                 CValue* tmpval = (*it).second;
383                 STR_String name = (*it).first;
384                 tmpval->Release();
385         }
386
387         // Delete property array
388         delete m_pNamedPropertyArray;
389         m_pNamedPropertyArray=NULL;
390 }
391
392
393
394 //
395 // Set all properties' modified flag to <inModified>
396 //
397 void CValue::SetPropertiesModified(bool inModified)
398 {
399         int numprops = GetPropertyCount();
400         for (int i=0; i<numprops; i++)
401                 GetProperty(i)->SetModified(inModified);
402 }
403
404
405
406 //
407 // Check if any of the properties in this value have been modified
408 //
409 bool CValue::IsAnyPropertyModified()
410 {
411         int numprops = GetPropertyCount();
412         for (int i=0;i<numprops;i++)
413                 if (GetProperty(i)->IsModified())
414                         return true;
415
416         return false;
417 }
418
419
420
421 //
422 // Get property number <inIndex>
423 //
424
425 CValue* CValue::GetProperty(int inIndex)
426 {
427
428         int count=0;
429         CValue* result = NULL;
430
431         if (m_pNamedPropertyArray)
432         {
433                 for ( std::map<STR_String,CValue*>::iterator it = m_pNamedPropertyArray->begin();
434                 !(it == m_pNamedPropertyArray->end());it++)
435                 {
436                         if (count++==inIndex)
437                         {
438                                 result = (*it).second;
439                                 break;
440                         }
441                 }
442
443         }
444         return result;
445 }
446
447
448
449 //
450 // Get the amount of properties assiocated with this value
451 //
452 int CValue::GetPropertyCount()
453 {
454         if (m_pNamedPropertyArray)
455                 return m_pNamedPropertyArray->size();
456         else
457                 return 0;
458 }
459
460
461
462
463
464 void CValue::CloneProperties(CValue *replica)
465 {
466         
467         if (m_pNamedPropertyArray)
468         {
469                 replica->m_pNamedPropertyArray=NULL;
470                 for ( std::map<STR_String,CValue*>::iterator it = m_pNamedPropertyArray->begin();
471                 !(it == m_pNamedPropertyArray->end());it++)
472                 {
473                         
474                         replica->SetProperty((*it).first,(*it).second->GetReplica());
475                 }
476         }
477
478         
479 }
480
481
482
483
484
485
486 double*         CValue::GetVector3(bool bGetTransformedVec)
487 {
488         assertd(false); // don;t get vector from me
489         return m_sZeroVec;//::sZero;
490 }
491
492
493
494
495
496
497 /*---------------------------------------------------------------------------------------------------------------------
498         Reference Counting
499 ---------------------------------------------------------------------------------------------------------------------*/
500
501
502
503 //
504 // Add a reference to this value
505 //
506 CValue *CValue::AddRef()
507 {
508         // Increase global reference count, used to see at the end of the program
509         // if all CValue-derived classes have been dereferenced to 0
510         //debug(gRefCountValue++);
511         m_refcount++; 
512         return this;
513 }
514
515
516
517 //
518 // Release a reference to this value (when reference count reaches 0, the value is removed from the heap)
519 //
520 int     CValue::Release()
521 {
522         // Decrease global reference count, used to see at the end of the program
523         // if all CValue-derived classes have been dereferenced to 0
524         //debug(gRefCountValue--);
525
526         // Decrease local reference count, if it reaches 0 the object should be freed
527         if (--m_refcount > 0)
528         {
529                 // Reference count normal, return new reference count
530                 return m_refcount;
531         }
532         else
533         {
534                 // Reference count reached 0, delete ourselves and return 0
535 //              MT_assert(m_refcount==0, "Reference count reached sub-zero, object released too much");
536                 delete this;
537                 return 0;
538         }
539
540 }
541
542
543
544 //
545 // Disable reference counting for this value
546 //
547 void CValue::DisableRefCount()
548 {
549         assertd(m_refcount == 1);
550         m_refcount--;
551
552         //debug(gRefCountValue--);
553         m_ValFlags.RefCountDisabled=true;
554 }
555
556
557
558 void CValue::AddDataToReplica(CValue *replica)
559 {
560         replica->m_refcount = 1;
561 #ifdef _DEBUG
562         //gRefCountValue++;
563 #endif
564         replica->m_ValFlags.RefCountDisabled = false;
565
566         replica->ReplicaSetName(GetName());
567
568         //copy all props
569         CloneProperties(replica);
570 }
571
572
573
574 CValue* CValue::FindIdentifier(const STR_String& identifiername)
575 {
576
577         CValue* result = NULL;
578
579         int pos = 0;
580         // if a dot exists, explode the name into pieces to get the subcontext
581         if ((pos=identifiername.Find('.'))>=0)
582         {
583                 const STR_String rightstring = identifiername.Right(identifiername.Length() -1 - pos);
584                 const STR_String leftstring = identifiername.Left(pos);
585                 CValue* tempresult = GetProperty(leftstring);
586                 if (tempresult)
587                 {
588                         result=tempresult->FindIdentifier(rightstring);
589                 } 
590         } else
591         {
592                 result = GetProperty(identifiername);
593         }
594         if (result)
595                 return result->AddRef();
596         // warning here !!!
597         result = new CErrorValue(identifiername+" not found");
598         return result;
599 }
600
601
602 #ifndef NO_EXP_PYTHON_EMBEDDING
603
604
605 static PyMethodDef      CValueMethods[] = 
606 {
607         //{ "new", CValue::PyMake , Py_NEWARGS},
608         { NULL,NULL}    // Sentinel
609 };
610
611
612 PyObject*       CValue::_getattr(const STR_String& attr)
613 {
614         CValue* resultattr = FindIdentifier(attr);
615         STR_String text;
616         if (resultattr)
617         {
618                 if (resultattr->IsError())
619                 {
620                         resultattr->Release();
621                 } else
622                 {
623                         // to avoid some compare problems, return a real pythonthing
624                         PyObject* pyconvert = resultattr->ConvertValueToPython();
625                         if (pyconvert)
626                         {
627                                 resultattr->Release();
628                                 return pyconvert;
629                         } else
630                         {
631                                 // also check if it's already in pythoninterpreter!
632                                 return resultattr;
633                         }
634                         
635                 }
636         }
637         _getattr_up(PyObjectPlus);
638 }
639
640 CValue* CValue::ConvertPythonToValue(PyObject* pyobj)
641 {
642
643         CValue* vallie = NULL;
644
645         PyTypeObject* type = pyobj->ob_type;
646
647         if (type == &PyList_Type)
648         {
649                 CListValue* listval = new CListValue();
650                 bool error = false;
651
652                 int i;
653                 int numitems = PyList_Size(pyobj);
654                 for (i=0;i<numitems;i++)
655                 {
656                         PyObject* listitem = PyList_GetItem(pyobj,i); /* borrowed ref */
657                         CValue* listitemval = ConvertPythonToValue(listitem);
658                         if (listitemval)
659                         {
660                                 listval->Add(listitemval);
661                         } else
662                         {
663                                 error = true;
664                         }
665                 }
666                 if (!error)
667                 {
668                         // jippie! could be converted
669                         vallie = listval;
670                 } else
671                 {
672                         // list could not be converted... bad luck
673                         listval->Release();
674                 }
675
676         } else
677         if (type == &PyFloat_Type)
678         {
679                 float fl;
680                 PyArg_Parse(pyobj,"f",&fl);
681                 vallie = new CFloatValue(fl);
682         } else
683         if (type==&PyInt_Type)
684         {
685                 int innie;
686                 PyArg_Parse(pyobj,"i",&innie);
687                 vallie = new CIntValue(innie);
688         } else
689         
690         if (type==&PyString_Type)
691         {
692                 vallie = new CStringValue(PyString_AsString(pyobj),"");
693         } else
694         if (type==&CValue::Type || type==&CListValue::Type)
695         {
696                 vallie = ((CValue*) pyobj)->AddRef();
697         }
698         return vallie;
699
700 }
701
702 int     CValue::_delattr(const STR_String& attr)
703 {
704         RemoveProperty(attr);
705         return 0;
706 }
707
708 int     CValue::_setattr(const STR_String& attr,PyObject* pyobj)
709 {
710         CValue* vallie = ConvertPythonToValue(pyobj);
711         if (vallie)
712         {
713                 CValue* oldprop = GetProperty(attr);
714                 
715                 if (oldprop)
716                 {
717                         oldprop->SetValue(vallie);
718                 } else
719                 {
720                         SetProperty(attr,vallie->AddRef());
721                 }
722                 vallie->Release();
723         }
724         
725         //PyObjectPlus::_setattr(attr,value);
726         return 0;
727 };
728 /*
729 PyObject*       CValue::PyMake(PyObject* ignored,PyObject* args)
730 {
731
732         //Py_Try(PyArg_ParseTuple(args,"s",&name));
733         Py_INCREF(Py_None);
734         return Py_None;//new CValue();
735 }
736 */
737
738 extern "C" {
739         void initCValue(void)
740         {
741                 Py_InitModule("CValue",CValueMethods);
742         }
743 }
744
745
746
747 #endif //NO_EXP_PYTHON_EMBEDDING
748
749 ///////////////////////////////////////////////////////////////////////////////////////////////
750 ///////////////////////////////////////////////////////////////////////////////////////////////
751 /* These implementations were moved out of the header */
752
753 void CValue::SetOwnerExpression(class CExpression* expr)
754 {
755         /* intentionally empty */
756 }
757
758 void CValue::SetColorOperator(VALUE_OPERATOR op)
759 {
760         /* intentionally empty */
761 }
762 void CValue::SetValue(CValue* newval)
763
764         // no one should get here
765         assertd(newval->GetNumber() == 10121969);       
766 }
767 ///////////////////////////////////////////////////////////////////////////////////////////////
768 ///////////////////////////////////////////////////////////////////////////////////////////////
769