00001
00002
00003
00005
00006 * Copyright (c) 1996-2000 Erwin Coumans <[email protected]>
00007 *
00008 * Permission to use, copy, modify, distribute and sell this software
00009 * and its documentation for any purpose is hereby granted without fee,
00010 * provided that the above copyright notice appear in all copies and
00011 * that both that copyright notice and this permission notice appear
00012 * in supporting documentation. Erwin Coumans makes no
00013 * representations about the suitability of this software for any
00014 * purpose. It is provided "as is" without express or implied warranty.
00015 *
00016 */
00017
00018
00019 #include "Value.h"
00020 #include "FloatValue.h"
00021 #include "IntValue.h"
00022 #include "VectorValue.h"
00023 #include "VoidValue.h"
00024 #include "StringValue.h"
00025 #include "ErrorValue.h"
00026 #include "ListValue.h"
00027
00028
00029
00031
00033
00034 double CValue::m_sZeroVec[3] = {0.0,0.0,0.0};
00035
00036 #ifndef NO_EXP_PYTHON_EMBEDDING
00037
00038 PyObject* cvalue_add(PyObject*v, PyObject*w)
00039 {
00040 return ((CValue*)v)->Calc(VALUE_ADD_OPERATOR,(CValue*)w);
00041 }
00042 PyObject* cvalue_sub(PyObject*v, PyObject*w)
00043 {
00044 return ((CValue*)v)->Calc(VALUE_SUB_OPERATOR,(CValue*)w);
00045 }
00046 PyObject* cvalue_mul(PyObject*v, PyObject*w)
00047 {
00048 return ((CValue*)v)->Calc(VALUE_MUL_OPERATOR,(CValue*)w);
00049 }
00050 PyObject* cvalue_div(PyObject*v, PyObject*w)
00051 {
00052 return ((CValue*)v)->Calc(VALUE_DIV_OPERATOR,(CValue*)w);
00053 }
00054 PyObject* cvalue_neg(PyObject*v)
00055 {
00056 return ((CValue*)v)->Calc(VALUE_NEG_OPERATOR,(CValue*)v);
00057 }
00058
00059 int MyPyCompare (PyObject* v,PyObject* w)
00060 {
00061 CValue* eqval = ((CValue*)v)->Calc(VALUE_EQL_OPERATOR,(CValue*)w);
00062 CCString txt = eqval->GetText();
00063 eqval->Release();
00064 if (txt=="TRUE")
00065 return 0;
00066 CValue* lessval = ((CValue*)v)->Calc(VALUE_LES_OPERATOR,(CValue*)w);
00067 txt = lessval->GetText();
00068 lessval->Release();
00069 if (txt=="TRUE")
00070 return -1;
00071
00072 return 1;
00073 }
00074
00075
00076 int cvalue_coerce(PyObject** pv,PyObject** pw)
00077 {
00078 if (PyInt_Check(*pw)) {
00079 double db = (double)PyInt_AsLong(*pw);
00080 *pw = new CIntValue(db);
00081 Py_INCREF(*pv);
00082 return 0;
00083 }
00084 else if (PyLong_Check(*pw)) {
00085 double db = PyLong_AsDouble(*pw);
00086 *pw = new CFloatValue(db);
00087 Py_INCREF(*pv);
00088 return 0;
00089 }
00090 else if (PyFloat_Check(*pw)) {
00091 double db = PyFloat_AsDouble(*pw);
00092 *pw = new CFloatValue(db);
00093 Py_INCREF(*pv);
00094 return 0;
00095 } else if (PyString_Check(*pw)) {
00096 const CCString str = PyString_AsString(*pw);
00097 *pw = new CStringValue(str,"");
00098 Py_INCREF(*pv);
00099 return 0;
00100 }
00101 return 1;
00102
00103 }
00104 static PyNumberMethods cvalue_as_number = {
00105 (binaryfunc)cvalue_add,
00106 (binaryfunc)cvalue_sub,
00107 (binaryfunc)cvalue_mul,
00108 (binaryfunc)cvalue_div,
00109 0,
00110 0,
00111 0,
00112 (unaryfunc)cvalue_neg,
00113 0,
00114 0,
00115 0,
00116 0,
00117 0,
00118 0,
00119 0,
00120 0,
00121 0,
00122 (coercion)cvalue_coerce,
00123 0,
00124 0,
00125 0,
00126 0,
00127 0,
00128 };
00129
00130
00131 PyTypeObject CValue::Type = {
00132 PyObject_HEAD_INIT(&PyType_Type)
00133 0,
00134 "CValue",
00135 sizeof(CValue),
00136 0,
00137 PyDestructor,
00138 0,
00139 __getattr,
00140 __setattr,
00141 &MyPyCompare,
00142 __repr,
00143 &cvalue_as_number,
00144 0,
00145 0,
00146 0,
00147 0
00148 };
00149
00150 PyParentObject CValue::Parents[] = {
00151 &CValue::Type,
00152 NULL
00153 };
00154
00155 PyMethodDef CValue::Methods[] = {
00156 { "printHello", (PyCFunction) CValue::sPyPrintHello, Py_NEWARGS},
00157 { "getName", (PyCFunction) CValue::sPyGetName, Py_NEWARGS},
00158 {NULL,NULL}
00159 };
00160
00161 PyObject* CValue::PyGetName(PyObject* self,PyObject* args,PyObject* kwds)
00162 {
00163 PyObject* pyname = PyString_FromString(this->GetName());
00164 return pyname;
00165 }
00166
00167
00168
00169 CValue::CValue(PyTypeObject *T)
00170 : PyObjectPlus(T),
00171 #else
00172 CValue::CValue()
00173 :
00174 #endif //NO_EXP_PYTHON_EMBEDDING
00175
00176 m_refcount(1),
00177 m_pNamedPropertyArray(NULL)
00178
00179
00180
00181
00182 {
00183
00184 }
00185
00186
00187
00188 CValue::~CValue()
00189
00190
00191
00192
00193 {
00194 ClearProperties();
00195
00196 assertd (m_refcount==0);
00197 }
00198
00199
00200
00201
00202 #define VALUE_SUB(val1, val2) (val1)->Calc(VALUE_SUB_OPERATOR, val2)
00203 #define VALUE_MUL(val1, val2) (val1)->Calc(VALUE_MUL_OPERATOR, val2)
00204 #define VALUE_DIV(val1, val2) (val1)->Calc(VALUE_DIV_OPERATOR, val2)
00205 #define VALUE_NEG(val1) (val1)->Calc(VALUE_NEG_OPERATOR, val1)
00206
00207
00208 CCString CValue::op2str (VALUE_OPERATOR op)
00209 {
00210
00211
00212
00213 CCString opmsg;
00214 switch (op) {
00215 case VALUE_ADD_OPERATOR:
00216 opmsg = " + ";
00217 break;
00218 case VALUE_SUB_OPERATOR:
00219 opmsg = " - ";
00220 break;
00221 case VALUE_MUL_OPERATOR:
00222 opmsg = " * ";
00223 break;
00224 case VALUE_DIV_OPERATOR:
00225 opmsg = " / ";
00226 break;
00227 case VALUE_NEG_OPERATOR:
00228 opmsg = " -";
00229 break;
00230 case VALUE_AND_OPERATOR:
00231 opmsg = " & ";
00232 break;
00233 case VALUE_OR_OPERATOR:
00234 opmsg = " | ";
00235 break;
00236 case VALUE_EQL_OPERATOR:
00237 opmsg = " = ";
00238 break;
00239 case VALUE_NEQ_OPERATOR:
00240 opmsg = " != ";
00241 break;
00242 case VALUE_NOT_OPERATOR:
00243 opmsg = " !";
00244 break;
00245 default:
00246 opmsg="Error in Errorhandling routine.";
00247
00248 break;
00249 }
00250 return opmsg;
00251 }
00252
00253
00254
00255
00256
00257
00258
00259
00260
00261
00262
00263
00264
00265
00266 void CValue::SetProperty(const CCString & name,CValue* ioProperty)
00267 {
00268
00269 if (ioProperty==NULL)
00270 {
00271 trace("Warning:trying to set empty property!");
00272 return;
00273 }
00274
00275
00276 if (m_pNamedPropertyArray == NULL)
00277 m_pNamedPropertyArray = new std::map<const CCString,CValue *>;
00278
00279
00280 CValue* oldval = (*m_pNamedPropertyArray)[name];
00281 if (oldval)
00282 {
00283 oldval->Release();
00284 }
00285
00286
00287 (*m_pNamedPropertyArray)[name] = ioProperty;
00288 }
00289
00290
00291
00292
00293
00294
00295 CValue* CValue::GetProperty(const CCString & inName)
00296 {
00297
00298 CValue* result = NULL;
00299 if (m_pNamedPropertyArray)
00300 {
00301 std::map<const CCString,CValue*>::iterator it = (*m_pNamedPropertyArray).find(inName);
00302 if (!( it==m_pNamedPropertyArray->end()))
00303 {
00304 result = (*it).second;
00305 }
00306
00307 }
00308
00309
00310
00311
00312
00313 return result;
00314 }
00315
00316
00317
00318
00319
00320
00321 CCString CValue::GetPropertyText(const CCString & inName,const CCString& deftext)
00322 {
00323 CValue *property = GetProperty(inName);
00324 if (property)
00325 return property->GetText();
00326 else
00327 return deftext;
00328 }
00329
00330 float CValue::GetPropertyNumber(const CCString& inName,float defnumber)
00331 {
00332 CValue *property = GetProperty(inName);
00333 if (property)
00334 return property->GetNumber();
00335 else
00336 return defnumber;
00337 }
00338
00339
00340
00341
00342
00343
00344 bool CValue::RemoveProperty(const CCString & inName)
00345 {
00346
00347 if (m_pNamedPropertyArray == NULL)
00348 return false;
00349
00350
00351 CValue* val = (*m_pNamedPropertyArray)[inName];
00352
00353 return false;
00354 }
00355
00356
00357
00358
00359
00360
00361 void CValue::ClearProperties()
00362 {
00363
00364 if (m_pNamedPropertyArray == NULL)
00365 return;
00366
00367
00368 for ( std::map<const CCString,CValue*>::iterator it = m_pNamedPropertyArray->begin();
00369 !(it == m_pNamedPropertyArray->end());it++)
00370 {
00371 CValue* tmpval = (*it).second;
00372 CCString name = (*it).first;
00373 tmpval->Release();
00374 }
00375
00376
00377 delete m_pNamedPropertyArray;
00378 m_pNamedPropertyArray=NULL;
00379 }
00380
00381
00382
00383
00384
00385
00386 void CValue::SetPropertiesModified(bool inModified)
00387 {
00388 int numprops = GetPropertyCount();
00389 for (int i=0; i<numprops; i++)
00390 GetProperty(i)->SetModified(inModified);
00391 }
00392
00393
00394
00395
00396
00397
00398 bool CValue::IsAnyPropertyModified()
00399 {
00400 int numprops = GetPropertyCount();
00401 for (int i=0;i<numprops;i++)
00402 if (GetProperty(i)->IsModified())
00403 return true;
00404
00405 return false;
00406 }
00407
00408
00409
00410
00411
00412
00413
00414 CValue* CValue::GetProperty(int inIndex)
00415 {
00416
00417 int count=0;
00418 CValue* result = NULL;
00419
00420 if (m_pNamedPropertyArray)
00421 {
00422 for ( std::map<const CCString,CValue*>::iterator it = m_pNamedPropertyArray->begin();
00423 !(it == m_pNamedPropertyArray->end());it++)
00424 {
00425 if (count++==inIndex)
00426 {
00427 result = (*it).second;
00428 break;
00429 }
00430 }
00431
00432 }
00433 return result;
00434 }
00435
00436
00437
00438
00439
00440
00441 int CValue::GetPropertyCount()
00442 {
00443 if (m_pNamedPropertyArray)
00444 return m_pNamedPropertyArray->size();
00445 else
00446 return 0;
00447 }
00448
00449
00450
00451
00452
00453 void CValue::CloneProperties(CValue *replica)
00454 {
00455
00456 if (m_pNamedPropertyArray)
00457 {
00458 replica->m_pNamedPropertyArray=NULL;
00459 for ( std::map<const CCString,CValue*>::iterator it = m_pNamedPropertyArray->begin();
00460 !(it == m_pNamedPropertyArray->end());it++)
00461 {
00462
00463 replica->SetProperty((*it).first,(*it).second->GetReplica());
00464 }
00465 }
00466
00467
00468 }
00469
00470
00471
00472
00473
00474
00475 double* CValue::GetVector3(bool bGetTransformedVec)
00476 {
00477 assertd(false);
00478 return m_sZeroVec;
00479 }
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495 CValue *CValue::AddRef()
00496 {
00497
00498
00499
00500 m_refcount++;
00501
00502 return this;
00503 }
00504
00505
00506
00507
00508
00509
00510 int CValue::Release()
00511 {
00512
00513
00514
00515
00516
00517 if (--m_refcount > 0)
00518 {
00519
00520 return m_refcount;
00521 }
00522 else
00523 {
00524
00525
00526 delete this;
00527 return 0;
00528 }
00529
00530 }
00531
00532
00533
00534
00535
00536
00537 void CValue::DisableRefCount()
00538 {
00539 assertd(m_refcount == 1);
00540 m_refcount--;
00541
00542
00543 m_ValFlags.RefCountDisabled=true;
00544 }
00545
00546
00547
00548 void CValue::AddDataToReplica(CValue *replica)
00549 {
00550 replica->m_refcount = 1;
00551 #ifdef _DEBUG
00552
00553 #endif
00554 replica->m_ValFlags.RefCountDisabled = false;
00555
00556 replica->ReplicaSetName(GetName());
00557
00558
00559 CloneProperties(replica);
00560 }
00561
00562
00563
00564 CValue* CValue::FindIdentifier(const CCString& identifiername)
00565 {
00566
00567 CValue* result = NULL;
00568
00569 int pos = 0;
00570
00571 if ((pos=identifiername.Find('.'))>=0)
00572 {
00573 const CCString rightstring = identifiername.Right(identifiername.Length() -1 - pos);
00574 const CCString leftstring = identifiername.Left(pos);
00575 CValue* tempresult = GetProperty(leftstring);
00576 if (tempresult)
00577 {
00578 result=tempresult->FindIdentifier(rightstring);
00579 }
00580 } else
00581 {
00582 result = GetProperty(identifiername);
00583 int i=0;
00584 }
00585 if (result)
00586 return result->AddRef();
00587
00588 result = new CErrorValue(identifiername+" not found");
00589 return result;
00590 }
00591
00592
00593 #ifndef NO_EXP_PYTHON_EMBEDDING
00594
00595
00596 static PyMethodDef CValueMethods[] =
00597 {
00598 { "new", CValue::PyMake , Py_NEWARGS},
00599 { NULL,NULL}
00600 };
00601
00602
00603 PyObject* CValue::_getattr(char* attr)
00604 {
00605 PyTypeObject* type = ob_type;
00606 CValue* resultattr = FindIdentifier(attr);
00607 CCString text;
00608 if (resultattr)
00609 {
00610 if (resultattr->IsError())
00611 {
00612 resultattr->Release();
00613 } else
00614 {
00615
00616 PyObject* pyconvert = resultattr->ConvertValueToPython();
00617 if (pyconvert)
00618 {
00619 resultattr->Release();
00620 return pyconvert;
00621 } else
00622 {
00623
00624 return resultattr;
00625 }
00626
00627 }
00628 }
00629 _getattr_up(PyObjectPlus);
00630 }
00631
00632 CValue* CValue::ConvertPythonToValue(PyObject* pyobj)
00633 {
00634
00635 CValue* vallie = NULL;
00636
00637 PyTypeObject* type = pyobj->ob_type;
00638
00639 if (type == &PyList_Type)
00640 {
00641 CListValue* listval = new CListValue();
00642 bool error = false;
00643
00644 int i;
00645 int numitems = PyList_Size(pyobj);
00646 for (i=0;i<numitems;i++)
00647 {
00648 PyObject* listitem = PyList_GetItem(pyobj,i);
00649 CValue* listitemval = ConvertPythonToValue(listitem);
00650 if (listitemval)
00651 {
00652 listval->Add(listitemval);
00653 } else
00654 {
00655 error = true;
00656 }
00657 }
00658 if (!error)
00659 {
00660
00661 vallie = listval;
00662 } else
00663 {
00664
00665 listval->Release();
00666 }
00667
00668 } else
00669 if (type == &PyFloat_Type)
00670 {
00671 float fl;
00672 PyArg_Parse(pyobj,"f",&fl);
00673 vallie = new CFloatValue(fl);
00674 } else
00675 if (type==&PyInt_Type)
00676 {
00677 int innie;
00678 PyArg_Parse(pyobj,"i",&innie);
00679 vallie = new CIntValue(innie);
00680 } else
00681
00682 if (type==&PyString_Type)
00683 {
00684 vallie = new CStringValue(PyString_AsString(pyobj),"");
00685 } else
00686 if (type==&CValue::Type || type==&CListValue::Type)
00687 {
00688 vallie = ((CValue*) pyobj)->AddRef();
00689 }
00690 return vallie;
00691
00692 }
00693 int CValue::_setattr(char* attr,PyObject* pyobj)
00694 {
00695
00696 CValue* vallie = ConvertPythonToValue(pyobj);
00697 if (vallie)
00698 {
00699 SetProperty(attr,vallie);
00700 }
00701
00702
00703 return 0;
00704 };
00705 PyObject* CValue::PyMake(PyObject* ignored,PyObject* args)
00706 {
00707 char* name;
00708
00709 Py_INCREF(Py_None);
00710 return Py_None;
00711 }
00712
00713 extern "C" {
00714 void initCValue(void)
00715 {
00716 Py_InitModule("CValue",CValueMethods);
00717 }
00718 }
00719
00720
00721
00722 #endif //NO_EXP_PYTHON_EMBEDDING
00723
00728