Initial revision
This commit is contained in:
767
source/gameengine/Expressions/Value.cpp
Normal file
767
source/gameengine/Expressions/Value.cpp
Normal file
@@ -0,0 +1,767 @@
|
||||
// Value.cpp: implementation of the CValue class.
|
||||
// developed at Eindhoven University of Technology, 1997
|
||||
// by the OOPS team
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
/*
|
||||
* Copyright (c) 1996-2000 Erwin Coumans <coockie@acm.org>
|
||||
*
|
||||
* Permission to use, copy, modify, distribute and sell this software
|
||||
* and its documentation for any purpose is hereby granted without fee,
|
||||
* provided that the above copyright notice appear in all copies and
|
||||
* that both that copyright notice and this permission notice appear
|
||||
* in supporting documentation. Erwin Coumans makes no
|
||||
* representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied warranty.
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "Value.h"
|
||||
#include "FloatValue.h"
|
||||
#include "IntValue.h"
|
||||
#include "VectorValue.h"
|
||||
#include "VoidValue.h"
|
||||
#include "StringValue.h"
|
||||
#include "ErrorValue.h"
|
||||
#include "ListValue.h"
|
||||
|
||||
//#include "FactoryManager.h"
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// Construction/Destruction
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
double CValue::m_sZeroVec[3] = {0.0,0.0,0.0};
|
||||
|
||||
#ifndef NO_EXP_PYTHON_EMBEDDING
|
||||
|
||||
PyObject* cvalue_add(PyObject*v, PyObject*w)
|
||||
{
|
||||
return ((CValue*)v)->Calc(VALUE_ADD_OPERATOR,(CValue*)w);
|
||||
}
|
||||
PyObject* cvalue_sub(PyObject*v, PyObject*w)
|
||||
{
|
||||
return ((CValue*)v)->Calc(VALUE_SUB_OPERATOR,(CValue*)w);
|
||||
}
|
||||
PyObject* cvalue_mul(PyObject*v, PyObject*w)
|
||||
{
|
||||
return ((CValue*)v)->Calc(VALUE_MUL_OPERATOR,(CValue*)w);
|
||||
}
|
||||
PyObject* cvalue_div(PyObject*v, PyObject*w)
|
||||
{
|
||||
return ((CValue*)v)->Calc(VALUE_DIV_OPERATOR,(CValue*)w);
|
||||
}
|
||||
PyObject* cvalue_neg(PyObject*v)
|
||||
{
|
||||
return ((CValue*)v)->Calc(VALUE_NEG_OPERATOR,(CValue*)v);
|
||||
}
|
||||
PyObject* cvalue_pos(PyObject*v)
|
||||
{
|
||||
return ((CValue*)v)->Calc(VALUE_POS_OPERATOR,(CValue*)v);
|
||||
}
|
||||
|
||||
|
||||
int MyPyCompare (PyObject* v,PyObject* w)
|
||||
{
|
||||
CValue* eqval = ((CValue*)v)->Calc(VALUE_EQL_OPERATOR,(CValue*)w);
|
||||
STR_String txt = eqval->GetText();
|
||||
eqval->Release();
|
||||
if (txt=="TRUE")
|
||||
return 0;
|
||||
CValue* lessval = ((CValue*)v)->Calc(VALUE_LES_OPERATOR,(CValue*)w);
|
||||
txt = lessval->GetText();
|
||||
lessval->Release();
|
||||
if (txt=="TRUE")
|
||||
return -1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
int cvalue_coerce(PyObject** pv,PyObject** pw)
|
||||
{
|
||||
if (PyInt_Check(*pw)) {
|
||||
double db = (double)PyInt_AsLong(*pw);
|
||||
*pw = new CIntValue(db);
|
||||
Py_INCREF(*pv);
|
||||
return 0;
|
||||
}
|
||||
else if (PyLong_Check(*pw)) {
|
||||
double db = PyLong_AsDouble(*pw);
|
||||
*pw = new CFloatValue(db);
|
||||
Py_INCREF(*pv);
|
||||
return 0;
|
||||
}
|
||||
else if (PyFloat_Check(*pw)) {
|
||||
double db = PyFloat_AsDouble(*pw);
|
||||
*pw = new CFloatValue(db);
|
||||
Py_INCREF(*pv);
|
||||
return 0;
|
||||
} else if (PyString_Check(*pw)) {
|
||||
const STR_String str = PyString_AsString(*pw);
|
||||
*pw = new CStringValue(str,"");
|
||||
Py_INCREF(*pv);
|
||||
return 0;
|
||||
}
|
||||
return 1; /* Can't do it */
|
||||
|
||||
}
|
||||
static PyNumberMethods cvalue_as_number = {
|
||||
(binaryfunc)cvalue_add, /*nb_add*/
|
||||
(binaryfunc)cvalue_sub, /*nb_subtract*/
|
||||
(binaryfunc)cvalue_mul, /*nb_multiply*/
|
||||
(binaryfunc)cvalue_div, /*nb_divide*/
|
||||
0,//(binaryfunc)cvalue_remainder, /*nb_remainder*/
|
||||
0,//(binaryfunc)cvalue_divmod, /*nb_divmod*/
|
||||
0,//0,//0,//0,//(ternaryfunc)cvalue_pow, /*nb_power*/
|
||||
(unaryfunc)cvalue_neg, /*nb_negative*/
|
||||
0,//(unaryfunc)cvalue_pos, /*nb_positive*/
|
||||
0,//(unaryfunc)cvalue_abs, /*nb_absolute*/
|
||||
0,//(inquiry)cvalue_nonzero, /*nb_nonzero*/
|
||||
0, /*nb_invert*/
|
||||
0, /*nb_lshift*/
|
||||
0, /*nb_rshift*/
|
||||
0, /*nb_and*/
|
||||
0, /*nb_xor*/
|
||||
0, /*nb_or*/
|
||||
(coercion)cvalue_coerce, /*nb_coerce*/
|
||||
0,//(unaryfunc)cvalue_int, /*nb_int*/
|
||||
0,//(unaryfunc)cvalue_long, /*nb_long*/
|
||||
0,//(unaryfunc)cvalue_float, /*nb_float*/
|
||||
0, /*nb_oct*/
|
||||
0, /*nb_hex*/
|
||||
};
|
||||
|
||||
|
||||
PyTypeObject CValue::Type = {
|
||||
PyObject_HEAD_INIT(&PyType_Type)
|
||||
0,
|
||||
"CValue",
|
||||
sizeof(CValue),
|
||||
0,
|
||||
PyDestructor,
|
||||
0,
|
||||
__getattr,
|
||||
__setattr,
|
||||
&MyPyCompare,
|
||||
__repr,
|
||||
&cvalue_as_number,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
0
|
||||
};
|
||||
|
||||
PyParentObject CValue::Parents[] = {
|
||||
&CValue::Type,
|
||||
NULL
|
||||
};
|
||||
|
||||
PyMethodDef CValue::Methods[] = {
|
||||
// { "printHello", (PyCFunction) CValue::sPyPrintHello, Py_NEWARGS},
|
||||
{ "getName", (PyCFunction) CValue::sPyGetName, Py_NEWARGS},
|
||||
{NULL,NULL} //Sentinel
|
||||
};
|
||||
|
||||
PyObject* CValue::PyGetName(PyObject* self,PyObject* args,PyObject* kwds)
|
||||
{
|
||||
PyObject* pyname = PyString_FromString(this->GetName());
|
||||
return pyname;
|
||||
}
|
||||
|
||||
|
||||
|
||||
CValue::CValue(PyTypeObject *T)
|
||||
: PyObjectPlus(T),
|
||||
#else
|
||||
CValue::CValue()
|
||||
:
|
||||
#endif //NO_EXP_PYTHON_EMBEDDING
|
||||
|
||||
m_refcount(1),
|
||||
m_pNamedPropertyArray(NULL)
|
||||
/*
|
||||
pre: false
|
||||
effect: constucts a CValue
|
||||
*/
|
||||
{
|
||||
//debug(gRefCountValue++) // debugging
|
||||
}
|
||||
|
||||
|
||||
|
||||
CValue::~CValue()
|
||||
/*
|
||||
pre:
|
||||
effect: deletes the object
|
||||
*/
|
||||
{
|
||||
ClearProperties();
|
||||
|
||||
assertd (m_refcount==0);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
#define VALUE_SUB(val1, val2) (val1)->Calc(VALUE_SUB_OPERATOR, val2)
|
||||
#define VALUE_MUL(val1, val2) (val1)->Calc(VALUE_MUL_OPERATOR, val2)
|
||||
#define VALUE_DIV(val1, val2) (val1)->Calc(VALUE_DIV_OPERATOR, val2)
|
||||
#define VALUE_NEG(val1) (val1)->Calc(VALUE_NEG_OPERATOR, val1)
|
||||
#define VALUE_POS(val1) (val1)->Calc(VALUE_POS_OPERATOR, val1)
|
||||
|
||||
|
||||
STR_String CValue::op2str (VALUE_OPERATOR op)
|
||||
{
|
||||
//pre:
|
||||
//ret: the stringrepresentation of operator op
|
||||
|
||||
STR_String opmsg;
|
||||
switch (op) {
|
||||
case VALUE_ADD_OPERATOR:
|
||||
opmsg = " + ";
|
||||
break;
|
||||
case VALUE_SUB_OPERATOR:
|
||||
opmsg = " - ";
|
||||
break;
|
||||
case VALUE_MUL_OPERATOR:
|
||||
opmsg = " * ";
|
||||
break;
|
||||
case VALUE_DIV_OPERATOR:
|
||||
opmsg = " / ";
|
||||
break;
|
||||
case VALUE_NEG_OPERATOR:
|
||||
opmsg = " -";
|
||||
break;
|
||||
case VALUE_POS_OPERATOR:
|
||||
opmsg = " +";
|
||||
break;
|
||||
case VALUE_AND_OPERATOR:
|
||||
opmsg = " & ";
|
||||
break;
|
||||
case VALUE_OR_OPERATOR:
|
||||
opmsg = " | ";
|
||||
break;
|
||||
case VALUE_EQL_OPERATOR:
|
||||
opmsg = " = ";
|
||||
break;
|
||||
case VALUE_NEQ_OPERATOR:
|
||||
opmsg = " != ";
|
||||
break;
|
||||
case VALUE_NOT_OPERATOR:
|
||||
opmsg = " !";
|
||||
break;
|
||||
default:
|
||||
opmsg="Error in Errorhandling routine.";
|
||||
// AfxMessageBox("Invalid operator");
|
||||
break;
|
||||
}
|
||||
return opmsg;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
// Property Management
|
||||
//---------------------------------------------------------------------------------------------------------------------
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Set property <ioProperty>, overwrites and releases a previous property with the same name if needed
|
||||
//
|
||||
void CValue::SetProperty(const STR_String & name,CValue* ioProperty)
|
||||
{
|
||||
// Check if somebody is setting an empty property
|
||||
if (ioProperty==NULL)
|
||||
{
|
||||
trace("Warning:trying to set empty property!");
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure we have a property array
|
||||
if (m_pNamedPropertyArray == NULL)
|
||||
m_pNamedPropertyArray = new std::map<const STR_String,CValue *>;
|
||||
|
||||
// Try to replace property (if so -> exit as soon as we replaced it)
|
||||
CValue* oldval = (*m_pNamedPropertyArray)[name];
|
||||
if (oldval)
|
||||
{
|
||||
oldval->Release();
|
||||
}
|
||||
|
||||
// Add property at end of array
|
||||
(*m_pNamedPropertyArray)[name] = ioProperty;//->Add(ioProperty);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Get pointer to a property with name <inName>, returns NULL if there is no property named <inName>
|
||||
//
|
||||
CValue* CValue::GetProperty(const STR_String & inName)
|
||||
{
|
||||
// Check properties, as soon as we found it -> Return a pointer to the property
|
||||
CValue* result = NULL;
|
||||
if (m_pNamedPropertyArray)
|
||||
{
|
||||
std::map<const STR_String,CValue*>::iterator it = (*m_pNamedPropertyArray).find(inName);
|
||||
if (!( it==m_pNamedPropertyArray->end()))
|
||||
{
|
||||
result = (*it).second;
|
||||
}
|
||||
|
||||
}
|
||||
//for (int i=0; i<m_pValuePropertyArray->size(); i++)
|
||||
// if ((*m_pValuePropertyArray)[i]->GetName() == inName)
|
||||
// return (*m_pValuePropertyArray)[i];
|
||||
|
||||
// Did not find property with name <inName>, return NULL property pointer
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Get text description of property with name <inName>, returns an empty string if there is no property named <inName>
|
||||
//
|
||||
STR_String CValue::GetPropertyText(const STR_String & inName,const STR_String& deftext)
|
||||
{
|
||||
CValue *property = GetProperty(inName);
|
||||
if (property)
|
||||
return property->GetText();
|
||||
else
|
||||
return deftext;//String::sEmpty;
|
||||
}
|
||||
|
||||
float CValue::GetPropertyNumber(const STR_String& inName,float defnumber)
|
||||
{
|
||||
CValue *property = GetProperty(inName);
|
||||
if (property)
|
||||
return property->GetNumber();
|
||||
else
|
||||
return defnumber;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Remove the property named <inName>, returns true if the property was succesfully removed, false if property was not found or could not be removed
|
||||
//
|
||||
bool CValue::RemoveProperty(const STR_String & inName)
|
||||
{
|
||||
// Check if there are properties at all which can be removed
|
||||
if (m_pNamedPropertyArray == NULL)
|
||||
return false;
|
||||
|
||||
// Scan all properties, as soon as we find one with <inName> -> Remove it
|
||||
// CValue* val = (*m_pNamedPropertyArray)[inName];
|
||||
if (m_pNamedPropertyArray->erase(inName)) return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Clear all properties
|
||||
//
|
||||
void CValue::ClearProperties()
|
||||
{
|
||||
// Check if we have any properties
|
||||
if (m_pNamedPropertyArray == NULL)
|
||||
return;
|
||||
|
||||
// Remove all properties
|
||||
for ( std::map<const STR_String,CValue*>::iterator it = m_pNamedPropertyArray->begin();
|
||||
!(it == m_pNamedPropertyArray->end());it++)
|
||||
{
|
||||
CValue* tmpval = (*it).second;
|
||||
STR_String name = (*it).first;
|
||||
tmpval->Release();
|
||||
}
|
||||
|
||||
// Delete property array
|
||||
delete m_pNamedPropertyArray;
|
||||
m_pNamedPropertyArray=NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Set all properties' modified flag to <inModified>
|
||||
//
|
||||
void CValue::SetPropertiesModified(bool inModified)
|
||||
{
|
||||
int numprops = GetPropertyCount();
|
||||
for (int i=0; i<numprops; i++)
|
||||
GetProperty(i)->SetModified(inModified);
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Check if any of the properties in this value have been modified
|
||||
//
|
||||
bool CValue::IsAnyPropertyModified()
|
||||
{
|
||||
int numprops = GetPropertyCount();
|
||||
for (int i=0;i<numprops;i++)
|
||||
if (GetProperty(i)->IsModified())
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Get property number <inIndex>
|
||||
//
|
||||
|
||||
CValue* CValue::GetProperty(int inIndex)
|
||||
{
|
||||
|
||||
int count=0;
|
||||
CValue* result = NULL;
|
||||
|
||||
if (m_pNamedPropertyArray)
|
||||
{
|
||||
for ( std::map<const STR_String,CValue*>::iterator it = m_pNamedPropertyArray->begin();
|
||||
!(it == m_pNamedPropertyArray->end());it++)
|
||||
{
|
||||
if (count++==inIndex)
|
||||
{
|
||||
result = (*it).second;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Get the amount of properties assiocated with this value
|
||||
//
|
||||
int CValue::GetPropertyCount()
|
||||
{
|
||||
if (m_pNamedPropertyArray)
|
||||
return m_pNamedPropertyArray->size();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
void CValue::CloneProperties(CValue *replica)
|
||||
{
|
||||
|
||||
if (m_pNamedPropertyArray)
|
||||
{
|
||||
replica->m_pNamedPropertyArray=NULL;
|
||||
for ( std::map<const STR_String,CValue*>::iterator it = m_pNamedPropertyArray->begin();
|
||||
!(it == m_pNamedPropertyArray->end());it++)
|
||||
{
|
||||
|
||||
replica->SetProperty((*it).first,(*it).second->GetReplica());
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
double* CValue::GetVector3(bool bGetTransformedVec)
|
||||
{
|
||||
assertd(false); // don;t get vector from me
|
||||
return m_sZeroVec;//::sZero;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
/*---------------------------------------------------------------------------------------------------------------------
|
||||
Reference Counting
|
||||
---------------------------------------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Add a reference to this value
|
||||
//
|
||||
CValue *CValue::AddRef()
|
||||
{
|
||||
// Increase global reference count, used to see at the end of the program
|
||||
// if all CValue-derived classes have been dereferenced to 0
|
||||
//debug(gRefCountValue++);
|
||||
m_refcount++;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Release a reference to this value (when reference count reaches 0, the value is removed from the heap)
|
||||
//
|
||||
int CValue::Release()
|
||||
{
|
||||
// Decrease global reference count, used to see at the end of the program
|
||||
// if all CValue-derived classes have been dereferenced to 0
|
||||
//debug(gRefCountValue--);
|
||||
|
||||
// Decrease local reference count, if it reaches 0 the object should be freed
|
||||
if (--m_refcount > 0)
|
||||
{
|
||||
// Reference count normal, return new reference count
|
||||
return m_refcount;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Reference count reached 0, delete ourselves and return 0
|
||||
// assert(m_refcount==0, "Reference count reached sub-zero, object released too much");
|
||||
delete this;
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
//
|
||||
// Disable reference counting for this value
|
||||
//
|
||||
void CValue::DisableRefCount()
|
||||
{
|
||||
assertd(m_refcount == 1);
|
||||
m_refcount--;
|
||||
|
||||
//debug(gRefCountValue--);
|
||||
m_ValFlags.RefCountDisabled=true;
|
||||
}
|
||||
|
||||
|
||||
|
||||
void CValue::AddDataToReplica(CValue *replica)
|
||||
{
|
||||
replica->m_refcount = 1;
|
||||
#ifdef _DEBUG
|
||||
//gRefCountValue++;
|
||||
#endif
|
||||
replica->m_ValFlags.RefCountDisabled = false;
|
||||
|
||||
replica->ReplicaSetName(GetName());
|
||||
|
||||
//copy all props
|
||||
CloneProperties(replica);
|
||||
}
|
||||
|
||||
|
||||
|
||||
CValue* CValue::FindIdentifier(const STR_String& identifiername)
|
||||
{
|
||||
|
||||
CValue* result = NULL;
|
||||
|
||||
int pos = 0;
|
||||
// if a dot exists, explode the name into pieces to get the subcontext
|
||||
if ((pos=identifiername.Find('.'))>=0)
|
||||
{
|
||||
const STR_String rightstring = identifiername.Right(identifiername.Length() -1 - pos);
|
||||
const STR_String leftstring = identifiername.Left(pos);
|
||||
CValue* tempresult = GetProperty(leftstring);
|
||||
if (tempresult)
|
||||
{
|
||||
result=tempresult->FindIdentifier(rightstring);
|
||||
}
|
||||
} else
|
||||
{
|
||||
result = GetProperty(identifiername);
|
||||
}
|
||||
if (result)
|
||||
return result->AddRef();
|
||||
// warning here !!!
|
||||
result = new CErrorValue(identifiername+" not found");
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
#ifndef NO_EXP_PYTHON_EMBEDDING
|
||||
|
||||
|
||||
static PyMethodDef CValueMethods[] =
|
||||
{
|
||||
//{ "new", CValue::PyMake , Py_NEWARGS},
|
||||
{ NULL,NULL} // Sentinel
|
||||
};
|
||||
|
||||
|
||||
PyObject* CValue::_getattr(char* attr)
|
||||
{
|
||||
CValue* resultattr = FindIdentifier(attr);
|
||||
STR_String text;
|
||||
if (resultattr)
|
||||
{
|
||||
if (resultattr->IsError())
|
||||
{
|
||||
resultattr->Release();
|
||||
} else
|
||||
{
|
||||
// to avoid some compare problems, return a real pythonthing
|
||||
PyObject* pyconvert = resultattr->ConvertValueToPython();
|
||||
if (pyconvert)
|
||||
{
|
||||
resultattr->Release();
|
||||
return pyconvert;
|
||||
} else
|
||||
{
|
||||
// also check if it's already in pythoninterpreter!
|
||||
return resultattr;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
_getattr_up(PyObjectPlus);
|
||||
}
|
||||
|
||||
CValue* CValue::ConvertPythonToValue(PyObject* pyobj)
|
||||
{
|
||||
|
||||
CValue* vallie = NULL;
|
||||
|
||||
PyTypeObject* type = pyobj->ob_type;
|
||||
|
||||
if (type == &PyList_Type)
|
||||
{
|
||||
CListValue* listval = new CListValue();
|
||||
bool error = false;
|
||||
|
||||
int i;
|
||||
int numitems = PyList_Size(pyobj);
|
||||
for (i=0;i<numitems;i++)
|
||||
{
|
||||
PyObject* listitem = PyList_GetItem(pyobj,i);
|
||||
CValue* listitemval = ConvertPythonToValue(listitem);
|
||||
if (listitemval)
|
||||
{
|
||||
listval->Add(listitemval);
|
||||
} else
|
||||
{
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
if (!error)
|
||||
{
|
||||
// jippie! could be converted
|
||||
vallie = listval;
|
||||
} else
|
||||
{
|
||||
// list could not be converted... bad luck
|
||||
listval->Release();
|
||||
}
|
||||
|
||||
} else
|
||||
if (type == &PyFloat_Type)
|
||||
{
|
||||
float fl;
|
||||
PyArg_Parse(pyobj,"f",&fl);
|
||||
vallie = new CFloatValue(fl);
|
||||
} else
|
||||
if (type==&PyInt_Type)
|
||||
{
|
||||
int innie;
|
||||
PyArg_Parse(pyobj,"i",&innie);
|
||||
vallie = new CIntValue(innie);
|
||||
} else
|
||||
|
||||
if (type==&PyString_Type)
|
||||
{
|
||||
vallie = new CStringValue(PyString_AsString(pyobj),"");
|
||||
} else
|
||||
if (type==&CValue::Type || type==&CListValue::Type)
|
||||
{
|
||||
vallie = ((CValue*) pyobj)->AddRef();
|
||||
}
|
||||
return vallie;
|
||||
|
||||
}
|
||||
int CValue::_setattr(char* attr,PyObject* pyobj)
|
||||
{
|
||||
|
||||
if (!pyobj) { // member deletion
|
||||
RemoveProperty(attr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
CValue* vallie = ConvertPythonToValue(pyobj);
|
||||
if (vallie)
|
||||
{
|
||||
CValue* oldprop = GetProperty(attr);
|
||||
|
||||
if (oldprop)
|
||||
{
|
||||
oldprop->SetValue(vallie);
|
||||
} else
|
||||
{
|
||||
SetProperty(attr,vallie->AddRef());
|
||||
}
|
||||
vallie->Release();
|
||||
}
|
||||
|
||||
//PyObjectPlus::_setattr(attr,value);
|
||||
return 0;
|
||||
};
|
||||
/*
|
||||
PyObject* CValue::PyMake(PyObject* ignored,PyObject* args)
|
||||
{
|
||||
|
||||
//Py_Try(PyArg_ParseTuple(args,"s",&name));
|
||||
Py_INCREF(Py_None);
|
||||
return Py_None;//new CValue();
|
||||
}
|
||||
*/
|
||||
|
||||
extern "C" {
|
||||
void initCValue(void)
|
||||
{
|
||||
Py_InitModule("CValue",CValueMethods);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif //NO_EXP_PYTHON_EMBEDDING
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
/* These implementations were moved out of the header */
|
||||
|
||||
void CValue::SetOwnerExpression(class CExpression* expr)
|
||||
{
|
||||
/* intentionally empty */
|
||||
}
|
||||
|
||||
void CValue::SetColorOperator(VALUE_OPERATOR op)
|
||||
{
|
||||
/* intentionally empty */
|
||||
}
|
||||
void CValue::SetValue(CValue* newval)
|
||||
{
|
||||
// no one should get here
|
||||
assertd(newval->GetNumber() == 10121969);
|
||||
}
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
///////////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
Reference in New Issue
Block a user