Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/gameengine/Expressions/ListValue.cpp')
-rw-r--r--source/gameengine/Expressions/ListValue.cpp536
1 files changed, 536 insertions, 0 deletions
diff --git a/source/gameengine/Expressions/ListValue.cpp b/source/gameengine/Expressions/ListValue.cpp
new file mode 100644
index 00000000000..25723350f36
--- /dev/null
+++ b/source/gameengine/Expressions/ListValue.cpp
@@ -0,0 +1,536 @@
+// ListValue.cpp: implementation of the CListValue class.
+//
+//////////////////////////////////////////////////////////////////////
+/*
+ * 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 "ListValue.h"
+#include "StringValue.h"
+#include "VoidValue.h"
+#include <algorithm>
+
+int listvalue_bufferlen(PyObject* list)
+{
+ return ( ((CListValue*)list)->GetCount());
+}
+
+
+
+PyObject* listvalue_buffer_item(PyObject* list,int index)
+{
+ if (index >= 0 && index < ((CListValue*) list)->GetCount())
+ {
+ PyObject* pyobj = ((CListValue*) list)->GetValue(index)->ConvertValueToPython();
+ if (pyobj)
+ return pyobj;
+ else
+ return ((CListValue*) list)->GetValue(index)->AddRef();
+
+ }
+ Py_Error(PyExc_IndexError, "Python ListIndex out of range");
+ return NULL;
+}
+
+
+
+/* just slice it into a python list... */
+PyObject* listvalue_buffer_slice(PyObject* list,int ilow, int ihigh)
+{
+ int i, j;
+ PyListObject *newlist;
+
+ if (ilow < 0) ilow = 0;
+
+ int n = ((CListValue*) list)->GetCount();
+
+ if (ihigh >= n)
+ ihigh = n;
+ if (ihigh < ilow)
+ ihigh = ilow;
+
+ newlist = (PyListObject *) PyList_New(ihigh - ilow);
+ if (!newlist)
+ return NULL;
+
+ for (i = ilow, j = 0; i < ihigh; i++, j++)
+ {
+ PyObject* pyobj = ((CListValue*) list)->GetValue(i)->ConvertValueToPython();
+ if (!pyobj)
+ pyobj = ((CListValue*) list)->GetValue(i)->AddRef();
+ newlist->ob_item[j] = pyobj;
+ }
+ return (PyObject *) newlist;
+}
+
+
+
+static PyObject *
+listvalue_buffer_concat(PyObject * self, PyObject * other)
+{
+ // for now, we support CListValue concatenated with items
+ // and CListValue concatenated to Python Lists
+ // and CListValue concatenated with another CListValue
+
+ CListValue* listval = (CListValue*) self;
+ listval->AddRef();
+ if (other->ob_type == &PyList_Type)
+ {
+ bool error = false;
+
+ int i;
+ int numitems = PyList_Size(other);
+ for (i=0;i<numitems;i++)
+ {
+ PyObject* listitem = PyList_GetItem(other,i);
+ CValue* listitemval = listval->ConvertPythonToValue(listitem);
+ if (listitemval)
+ {
+ listval->Add(listitemval);
+ } else
+ {
+ error = true;
+ }
+ }
+
+ if (error)
+ Py_Error(PyExc_SystemError, "Python Error: couldn't add one or more items to a list");
+
+
+ } else
+ {
+ if (other->ob_type == &CListValue::Type)
+ {
+ // add items from otherlist to this list
+ CListValue* otherval = (CListValue*) other;
+
+
+ for (int i=0;i<otherval->GetCount();i++)
+ {
+ otherval->Add(listval->GetValue(i)->AddRef());
+ }
+ }
+ else
+ {
+ CValue* objval = listval->ConvertPythonToValue(other);
+ if (objval)
+ {
+ listval->Add(objval);
+ } else
+ {
+ Py_Error(PyExc_SystemError, "Python Error: couldn't add item to a list");
+ // bad luck
+ }
+ }
+ }
+
+ return self;
+}
+
+
+
+static PySequenceMethods listvalue_as_sequence = {
+ (inquiry)listvalue_bufferlen,//(inquiry)buffer_length, /*sq_length*/
+ (binaryfunc)listvalue_buffer_concat, /*sq_concat*/
+ 0,//(intargfunc)buffer_repeat, /*sq_repeat*/
+ (intargfunc)listvalue_buffer_item, /*sq_item*/
+ (intintargfunc)listvalue_buffer_slice, /*sq_slice*/
+ 0,//(intobjargproc)buffer_ass_item, /*sq_ass_item*/
+ 0,//(intintobjargproc)buffer_ass_slice, /*sq_ass_slice*/
+};
+
+
+
+/* Is this one used ? */
+static PyMappingMethods instance_as_mapping = {
+ (inquiry)listvalue_bufferlen, /*mp_length*/
+ 0,//(binaryfunc)instance_subscript, /*mp_subscript*/
+ 0,//(objobjargproc)instance_ass_subscript, /*mp_ass_subscript*/
+};
+
+
+
+PyTypeObject CListValue::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /*ob_size*/
+ "CListValue", /*tp_name*/
+ sizeof(CListValue), /*tp_basicsize*/
+ 0, /*tp_itemsize*/
+ /* methods */
+ PyDestructor, /*tp_dealloc*/
+ 0, /*tp_print*/
+ __getattr, /*tp_getattr*/
+ __setattr, /*tp_setattr*/
+ 0, /*tp_compare*/
+ __repr, /*tp_repr*/
+ 0, /*tp_as_number*/
+ &listvalue_as_sequence, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call */
+};
+
+
+
+PyParentObject CListValue::Parents[] = {
+ &CListValue::Type,
+ &CValue::Type,
+ NULL
+};
+
+
+
+
+PyMethodDef CListValue::Methods[] = {
+ {"append", (PyCFunction)CListValue::sPyappend,METH_VARARGS},
+ {"reverse", (PyCFunction)CListValue::sPyreverse,METH_VARARGS},
+ {"index", (PyCFunction)CListValue::sPyindex,METH_VARARGS},
+ {"count", (PyCFunction)CListValue::sPycount,METH_VARARGS},
+
+ {NULL,NULL} //Sentinel
+};
+
+
+
+PyObject* CListValue::_getattr(char* attr) {
+ _getattr_up(CValue);
+}
+
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CListValue::CListValue(PyTypeObject *T )
+: CPropValue(T)
+{
+ m_bReleaseContents=true;
+}
+
+
+
+CListValue::~CListValue()
+{
+
+ if (m_bReleaseContents) {
+ for (int i=0;i<m_pValueArray.size();i++) {
+ m_pValueArray[i]->Release();
+ }
+ }
+}
+
+
+static STR_String gstrListRep=STR_String("List");
+
+const STR_String & CListValue::GetText()
+{
+ gstrListRep = "[";
+ STR_String commastr = "";
+
+ for (int i=0;i<GetCount();i++)
+ {
+ gstrListRep += commastr;
+ gstrListRep += GetValue(i)->GetText();
+ commastr = ",";
+ }
+ gstrListRep += "]";
+
+ return gstrListRep;
+}
+
+
+
+CValue* CListValue::GetReplica() {
+ CListValue* replica = new CListValue(*this);
+
+ CValue::AddDataToReplica(replica);
+
+ replica->m_bReleaseContents=true; // for copy, complete array is copied for now...
+ // copy all values
+ int numelements = m_pValueArray.size();
+ int i=0;
+ replica->m_pValueArray.resize(numelements);
+ for (i=0;i<m_pValueArray.size();i++)
+ replica->m_pValueArray[i] = m_pValueArray[i]->GetReplica();
+
+
+ return replica;
+};
+
+
+
+void CListValue::SetValue(int i, CValue *val)
+{
+ assertd(i < m_pValueArray.size());
+ m_pValueArray[i]=val;
+}
+
+
+
+void CListValue::Resize(int num)
+{
+ m_pValueArray.resize(num);
+}
+
+
+
+void CListValue::Remove(int i)
+{
+ assertd(i<m_pValueArray.size());
+ m_pValueArray.erase(m_pValueArray.begin()+i);
+}
+
+
+
+void CListValue::ReleaseAndRemoveAll()
+{
+ for (int i=0;i<m_pValueArray.size();i++)
+ m_pValueArray[i]->Release();
+ m_pValueArray.clear();//.Clear();
+}
+
+
+
+CValue* CListValue::FindValue(const STR_String & name)
+{
+ CValue* resultval = NULL;
+ int i=0;
+
+ while (!resultval && i < GetCount())
+ {
+ CValue* myval = GetValue(i);
+
+ if (myval->GetName() == name)
+ resultval = GetValue(i)->AddRef(); // add referencecount
+ else
+ i++;
+
+ }
+ return resultval;
+}
+
+
+
+bool CListValue::SearchValue(CValue *val)
+{
+ for (int i=0;i<GetCount();i++)
+ if (val == GetValue(i))
+ return true;
+ return false;
+}
+
+
+
+void CListValue::SetReleaseOnDestruct(bool bReleaseContents)
+{
+ m_bReleaseContents = bReleaseContents;
+}
+
+
+
+bool CListValue::RemoveValue(CValue *val)
+{
+ bool result=false;
+
+ for (int i=GetCount()-1;i>=0;i--)
+ if (val == GetValue(i))
+ {
+ Remove(i);
+ result=true;
+ }
+ return result;
+}
+
+
+
+void CListValue::MergeList(CListValue *otherlist)
+{
+
+ int numelements = this->GetCount();
+ int numotherelements = otherlist->GetCount();
+
+
+ Resize(numelements+numotherelements);
+
+ for (int i=0;i<numotherelements;i++)
+ {
+ SetValue(i+numelements,otherlist->GetValue(i)->AddRef());
+ }
+
+}
+
+
+
+PyObject* CListValue::Pyappend(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+
+ PyObject* pyobj = NULL;
+ if (PyArg_ParseTuple(args,"O",&pyobj))
+ {
+ return listvalue_buffer_concat(self,pyobj);
+ }
+ else
+ {
+ return NULL;
+ }
+
+
+}
+
+
+
+PyObject* CListValue::Pyreverse(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ std::reverse(m_pValueArray.begin(),m_pValueArray.end());
+
+ Py_Return;
+
+}
+
+
+
+bool CListValue::CheckEqual(CValue* first,CValue* second)
+{
+ bool result = false;
+
+ CValue* eqval = ((CValue*)first)->Calc(VALUE_EQL_OPERATOR,(CValue*)second);
+ STR_String txt = eqval->GetText();
+ eqval->Release();
+ if (txt=="TRUE")
+ {
+ result = true;
+ }
+ return result;
+
+}
+
+
+
+PyObject* CListValue::Pyindex(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+ PyObject* result = NULL;
+
+ PyObject* pyobj = NULL;
+ if (PyArg_ParseTuple(args,"O",&pyobj))
+ {
+
+ CValue* checkobj = ConvertPythonToValue(pyobj);
+ int numelem = GetCount();
+ for (int i=0;i<numelem;i++)
+ {
+ CValue* elem = GetValue(i);
+ if (CheckEqual(checkobj,elem))
+ {
+ result = PyInt_FromLong(i);
+ break;
+ }
+ }
+ checkobj->Release();
+ }
+
+ return result;
+
+}
+
+
+
+PyObject* CListValue::Pycount(PyObject* self,
+ PyObject* args,
+ PyObject* kwds)
+{
+
+ int numfound = 0;
+
+ PyObject* pyobj = NULL;
+ if (PyArg_ParseTuple(args,"O",&pyobj))
+ {
+ CValue* checkobj = ConvertPythonToValue(pyobj);
+ int numelem = GetCount();
+ for (int i=0;i<numelem;i++)
+ {
+ CValue* elem = GetValue(i);
+ if (CheckEqual(checkobj,elem))
+ {
+ numfound ++;
+ }
+ }
+ checkobj->Release();
+ }
+
+ return PyInt_FromLong(numfound);
+}
+
+
+
+/* ---------------------------------------------------------------------
+ * Some stuff taken from the header
+ * --------------------------------------------------------------------- */
+CValue* CListValue::Calc(VALUE_OPERATOR op,CValue *val)
+{
+ assert(false); // todo: implement me!
+ return NULL;
+}
+
+
+
+CValue* CListValue::CalcFinal(VALUE_DATA_TYPE dtype,
+ VALUE_OPERATOR op,
+ CValue* val)
+{
+ assert(false); // todo: implement me!
+ return NULL;
+}
+
+
+
+void CListValue::Add(CValue* value)
+{
+ m_pValueArray.push_back(value);
+}
+
+
+
+float CListValue::GetNumber()
+{
+ return -1;
+}
+
+
+
+void CListValue::SetModified(bool bModified)
+{
+ CValue::SetModified(bModified);
+ int numels = GetCount();
+
+ for (int i=0;i<numels;i++)
+ GetValue(i)->SetModified(bModified);
+}
+
+
+
+bool CListValue::IsModified()
+{
+ bool bmod = CValue::IsModified(); //normal own flag
+ int numels = GetCount();
+
+ for (int i=0;i<numels;i++)
+ bmod = bmod || GetValue(i)->IsModified();
+
+ return bmod;
+} \ No newline at end of file