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')
-rw-r--r--source/gameengine/Expressions/BoolValue.cpp213
-rw-r--r--source/gameengine/Expressions/BoolValue.h51
-rw-r--r--source/gameengine/Expressions/ConstExpr.cpp132
-rw-r--r--source/gameengine/Expressions/ConstExpr.h46
-rw-r--r--source/gameengine/Expressions/EXP_C-Api.cpp124
-rw-r--r--source/gameengine/Expressions/EXP_C-Api.h68
-rw-r--r--source/gameengine/Expressions/EmptyValue.cpp127
-rw-r--r--source/gameengine/Expressions/EmptyValue.h39
-rw-r--r--source/gameengine/Expressions/ErrorValue.cpp125
-rw-r--r--source/gameengine/Expressions/ErrorValue.h38
-rw-r--r--source/gameengine/Expressions/Expression.cpp75
-rw-r--r--source/gameengine/Expressions/Expression.h133
-rw-r--r--source/gameengine/Expressions/FloatValue.cpp316
-rw-r--r--source/gameengine/Expressions/FloatValue.h48
-rw-r--r--source/gameengine/Expressions/IdentifierExpr.cpp103
-rw-r--r--source/gameengine/Expressions/IdentifierExpr.h55
-rw-r--r--source/gameengine/Expressions/IfExpr.cpp141
-rw-r--r--source/gameengine/Expressions/IfExpr.h49
-rw-r--r--source/gameengine/Expressions/InputParser.cpp648
-rw-r--r--source/gameengine/Expressions/InputParser.h105
-rw-r--r--source/gameengine/Expressions/IntValue.cpp325
-rw-r--r--source/gameengine/Expressions/IntValue.h60
-rw-r--r--source/gameengine/Expressions/KX_HashedPtr.cpp58
-rw-r--r--source/gameengine/Expressions/KX_HashedPtr.h53
-rw-r--r--source/gameengine/Expressions/ListValue.cpp536
-rw-r--r--source/gameengine/Expressions/ListValue.h77
-rw-r--r--source/gameengine/Expressions/Makefile45
-rw-r--r--source/gameengine/Expressions/Operator1Expr.cpp148
-rw-r--r--source/gameengine/Expressions/Operator1Expr.h53
-rw-r--r--source/gameengine/Expressions/Operator2Expr.cpp275
-rw-r--r--source/gameengine/Expressions/Operator2Expr.h59
-rw-r--r--source/gameengine/Expressions/PyObjectPlus.cpp157
-rw-r--r--source/gameengine/Expressions/PyObjectPlus.h135
-rw-r--r--source/gameengine/Expressions/StringValue.cpp139
-rw-r--r--source/gameengine/Expressions/StringValue.h51
-rw-r--r--source/gameengine/Expressions/Value.cpp767
-rw-r--r--source/gameengine/Expressions/Value.h467
-rw-r--r--source/gameengine/Expressions/VectorValue.cpp213
-rw-r--r--source/gameengine/Expressions/VectorValue.h86
-rw-r--r--source/gameengine/Expressions/VoidValue.h68
40 files changed, 6408 insertions, 0 deletions
diff --git a/source/gameengine/Expressions/BoolValue.cpp b/source/gameengine/Expressions/BoolValue.cpp
new file mode 100644
index 00000000000..544b760f4e9
--- /dev/null
+++ b/source/gameengine/Expressions/BoolValue.cpp
@@ -0,0 +1,213 @@
+
+// BoolValue.cpp: implementation of the CBoolValue 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 "BoolValue.h"
+#include "StringValue.h"
+#include "ErrorValue.h"
+#include "VoidValue.h"
+//#include "FactoryManager.h"
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+
+CBoolValue::CBoolValue()
+/*
+pre: false
+effect: constructs a new CBoolValue
+*/
+{
+ trace("Bool constructor error");
+}
+
+
+
+CBoolValue::CBoolValue(bool inBool)
+: m_bool(inBool)
+{
+} // Constructs a new CBoolValue containing <inBool>
+
+
+
+CBoolValue::CBoolValue(bool innie,STR_String name,AllocationTYPE alloctype)
+{
+ m_bool = innie;
+ SetName(name);
+
+ if (alloctype == CValue::STACKVALUE)
+ CValue::DisableRefCount();
+}
+
+
+
+void CBoolValue::SetValue(CValue* newval)
+{
+ m_bool = (newval->GetNumber() != 0);
+ SetModified(true);
+}
+
+
+
+CValue* CBoolValue::Calc(VALUE_OPERATOR op, CValue *val)
+/*
+pre:
+ret: a new object containing the result of applying operator op to this
+object and val
+*/
+{
+ switch (op)
+ {
+ case VALUE_POS_OPERATOR:
+ case VALUE_NEG_OPERATOR:
+ {
+ return new CErrorValue (op2str(op) + GetText());
+ break;
+ }
+ case VALUE_NOT_OPERATOR:
+ {
+ return new CBoolValue (!m_bool);
+ break;
+ }
+ default:
+ {
+ return val->CalcFinal(VALUE_BOOL_TYPE, op, this);
+ break;
+ }
+ }
+}
+
+
+
+CValue* CBoolValue::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val)
+/*
+pre: the type of val is dtype
+ret: a new object containing the result of applying operator op to val and
+this object
+*/
+{
+ CValue *ret;
+
+ switch(dtype)
+ {
+ case VALUE_EMPTY_TYPE:
+ case VALUE_BOOL_TYPE:
+ {
+ switch(op)
+ {
+ case VALUE_AND_OPERATOR:
+ {
+ ret = new CBoolValue (((CBoolValue *) val)->GetBool() && m_bool);
+ break;
+ }
+ case VALUE_OR_OPERATOR:
+ {
+ ret = new CBoolValue (((CBoolValue *) val)->GetBool() || m_bool);
+ break;
+ }
+ case VALUE_EQL_OPERATOR:
+ {
+ ret = new CBoolValue (((CBoolValue *) val)->GetBool() == m_bool);
+ break;
+ }
+ case VALUE_NEQ_OPERATOR:
+ {
+ ret = new CBoolValue (((CBoolValue *) val)->GetBool() != m_bool);
+ break;
+ }
+ case VALUE_NOT_OPERATOR:
+ {
+ return new CBoolValue (!m_bool);
+ break;
+ }
+ default:
+ {
+ ret = new CErrorValue(val->GetText() + op2str(op) +
+ "[operator not allowed on booleans]");
+ break;
+ }
+ }
+ break;
+ }
+ case VALUE_STRING_TYPE:
+ {
+ switch(op)
+ {
+ case VALUE_ADD_OPERATOR:
+ {
+ ret = new CStringValue(val->GetText() + GetText(),"");
+ break;
+ }
+ default:
+ {
+ ret = new CErrorValue(val->GetText() + op2str(op) + "[Only + allowed on boolean and string]");
+ break;
+ }
+ }
+ break;
+ }
+ default:
+ ret = new CErrorValue("[type mismatch]" + op2str(op) + GetText());
+ }
+
+ return ret;
+}
+
+
+
+bool CBoolValue::GetBool()
+/*
+pre:
+ret: the bool stored in the object
+*/
+{
+ return m_bool;
+}
+
+
+
+float CBoolValue::GetNumber()
+{
+ return (float)m_bool;
+}
+
+
+
+const STR_String& CBoolValue::GetText()
+{
+ static STR_String sTrueString = STR_String("TRUE");
+ static STR_String sFalseString = STR_String("FALSE");
+
+ return m_bool ? sTrueString : sFalseString;
+}
+
+
+
+CValue* CBoolValue::GetReplica()
+{
+ CBoolValue* replica = new CBoolValue(*this);
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+PyObject* CBoolValue::ConvertValueToPython()
+{
+ return PyInt_FromLong(m_bool != 0);
+}
diff --git a/source/gameengine/Expressions/BoolValue.h b/source/gameengine/Expressions/BoolValue.h
new file mode 100644
index 00000000000..e78ff2ef4bf
--- /dev/null
+++ b/source/gameengine/Expressions/BoolValue.h
@@ -0,0 +1,51 @@
+/*
+ * BoolValue.h: interface for the CBoolValue class.
+ * $Id$
+ * 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.
+ *
+ */
+#if !defined _BOOLVALUE_H
+#define _BOOLVALUE_H
+
+#include "Value.h"
+
+/**
+ * Smart Boolean Value class.
+ * Is used by parser when an expression tree is build containing booleans.
+ */
+
+class CBoolValue : public CPropValue
+{
+
+ //PLUGIN_DECLARE_SERIAL(CBoolValue,CValue)
+
+public:
+ CBoolValue();
+ CBoolValue(bool inBool);
+ CBoolValue(bool innie, STR_String name, AllocationTYPE alloctype = CValue::HEAPVALUE);
+
+ virtual const STR_String& GetText();
+ virtual float GetNumber();
+ bool GetBool();
+ virtual void SetValue(CValue* newval);
+
+ virtual CValue* Calc(VALUE_OPERATOR op, CValue *val);
+ virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val);
+
+ void Configure(CValue* menuvalue);
+ virtual CValue* GetReplica();
+ virtual PyObject* ConvertValueToPython();
+
+private:
+ bool m_bool;
+};
+
+#endif // !defined _BOOLVALUE_H
diff --git a/source/gameengine/Expressions/ConstExpr.cpp b/source/gameengine/Expressions/ConstExpr.cpp
new file mode 100644
index 00000000000..c8b4c311b7c
--- /dev/null
+++ b/source/gameengine/Expressions/ConstExpr.cpp
@@ -0,0 +1,132 @@
+// ConstExpr.cpp: implementation of the CConstExpr 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 "Value.h" // for precompiled header
+
+#include "ConstExpr.h"
+#include "VectorValue.h"
+
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CConstExpr::CConstExpr()
+{
+}
+
+
+
+CConstExpr::CConstExpr(CValue* constval)
+/*
+pre:
+effect: constructs a CConstExpr cointing the value constval
+*/
+{
+ m_value = constval;
+// m_bModified=true;
+}
+
+
+
+CConstExpr::~CConstExpr()
+/*
+pre:
+effect: deletes the object
+*/
+{
+ if (m_value)
+ m_value->Release();
+}
+
+
+
+unsigned char CConstExpr::GetExpressionID()
+{
+ return CCONSTEXPRESSIONID;
+}
+
+
+
+CValue* CConstExpr::Calculate()
+/*
+pre:
+ret: a new object containing the value of the stored CValue
+*/
+{
+ return m_value->AddRef();
+}
+
+
+
+void CConstExpr::ClearModified()
+{
+ if (m_value)
+ {
+ m_value->SetModified(false);
+ m_value->SetAffected(false);
+ }
+}
+
+
+
+float CConstExpr::GetNumber()
+{
+ return -1;
+}
+
+
+
+bool CConstExpr::NeedsRecalculated()
+{
+ return m_value->IsAffected(); // IsAffected is m_bModified OR m_bAffected !!!
+}
+
+
+
+CExpression* CConstExpr::CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks)
+{
+// parent checks if child is still usefull.
+// When for example it's value it's deleted flag set
+// then release Value, and return NULL in case of constexpression
+// else return this...
+
+ assertd(m_value);
+ if (m_value->IsReleaseRequested())
+ {
+ AddRef(); //numchanges++;
+ return Release();
+ }
+ else
+ return this;
+}
+
+
+
+void CConstExpr::BroadcastOperators(VALUE_OPERATOR op)
+{
+ assertd(m_value);
+ m_value->SetColorOperator(op);
+}
+
+
+
+bool CConstExpr::MergeExpression(CExpression *otherexpr)
+{
+ assertd(false);
+ return false;
+}
diff --git a/source/gameengine/Expressions/ConstExpr.h b/source/gameengine/Expressions/ConstExpr.h
new file mode 100644
index 00000000000..4c01c142d32
--- /dev/null
+++ b/source/gameengine/Expressions/ConstExpr.h
@@ -0,0 +1,46 @@
+/*
+ * ConstExpr.h: interface for the CConstExpr class.
+ * $Id$
+ * 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.
+ *
+ */
+
+#ifndef __CONSTEXPR_H__
+#define __CONSTEXPR_H__
+
+#include "Expression.h"
+#include "Value.h" // Added by ClassView
+
+class CConstExpr : public CExpression
+{
+ //PLUGIN_DECLARE_SERIAL_EXPRESSION (CConstExpr,CExpression)
+public:
+ virtual bool MergeExpression(CExpression* otherexpr);
+
+ void BroadcastOperators(VALUE_OPERATOR op);
+
+ virtual unsigned char GetExpressionID();
+ CExpression* CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks);
+ //bool IsInside(float x,float y,float z,bool bBorderInclude=true);
+ bool NeedsRecalculated();
+ void ClearModified();
+ virtual float GetNumber();
+ virtual CValue* Calculate();
+ CConstExpr(CValue* constval);
+ CConstExpr();
+ virtual ~CConstExpr();
+
+
+private:
+ CValue* m_value;
+};
+
+#endif // !defined(AFX_CONSTEXPR_H__061ECFC3_BE87_11D1_A51C_00A02472FC58__INCLUDED_)
diff --git a/source/gameengine/Expressions/EXP_C-Api.cpp b/source/gameengine/Expressions/EXP_C-Api.cpp
new file mode 100644
index 00000000000..4d45fd556eb
--- /dev/null
+++ b/source/gameengine/Expressions/EXP_C-Api.cpp
@@ -0,0 +1,124 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#include "EXP_C-Api.h"
+#include "IntValue.h"
+#include "BoolValue.h"
+#include "StringValue.h"
+#include "ErrorValue.h"
+#include "InputParser.h"
+
+
+EXP_ValueHandle EXP_CreateInt(int innie)
+{
+ return (EXP_ValueHandle) new CIntValue(innie);
+}
+
+
+
+EXP_ValueHandle EXP_CreateBool(int innie)
+{
+ return (EXP_ValueHandle) new CBoolValue(innie!=0);
+}
+
+
+
+EXP_ValueHandle EXP_CreateString(const char* str)
+{
+
+ return (EXP_ValueHandle) new CStringValue(str,"");
+}
+
+
+
+void EXP_SetName(EXP_ValueHandle inval,const char* newname)
+{
+ ((CValue*) inval)->SetName(newname);
+}
+
+
+
+/* calculate expression from inputtext */
+EXP_ValueHandle EXP_ParseInput(const char* inputtext)
+{
+ CValue* resultval=NULL;
+ CParser parser;
+ CExpression* expr = parser.ProcessText(inputtext);
+ if (expr)
+ {
+ resultval = expr->Calculate();
+ expr->Release();
+ }
+ else
+ {
+ resultval = new CErrorValue("couldn't parsetext");
+ }
+
+ return (EXP_ValueHandle) resultval;
+}
+
+
+
+void EXP_ReleaseValue(EXP_ValueHandle inval)
+{
+ ((CValue*) inval)->Release();
+}
+
+
+
+int EXP_IsValid(EXP_ValueHandle inval)
+{
+ return !((CValue*) inval)->IsError();
+}
+
+
+
+/* assign property 'propval' to 'destinationval' */
+void EXP_SetProperty(EXP_ValueHandle destinationval,
+ const char* propname,
+ EXP_ValueHandle propval)
+{
+ ((CValue*) destinationval)->SetProperty(propname,(CValue*)propval);
+}
+
+
+
+const char* EXP_GetText(EXP_ValueHandle inval)
+{
+ return ((CValue*) inval)->GetText();
+}
+
+
+
+EXP_ValueHandle EXP_GetProperty(EXP_ValueHandle inval,const char* propname)
+{
+ return (EXP_ValueHandle) ((CValue*)inval)->GetProperty(propname);
+}
diff --git a/source/gameengine/Expressions/EXP_C-Api.h b/source/gameengine/Expressions/EXP_C-Api.h
new file mode 100644
index 00000000000..e99152294f1
--- /dev/null
+++ b/source/gameengine/Expressions/EXP_C-Api.h
@@ -0,0 +1,68 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef __EXPRESSION_INCLUDE
+#define __EXPRESSION_INCLUDE
+
+
+#define EXP_DECLARE_HANDLE(name) typedef struct name##__ { int unused; } *name
+
+EXP_DECLARE_HANDLE(EXP_ValueHandle);
+EXP_DECLARE_HANDLE(EXP_ExpressionHandle);
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern EXP_ValueHandle EXP_CreateInt(int innie);
+extern EXP_ValueHandle EXP_CreateBool(int innie);
+extern EXP_ValueHandle EXP_CreateString(const char* str);
+extern void EXP_SetName(EXP_ValueHandle,const char* newname);
+
+/* calculate expression from inputtext */
+extern EXP_ValueHandle EXP_ParseInput(const char* inputtext);
+extern void EXP_ReleaseValue(EXP_ValueHandle);
+extern int EXP_IsValid(EXP_ValueHandle);
+
+/* assign property 'propval' to 'destinationval' */
+extern void EXP_SetProperty(EXP_ValueHandle propval,EXP_ValueHandle destinationval);
+
+/* returns NULL if property doesn't exist */
+extern EXP_ValueHandle EXP_GetProperty(EXP_ValueHandle inval,const char* propname);
+
+const char* EXP_GetText(EXP_ValueHandle);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //__EXPRESSION_INCLUDE
diff --git a/source/gameengine/Expressions/EmptyValue.cpp b/source/gameengine/Expressions/EmptyValue.cpp
new file mode 100644
index 00000000000..25c0b6af5d7
--- /dev/null
+++ b/source/gameengine/Expressions/EmptyValue.cpp
@@ -0,0 +1,127 @@
+
+// EmptyValue.cpp: implementation of the CEmptyValue 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 "EmptyValue.h"
+#include "IntValue.h"
+#include "FloatValue.h"
+#include "StringValue.h"
+#include "ErrorValue.h"
+#include "ListValue.h"
+#include "VoidValue.h"
+
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CEmptyValue::CEmptyValue()
+/*
+pre:
+effect: constructs a new CEmptyValue
+*/
+{
+ SetModified(false);
+}
+
+
+
+CEmptyValue::~CEmptyValue()
+/*
+pre:
+effect: deletes the object
+*/
+{
+
+}
+
+
+
+CValue * CEmptyValue::Calc(VALUE_OPERATOR op, CValue * val)
+/*
+pre:
+ret: a new object containing the result of applying operator op to this
+object and val
+*/
+{
+ return val->CalcFinal(VALUE_EMPTY_TYPE, op, this);
+
+}
+
+
+
+CValue * CEmptyValue::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue * val)
+/*
+pre: the type of val is dtype
+ret: a new object containing the result of applying operator op to val and
+this object
+*/
+{
+ return val->AddRef();
+}
+
+
+
+float CEmptyValue::GetNumber()
+{
+ return 0;
+}
+
+
+
+CListValue* CEmptyValue::GetPolySoup()
+{
+ CListValue* soup = new CListValue();
+ //don't add any poly, while it's an empty value
+ return soup;
+}
+
+
+
+bool CEmptyValue::IsInside(CValue* testpoint,bool bBorderInclude)
+{
+ // empty space is solid, so always inside
+ return true;
+}
+
+
+
+double* CEmptyValue::GetVector3(bool bGetTransformedVec)
+{
+ assertd(false); // don't get vector from me
+ return ZeroVector();
+}
+
+
+
+static STR_String emptyString = STR_String("");
+
+
+const STR_String & CEmptyValue::GetText()
+{
+ return emptyString;
+}
+
+
+
+CValue* CEmptyValue::GetReplica()
+{
+ CEmptyValue* replica = new CEmptyValue(*this);
+ CValue::AddDataToReplica(replica);
+ return replica;
+}
+
diff --git a/source/gameengine/Expressions/EmptyValue.h b/source/gameengine/Expressions/EmptyValue.h
new file mode 100644
index 00000000000..d400cd065f5
--- /dev/null
+++ b/source/gameengine/Expressions/EmptyValue.h
@@ -0,0 +1,39 @@
+/*
+ * EmptyValue.h: interface for the CEmptyValue class.
+ * $Id$
+ * 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.
+ *
+ */
+#if !defined _EMPTYVALUE_H
+#define _EMPTYVALUE_H
+
+#include "Value.h"
+
+class CListValue;
+
+class CEmptyValue : public CPropValue
+{
+ //PLUGIN_DECLARE_SERIAL (CEmptyValue,CValue)
+public:
+ CEmptyValue();
+ virtual ~CEmptyValue();
+
+ virtual const STR_String & GetText();
+ virtual float GetNumber();
+ CListValue* GetPolySoup();
+ virtual double* GetVector3(bool bGetTransformedVec=false);
+ bool IsInside(CValue* testpoint,bool bBorderInclude=true);
+ CValue * Calc(VALUE_OPERATOR op, CValue *val);
+ CValue * CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val);
+ virtual CValue* GetReplica();
+};
+
+#endif // !defined _EMPTYVALUE_H
diff --git a/source/gameengine/Expressions/ErrorValue.cpp b/source/gameengine/Expressions/ErrorValue.cpp
new file mode 100644
index 00000000000..fd1ba7399b3
--- /dev/null
+++ b/source/gameengine/Expressions/ErrorValue.cpp
@@ -0,0 +1,125 @@
+// ErrorValue.cpp: implementation of the CErrorValue 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 "ErrorValue.h"
+
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CErrorValue::CErrorValue()
+/*
+pre:
+effect: constructs a new CErrorValue containing errormessage "Error"
+*/
+{
+ m_strErrorText = "Error";
+ SetError(true);
+}
+
+
+
+CErrorValue::CErrorValue(STR_String errmsg)
+/*
+pre:
+effect: constructs a new CErrorValue containing errormessage errmsg
+*/
+{
+ m_strErrorText = "[" + errmsg + "]";
+ SetError(true);
+}
+
+
+
+CErrorValue::~CErrorValue()
+/*
+pre:
+effect: deletes the object
+*/
+{
+
+}
+
+
+
+CValue* CErrorValue::Calc(VALUE_OPERATOR op, CValue *val)
+/*
+pre:
+ret: a new object containing the result of applying operator op to this
+ object and val
+*/
+{
+ CValue* errorval;
+
+ switch (op)
+ {
+ case VALUE_POS_OPERATOR:
+ case VALUE_NEG_OPERATOR:
+ case VALUE_NOT_OPERATOR:
+ {
+ errorval = new CErrorValue (op2str(op) + GetText());
+ break;
+ }
+ default:
+ {
+ errorval = val->CalcFinal(VALUE_ERROR_TYPE, op, this);
+ break;
+ }
+ }
+
+ return errorval;
+}
+
+
+
+CValue* CErrorValue::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val)
+/*
+pre: the type of val is dtype
+ret: a new object containing the result of applying operator op to val and
+ this object
+*/
+{
+ return new CErrorValue (val->GetText() + op2str(op) + GetText());
+}
+
+
+
+float CErrorValue::GetNumber()
+{
+ return -1;
+}
+
+
+
+const STR_String & CErrorValue::GetText()
+{
+ return m_strErrorText;
+}
+
+
+
+CValue* CErrorValue::GetReplica()
+{
+ // who would want a copy of an error ?
+ trace ("Error: ErrorValue::GetReplica() not implemented yet");
+ assertd(false);
+
+ return NULL;
+} \ No newline at end of file
diff --git a/source/gameengine/Expressions/ErrorValue.h b/source/gameengine/Expressions/ErrorValue.h
new file mode 100644
index 00000000000..8a4726e196d
--- /dev/null
+++ b/source/gameengine/Expressions/ErrorValue.h
@@ -0,0 +1,38 @@
+/*
+ * ErrorValue.h: interface for the CErrorValue class.
+ * $Id$
+ * 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.
+ *
+ */
+
+#if !defined _ERRORVALUE_H
+#define _ERRORVALUE_H
+
+#include "Value.h"
+
+class CErrorValue : public CPropValue
+{
+
+public:
+ virtual const STR_String & GetText();
+ virtual float GetNumber();
+ CErrorValue();
+ CErrorValue(STR_String errmsg);
+ virtual ~CErrorValue();
+ virtual CValue* Calc(VALUE_OPERATOR op, CValue* val);
+ virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val);
+ virtual CValue* GetReplica();
+
+private:
+ STR_String m_strErrorText;
+};
+
+#endif // !defined _ERRORVALUE_H
diff --git a/source/gameengine/Expressions/Expression.cpp b/source/gameengine/Expressions/Expression.cpp
new file mode 100644
index 00000000000..5e7950fbcf0
--- /dev/null
+++ b/source/gameengine/Expressions/Expression.cpp
@@ -0,0 +1,75 @@
+// Expression.cpp: implementation of the CExpression 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 "Expression.h"
+#include "ErrorValue.h"
+//#include "FactoryManager.h"
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CExpression::CExpression()// : m_cached_calculate(NULL)
+{
+ m_refcount = 1;
+#ifdef _DEBUG
+ //gRefCountExpr++;
+#endif
+}
+
+CExpression::~CExpression()
+{
+ assert (m_refcount == 0);
+}
+
+
+
+// destuctor for CBrokenLinkInfo
+CBrokenLinkInfo::~CBrokenLinkInfo()
+{
+ if (m_pExpr && !m_bRestored)
+ m_pExpr->Release();
+}
+
+
+void CBrokenLinkInfo::RestoreLink()
+{
+
+
+ assertd(m_pExpr);
+
+ if (m_pExpr)
+ {
+ if (!m_bRestored){
+ m_bRestored=true;
+
+ }
+ if (*m_pmemExpr)
+ {
+ (*m_pmemExpr)->Release();
+ }
+ *m_pmemExpr = m_pExpr;
+
+// m_pExpr=NULL;
+ }
+}
+
+void CBrokenLinkInfo::BreakLink()
+{
+ m_bRestored=false;
+ m_pExpr->AddRef();
+}
+
diff --git a/source/gameengine/Expressions/Expression.h b/source/gameengine/Expressions/Expression.h
new file mode 100644
index 00000000000..f48ac7eb160
--- /dev/null
+++ b/source/gameengine/Expressions/Expression.h
@@ -0,0 +1,133 @@
+/*
+ * Expression.h: interface for the CExpression class.
+ * $Id$
+ * 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.
+ *
+ */
+
+#if !defined _EXPRESSION_H
+#define _EXPRESSION_H
+
+#include "Value.h"
+
+//extern int gRefCountExpr; // only for debugging purposes (detect mem.leaks)
+
+
+
+
+#define PLUGIN_DECLARE_SERIAL_EXPRESSION(class_name,base_class_name) \
+public: \
+ virtual base_class_name * Copy() { return new class_name; } \
+ virtual bool EdSerialize(CompressorArchive& arch,class CFactoryManager* facmgr,bool bIsStoring); \
+ virtual bool EdIdSerialize(CompressorArchive& arch,class CFactoryManager* facmgr,bool bIsStoring) \
+{ \
+ if (bIsStoring) \
+ { \
+ unsigned char exprID = GetExpressionID(); \
+ arch << exprID; \
+ } \
+ return true; \
+} \
+
+
+
+class CExpression;
+
+
+// for undo/redo system the deletion in the expressiontree can be restored by replacing broken links 'inplace'
+class CBrokenLinkInfo
+{
+ public:
+ CBrokenLinkInfo(CExpression** pmemexpr,CExpression* expr)
+ :m_pmemExpr(pmemexpr),
+ m_pExpr(expr)
+ {
+ assertd(pmemexpr);
+ m_bRestored=false;
+ };
+
+ virtual ~CBrokenLinkInfo();
+ void RestoreLink();
+ void BreakLink();
+
+
+ // members vars
+ private:
+ CExpression** m_pmemExpr;
+ CExpression* m_pExpr;
+ bool m_bRestored;
+
+};
+
+
+
+
+
+
+
+
+class CExpression
+{
+public:
+ enum {
+ COPERATOR1EXPRESSIONID = 1,
+ COPERATOR2EXPRESSIONID = 2,
+ CCONSTEXPRESSIONID = 3,
+ CIFEXPRESSIONID = 4,
+ COPERATORVAREXPRESSIONID = 5,
+ CIDENTIFIEREXPRESSIONID = 6
+ };
+
+
+protected:
+ virtual ~CExpression() = 0; //pure virtual
+public:
+ virtual bool MergeExpression(CExpression* otherexpr) = 0;
+ CExpression();
+
+
+ virtual CValue* Calculate() = 0; //pure virtual
+ virtual unsigned char GetExpressionID() = 0;
+ //virtual bool IsInside(float x,float y,float z,bool bBorderInclude=true) = 0; //pure virtual
+ virtual bool NeedsRecalculated() = 0; // another pure one
+ virtual CExpression * CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks) =0; // another pure one
+ virtual void ClearModified() = 0; // another pure one
+ //virtual CExpression * Copy() =0;
+ virtual void BroadcastOperators(VALUE_OPERATOR op) =0;
+
+ virtual CExpression * AddRef() { // please leave multiline, for debugger !!!
+
+#ifdef _DEBUG
+ //gRefCountExpr++;
+ assertd(m_refcount < 255);
+#endif
+ m_refcount++;
+ return this;
+ };
+ virtual CExpression* Release(CExpression* complicatedtrick=NULL) {
+#ifdef _DEBUG
+ //gRefCountExpr--;
+#endif
+ if (--m_refcount < 1)
+ {
+ delete this;
+ } //else
+ // return this;
+ return complicatedtrick;
+ };
+
+
+protected:
+
+ int m_refcount;
+};
+
+#endif // !defined _EXPRESSION_H
diff --git a/source/gameengine/Expressions/FloatValue.cpp b/source/gameengine/Expressions/FloatValue.cpp
new file mode 100644
index 00000000000..78185bbe163
--- /dev/null
+++ b/source/gameengine/Expressions/FloatValue.cpp
@@ -0,0 +1,316 @@
+// FloatValue.cpp: implementation of the CFloatValue 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 "FloatValue.h"
+#include "IntValue.h"
+#include "StringValue.h"
+#include "BoolValue.h"
+#include "ErrorValue.h"
+#include "VoidValue.h"
+
+///#include "..\..\menuvalue.h"
+//#include "FactoryManager.h"
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CFloatValue::CFloatValue()
+/*
+pre: false
+effect: constructs a new CFloatValue
+*/
+{
+ m_pstrRep=NULL;
+}
+
+
+
+CFloatValue::CFloatValue(float fl)
+/*
+pre:
+effect: constructs a new CFloatValue containing value fl
+*/
+{
+ m_float = fl;
+ m_pstrRep=NULL;
+}
+
+
+
+CFloatValue::CFloatValue(float fl,STR_String name,AllocationTYPE alloctype)
+/*
+pre:
+effect: constructs a new CFloatValue containing value fl
+*/
+{
+
+ m_float = fl;
+ SetName(name);
+ if (alloctype==CValue::STACKVALUE)
+ {
+ CValue::DisableRefCount();
+
+ }
+ m_pstrRep=NULL;
+}
+
+
+
+CFloatValue::~CFloatValue()
+/*
+pre:
+effect: deletes the object
+*/
+{
+ if (m_pstrRep)
+ delete m_pstrRep;
+}
+
+
+
+CValue* CFloatValue::Calc(VALUE_OPERATOR op, CValue *val)
+/*
+pre:
+ret: a new object containing the result of applying operator op to this
+ object and val
+*/
+{
+ //return val->CalcFloat(op, this);
+ switch (op)
+ {
+ case VALUE_POS_OPERATOR:
+ return new CFloatValue (m_float);
+ break;
+ case VALUE_NEG_OPERATOR:
+ return new CFloatValue (-m_float);
+ break;
+ case VALUE_NOT_OPERATOR:
+ return new CErrorValue (op2str(op) + "only allowed on booleans");
+ break;
+ case VALUE_AND_OPERATOR:
+ case VALUE_OR_OPERATOR:
+ return new CErrorValue(val->GetText() + op2str(op) + "only allowed on booleans");
+ break;
+ default:
+ return val->CalcFinal(VALUE_FLOAT_TYPE, op, this);
+ break;
+ }
+}
+
+
+
+CValue* CFloatValue::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val)
+/*
+pre: the type of val is dtype
+ret: a new object containing the result of applying operator op to val and
+ this object
+*/
+{
+ CValue *ret;
+
+ switch(dtype)
+ {
+ case VALUE_INT_TYPE:
+ {
+ switch (op)
+ {
+ case VALUE_ADD_OPERATOR:
+ ret = new CFloatValue(((CIntValue *) val)->GetInt() + m_float);
+ break;
+ case VALUE_SUB_OPERATOR:
+ ret = new CFloatValue(((CIntValue *) val)->GetInt() - m_float);
+ break;
+ case VALUE_MUL_OPERATOR:
+ ret = new CFloatValue(((CIntValue *) val)->GetInt() * m_float);
+ break;
+ case VALUE_DIV_OPERATOR:
+ if (m_float == 0)
+ ret = new CErrorValue("Division by zero");
+ else
+ ret = new CFloatValue (((CIntValue *) val)->GetInt() / m_float);
+ break;
+ case VALUE_EQL_OPERATOR:
+ ret = new CBoolValue(((CIntValue *) val)->GetInt() == m_float);
+ break;
+ case VALUE_NEQ_OPERATOR:
+ ret = new CBoolValue(((CIntValue *) val)->GetInt() != m_float);
+ break;
+ case VALUE_GRE_OPERATOR:
+ ret = new CBoolValue(((CIntValue *) val)->GetInt() > m_float);
+ break;
+ case VALUE_LES_OPERATOR:
+ ret = new CBoolValue(((CIntValue *) val)->GetInt() < m_float);
+ break;
+ case VALUE_GEQ_OPERATOR:
+ ret = new CBoolValue(((CIntValue *) val)->GetInt() >= m_float);
+ break;
+ case VALUE_LEQ_OPERATOR:
+ ret = new CBoolValue(((CIntValue *) val)->GetInt() <= m_float);
+ break;
+ default:
+ ret = new CErrorValue("illegal operator. please send a bug report.");
+ break;
+ }
+ break;
+ }
+ case VALUE_EMPTY_TYPE:
+ case VALUE_FLOAT_TYPE:
+ {
+ switch (op)
+ {
+ case VALUE_ADD_OPERATOR:
+ ret = new CFloatValue(((CFloatValue *) val)->GetFloat() + m_float);
+ break;
+ case VALUE_SUB_OPERATOR:
+ ret = new CFloatValue(((CFloatValue *) val)->GetFloat() - m_float);
+ break;
+ case VALUE_MUL_OPERATOR:
+ ret = new CFloatValue(((CFloatValue *) val)->GetFloat() * m_float);
+ break;
+ case VALUE_DIV_OPERATOR:
+ if (m_float == 0)
+ ret = new CErrorValue("Division by zero");
+ else
+ ret = new CFloatValue (((CFloatValue *) val)->GetFloat() / m_float);
+ break;
+ case VALUE_EQL_OPERATOR:
+ ret = new CBoolValue(((CFloatValue *) val)->GetFloat() == m_float);
+ break;
+ case VALUE_NEQ_OPERATOR:
+ ret = new CBoolValue(((CFloatValue *) val)->GetFloat() != m_float);
+ break;
+ case VALUE_GRE_OPERATOR:
+ ret = new CBoolValue(((CFloatValue *) val)->GetFloat() > m_float);
+ break;
+ case VALUE_LES_OPERATOR:
+ ret = new CBoolValue(((CFloatValue *) val)->GetFloat() < m_float);
+ break;
+ case VALUE_GEQ_OPERATOR:
+ ret = new CBoolValue(((CFloatValue *) val)->GetFloat() >= m_float);
+ break;
+ case VALUE_LEQ_OPERATOR:
+ ret = new CBoolValue(((CFloatValue *) val)->GetFloat() <= m_float);
+ break;
+ case VALUE_NEG_OPERATOR:
+ ret = new CFloatValue (-m_float);
+ break;
+ case VALUE_POS_OPERATOR:
+ ret = new CFloatValue (m_float);
+ break;
+
+ default:
+ ret = new CErrorValue("illegal operator. please send a bug report.");
+ break;
+ }
+ break;
+ }
+ case VALUE_STRING_TYPE:
+ {
+ switch(op)
+ {
+ case VALUE_ADD_OPERATOR:
+ ret = new CStringValue(val->GetText() + GetText(),"");
+ break;
+ case VALUE_EQL_OPERATOR:
+ case VALUE_NEQ_OPERATOR:
+ case VALUE_GRE_OPERATOR:
+ case VALUE_LES_OPERATOR:
+ case VALUE_GEQ_OPERATOR:
+ case VALUE_LEQ_OPERATOR:
+ ret = new CErrorValue("[Cannot compare string with float]" + op2str(op) + GetText());
+ break;
+ default:
+ ret = new CErrorValue("[operator not allowed on strings]" + op2str(op) + GetText());
+ break;
+ }
+ break;
+ }
+ case VALUE_BOOL_TYPE:
+ ret = new CErrorValue("[operator not valid on boolean and float]" + op2str(op) + GetText());
+ break;
+ case VALUE_ERROR_TYPE:
+ ret = new CErrorValue(val->GetText() + op2str(op) + GetText());
+ break;
+ default:
+ ret = new CErrorValue("illegal type. contact your dealer (if any)");
+ break;
+ }
+ return ret;
+}
+
+
+
+void CFloatValue::SetFloat(float fl)
+{
+ m_float = fl;
+ SetModified(true);
+}
+
+
+
+float CFloatValue::GetFloat()
+/*
+pre:
+ret: the float stored in the object
+*/
+{
+ return m_float;
+}
+
+
+
+float CFloatValue::GetNumber()
+{
+ return m_float;
+}
+
+
+
+void CFloatValue::SetValue(CValue* newval)
+{
+ m_float = newval->GetNumber();
+ SetModified(true);
+}
+
+
+
+const STR_String & CFloatValue::GetText()
+{
+ if (!m_pstrRep)
+ m_pstrRep = new STR_String();
+
+ m_pstrRep->Format("%f",m_float);
+ return *m_pstrRep;
+}
+
+
+
+CValue* CFloatValue::GetReplica()
+{
+ CFloatValue* replica = new CFloatValue(*this);
+ replica->m_pstrRep = NULL;
+ CValue::AddDataToReplica(replica);
+
+ return replica;
+}
+
+
+
+PyObject* CFloatValue::ConvertValueToPython()
+{
+ return PyFloat_FromDouble(m_float);
+}
+
diff --git a/source/gameengine/Expressions/FloatValue.h b/source/gameengine/Expressions/FloatValue.h
new file mode 100644
index 00000000000..4dce35ebfa0
--- /dev/null
+++ b/source/gameengine/Expressions/FloatValue.h
@@ -0,0 +1,48 @@
+/*
+ * FloatValue.h: interface for the CFloatValue class.
+ * $Id$
+ * 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.
+ *
+ */
+#if !defined _FLOATVALUE_H
+#define _FLOATVALUE_H
+
+#include "Value.h"
+
+
+class CFloatValue : public CPropValue
+{
+ //PLUGIN_DECLARE_SERIAL (CFloatValue,CValue)
+public:
+ CFloatValue();
+ CFloatValue(float fl);
+ CFloatValue(float fl,STR_String name,AllocationTYPE alloctype=CValue::HEAPVALUE);
+
+ virtual const STR_String & GetText();
+
+ void Configure(CValue* menuvalue);
+ virtual float GetNumber();
+ virtual void SetValue(CValue* newval);
+ float GetFloat();
+ void SetFloat(float fl);
+ virtual ~CFloatValue();
+ virtual CValue* GetReplica();
+ virtual CValue* Calc(VALUE_OPERATOR op, CValue *val);
+ virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val);
+ virtual PyObject* ConvertValueToPython();
+
+protected:
+ float m_float;
+ STR_String* m_pstrRep;
+
+};
+
+#endif // !defined _FLOATVALUE_H
diff --git a/source/gameengine/Expressions/IdentifierExpr.cpp b/source/gameengine/Expressions/IdentifierExpr.cpp
new file mode 100644
index 00000000000..ff517aa7636
--- /dev/null
+++ b/source/gameengine/Expressions/IdentifierExpr.cpp
@@ -0,0 +1,103 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#include "IdentifierExpr.h"
+
+
+CIdentifierExpr::CIdentifierExpr(const STR_String& identifier,CValue* id_context)
+:m_identifier(identifier)
+{
+ if (id_context)
+ m_idContext = id_context->AddRef();
+ else
+ m_idContext=NULL;
+}
+
+
+CIdentifierExpr::~CIdentifierExpr()
+{
+ if (m_idContext)
+ m_idContext->Release();
+}
+
+
+
+CValue* CIdentifierExpr::Calculate()
+{
+ CValue* result = NULL;
+ if (m_idContext)
+ result = m_idContext->FindIdentifier(m_identifier);
+
+ return result;
+}
+
+
+
+bool CIdentifierExpr::MergeExpression(CExpression* otherexpr)
+{
+ return false;
+}
+
+
+
+unsigned char CIdentifierExpr::GetExpressionID()
+{
+ return CIDENTIFIEREXPRESSIONID;
+}
+
+
+
+bool CIdentifierExpr::NeedsRecalculated()
+{
+ return true;
+}
+
+
+
+CExpression* CIdentifierExpr::CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks)
+{
+ assertd(false); // not implemented yet
+ return NULL;
+}
+
+
+
+void CIdentifierExpr::ClearModified()
+{
+ assertd(false); // not implemented yet
+}
+
+
+
+void CIdentifierExpr::BroadcastOperators(VALUE_OPERATOR op)
+{
+ assertd(false); // not implemented yet
+} \ No newline at end of file
diff --git a/source/gameengine/Expressions/IdentifierExpr.h b/source/gameengine/Expressions/IdentifierExpr.h
new file mode 100644
index 00000000000..dbffe7c02bc
--- /dev/null
+++ b/source/gameengine/Expressions/IdentifierExpr.h
@@ -0,0 +1,55 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef __IDENTIFIER_EXPR
+#define __IDENTIFIER_EXPR
+
+#include "Expression.h"
+
+class CIdentifierExpr : public CExpression
+{
+ CValue* m_idContext;
+ STR_String m_identifier;
+public:
+ CIdentifierExpr(const STR_String& identifier,CValue* id_context);
+ virtual ~CIdentifierExpr();
+
+ virtual CValue* Calculate();
+ virtual bool MergeExpression(CExpression* otherexpr);
+ virtual unsigned char GetExpressionID();
+ virtual bool NeedsRecalculated();
+ virtual CExpression* CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks);
+ virtual void ClearModified();
+ virtual void BroadcastOperators(VALUE_OPERATOR op);
+};
+
+#endif //__IDENTIFIER_EXPR
+
diff --git a/source/gameengine/Expressions/IfExpr.cpp b/source/gameengine/Expressions/IfExpr.cpp
new file mode 100644
index 00000000000..bcb365b87cc
--- /dev/null
+++ b/source/gameengine/Expressions/IfExpr.cpp
@@ -0,0 +1,141 @@
+// IfExpr.cpp: implementation of the CIfExpr 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 "IfExpr.h"
+#include "EmptyValue.h"
+#include "ErrorValue.h"
+
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+
+CIfExpr::CIfExpr()
+{
+}
+
+
+
+CIfExpr::CIfExpr(CExpression *guard, CExpression *e1, CExpression *e2)
+/*
+pre:
+effect: constructs an CifExpr-object corresponding to IF(guard, e1, e2)
+*/
+{
+ m_guard = guard;
+ m_e1 = e1;
+ m_e2 = e2;
+}
+
+
+
+CIfExpr::~CIfExpr()
+/*
+pre:
+effect: dereferences the object
+*/
+{
+ if (m_guard)
+ m_guard->Release();
+
+ if (m_e1)
+ m_e1->Release();
+
+ if (m_e2)
+ m_e2->Release();
+}
+
+
+
+CValue* CIfExpr::Calculate()
+/*
+pre:
+ret: a new object containing the value of m_e1 if m_guard is a boolean TRUE
+ a new object containing the value of m_e2 if m_guard is a boolean FALSE
+ an new errorvalue if m_guard is not a boolean
+*/
+{
+ CValue *guardval;
+ guardval = m_guard->Calculate();
+ STR_String text = guardval->GetText();
+ guardval->Release();
+
+ if (text == STR_String("TRUE"))
+ {
+ return m_e1->Calculate();
+ }
+ else if (text == STR_String("FALSE"))
+ {
+ return m_e2->Calculate();
+ }
+ else
+ {
+ return new CErrorValue("Guard should be of boolean type");
+ }
+}
+
+
+
+bool CIfExpr::MergeExpression(CExpression *otherexpr)
+{
+ assertd(false);
+ return false;
+}
+
+
+
+bool CIfExpr::IsInside(float x,float y,float z,bool bBorderInclude)
+{
+ assertd(false);
+ return false;
+}
+
+
+
+bool CIfExpr::NeedsRecalculated()
+{
+ return (m_guard->NeedsRecalculated() ||
+ m_e1->NeedsRecalculated() ||
+ m_e2->NeedsRecalculated());
+}
+
+
+
+CExpression* CIfExpr::CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks)
+{
+ assertd(false);
+ return NULL;
+}
+
+
+
+void CIfExpr::ClearModified()
+{
+ assertd(false);
+}
+
+
+
+void CIfExpr::BroadcastOperators(VALUE_OPERATOR op)
+{
+ assertd(false);
+}
+
+
+
+unsigned char CIfExpr::GetExpressionID()
+{
+ return CIFEXPRESSIONID;
+} \ No newline at end of file
diff --git a/source/gameengine/Expressions/IfExpr.h b/source/gameengine/Expressions/IfExpr.h
new file mode 100644
index 00000000000..192edfe8fee
--- /dev/null
+++ b/source/gameengine/Expressions/IfExpr.h
@@ -0,0 +1,49 @@
+/*
+ * IfExpr.h: interface for the CIfExpr class.
+ * $Id$
+ * 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.
+ *
+ */
+#if !defined(AFX_IFEXPR_H__1F691841_C5C7_11D1_A863_0000B4542BD8__INCLUDED_)
+#define AFX_IFEXPR_H__1F691841_C5C7_11D1_A863_0000B4542BD8__INCLUDED_
+
+#if _MSC_VER >= 1000
+#pragma once
+#endif // _MSC_VER >= 1000
+
+#include "Expression.h"
+
+class CIfExpr : public CExpression
+{
+ //PLUGIN_DECLARE_SERIAL_EXPRESSION (CIfExpr,CExpression)
+
+private:
+ CExpression *m_guard, *m_e1, *m_e2;
+
+public:
+ virtual bool MergeExpression(CExpression* otherexpr);
+ CIfExpr(CExpression *guard, CExpression *e1, CExpression *e2);
+ CIfExpr();
+
+ virtual unsigned char GetExpressionID();
+ virtual ~CIfExpr();
+ virtual CValue* Calculate();
+
+ virtual bool IsInside(float x,float y,float z,bool bBorderInclude=true);
+ virtual bool NeedsRecalculated();
+
+
+ virtual CExpression* CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks);
+ virtual void ClearModified();
+ virtual void BroadcastOperators(VALUE_OPERATOR op);
+};
+
+#endif // !defined(AFX_IFEXPR_H__1F691841_C5C7_11D1_A863_0000B4542BD8__INCLUDED_)
diff --git a/source/gameengine/Expressions/InputParser.cpp b/source/gameengine/Expressions/InputParser.cpp
new file mode 100644
index 00000000000..efb5e277737
--- /dev/null
+++ b/source/gameengine/Expressions/InputParser.cpp
@@ -0,0 +1,648 @@
+// Parser.cpp: implementation of the CParser 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 <stdlib.h>
+
+#include "Value.h"
+#include "InputParser.h"
+#include "ErrorValue.h"
+#include "IntValue.h"
+#include "StringValue.h"
+#include "FloatValue.h"
+#include "BoolValue.h"
+#include "EmptyValue.h"
+#include "ConstExpr.h"
+#include "Operator2Expr.h"
+#include "Operator1Expr.h"
+#include "IdentifierExpr.h"
+
+// this is disable at the moment, I expected a memleak from it, but the error-cleanup was the reason
+// well, looks we don't need it anyway, until maybe the Curved Surfaces are integrated into CSG
+// cool things like (IF(LOD==1,CCurvedValue,IF(LOD==2,CCurvedValue2)) etc...
+#include "IfExpr.h"
+
+
+#define NUM_PRIORITY 6
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CParser::CParser() : m_identifierContext(NULL)
+{
+}
+
+
+
+CParser::~CParser()
+{
+ if (m_identifierContext)
+ m_identifierContext->Release();
+}
+
+
+
+void CParser::ScanError(STR_String str)
+{
+ // sets the global variable errmsg to an errormessage with
+ // contents str, appending if it already exists
+ // AfxMessageBox("Parse Error:"+str,MB_ICONERROR);
+ if (errmsg)
+ errmsg = new COperator2Expr(VALUE_ADD_OPERATOR, errmsg, Error(str));
+ else
+ errmsg = Error(str);
+
+ sym = errorsym;
+}
+
+
+
+CExpression* CParser::Error(STR_String str)
+{
+ // makes and returns a new CConstExpr filled with an CErrorValue
+ // with string str
+ // AfxMessageBox("Error:"+str,MB_ICONERROR);
+ return new CConstExpr(new CErrorValue(str));
+}
+
+
+
+void CParser::NextCh()
+{
+ // sets the global variable ch to the next character, if it exists
+ // and increases the global variable chcount
+ chcount++;
+
+ if (chcount < text.Length())
+ ch = text[chcount];
+ else
+ ch = 0x00;
+}
+
+
+
+void CParser::TermChar(char c)
+{
+ // generates an error if the next char isn't the specified char c,
+ // otherwise, skip the char
+ if(ch == c)
+ {
+ NextCh();
+ }
+ else
+ {
+ STR_String str;
+ str.Format("Warning: %c expected\ncontinuing without it", c);
+ trace(str);
+ }
+}
+
+
+
+void CParser::DigRep()
+{
+ // changes the current character to the first character that
+ // isn't a decimal
+ while ((ch >= '0') && (ch <= '9'))
+ NextCh();
+}
+
+
+
+void CParser::CharRep()
+{
+ // changes the current character to the first character that
+ // isn't an alphanumeric character
+ while (((ch >= '0') && (ch <= '9'))
+ || ((ch >= 'a') && (ch <= 'z'))
+ || ((ch >= 'A') && (ch <= 'Z'))
+ || (ch == '.') || (ch == '_'))
+ NextCh();
+}
+
+
+
+void CParser::GrabString(int start)
+{
+ // puts part of the input string into the global variable
+ // const_as_string, from position start, to position chchount
+ const_as_string = text.Mid(start, chcount-start);
+}
+
+
+
+void CParser::NextSym()
+{
+ // sets the global variable sym to the next symbol, and
+ // if it is an operator
+ // sets the global variable opkind to the kind of operator
+ // if it is a constant
+ // sets the global variable constkind to the kind of operator
+ // if it is a reference to a cell
+ // sets the global variable cellcoord to the kind of operator
+
+ errmsg = NULL;
+ while(ch == ' ' || ch == 0x9)
+ NextCh();
+
+ switch(ch)
+ {
+ case '(':
+ sym = lbracksym; NextCh();
+ break;
+ case ')':
+ sym = rbracksym; NextCh();
+ break;
+ case ',':
+ sym = commasym; NextCh();
+ break;
+ case '+' :
+ sym = opsym; opkind = OPplus; NextCh();
+ break;
+ case '-' :
+ sym = opsym; opkind = OPminus; NextCh();
+ break;
+ case '*' :
+ sym = opsym; opkind = OPtimes; NextCh();
+ break;
+ case '/' :
+ sym = opsym; opkind = OPdivide; NextCh();
+ break;
+ case '&' :
+ sym = opsym; opkind = OPand; NextCh(); TermChar('&');
+ break;
+ case '|' :
+ sym = opsym; opkind = OPor; NextCh(); TermChar('|');
+ break;
+ case '=' :
+ sym = opsym; opkind = OPequal; NextCh(); TermChar('=');
+ break;
+ case '!' :
+ sym = opsym;
+ NextCh();
+ if (ch == '=')
+ {
+ opkind = OPunequal;
+ NextCh();
+ }
+ else
+ {
+ opkind = OPnot;
+ }
+ break;
+ case '>':
+ sym = opsym;
+ NextCh();
+ if (ch == '=')
+ {
+ opkind = OPgreaterequal;
+ NextCh();
+ }
+ else
+ {
+ opkind = OPgreater;
+ }
+ break;
+ case '<':
+ sym = opsym;
+ NextCh();
+ if (ch == '=') {
+ opkind = OPlessequal;
+ NextCh();
+ } else {
+ opkind = OPless;
+ }
+ break;
+ case '\"' : {
+ int start;
+ sym = constsym;
+ constkind = stringtype;
+ NextCh();
+ start = chcount;
+ while ((ch != '\"') && (ch != 0x0))
+ NextCh();
+ GrabString(start);
+ TermChar('\"'); // check for eol before '\"'
+ break;
+ }
+ case 0x0: sym = eolsym; break;
+ default:
+ {
+ int start;
+ start = chcount;
+ DigRep();
+ if ((start != chcount) || (ch == '.')) { // number
+ sym = constsym;
+ if (ch == '.') {
+ constkind = floattype;
+ NextCh();
+ DigRep();
+ }
+ else constkind = inttype;
+ if ((ch == 'e') || (ch == 'E')) {
+ int mark;
+ constkind = floattype;
+ NextCh();
+ if ((ch == '+') || (ch == '-')) NextCh();
+ mark = chcount;
+ DigRep();
+ if (mark == chcount) {
+ ScanError("Number expected after 'E'");
+ return;
+ }
+ }
+ GrabString(start);
+ } else if (((ch >= 'a') && (ch <= 'z'))
+ || ((ch >= 'A') && (ch <= 'Z')))
+ { // reserved word?
+ int start;
+ STR_String funstr;
+ start = chcount;
+ CharRep();
+ GrabString(start);
+ funstr = const_as_string;
+ funstr.Upper();
+ if (funstr == STR_String("SUM")) {
+ sym = sumsym;
+ }
+ else if (funstr == STR_String("NOT")) {
+ sym = opsym;
+ opkind = OPnot;
+ }
+ else if (funstr == STR_String("AND")) {
+ sym = opsym; opkind = OPand;
+ }
+ else if (funstr == STR_String("OR")) {
+ sym = opsym; opkind = OPor;
+ }
+ else if (funstr == STR_String("IF")) {
+ sym = ifsym;
+ } else if (funstr == STR_String("WHOMADE")) {
+ sym = whocodedsym;
+ } else if (funstr == STR_String("FALSE")) {
+ sym = constsym; constkind = booltype; boolvalue = false;
+ } else if (funstr == STR_String("TRUE")) {
+ sym = constsym; constkind = booltype; boolvalue = true;
+ } else {
+ sym = idsym;
+ //STR_String str;
+ //str.Format("'%s' makes no sense here", (const char*)funstr);
+ //ScanError(str);
+ }
+ } else { // unknown symbol
+ STR_String str;
+ str.Format("Unexpected character '%c'", ch);
+ NextCh();
+ ScanError(str);
+ return;
+ }
+ }
+ }
+}
+
+int CParser::MakeInt() {
+ // returns the integer representation of the value in the global
+ // variable const_as_string
+ // pre: const_as_string contains only numercal chars
+ return atoi(const_as_string);
+}
+
+STR_String CParser::Symbol2Str(int s) {
+ // returns a string representation of of symbol s,
+ // for use in Term when generating an error
+ switch(s) {
+ case errorsym: return "error";
+ case lbracksym: return "(";
+ case rbracksym: return ")";
+ case commasym: return ",";
+ case opsym: return "operator";
+ case constsym: return "constant";
+ case sumsym: return "SUM";
+ case ifsym: return "IF";
+ case whocodedsym: return "WHOMADE";
+ case eolsym: return "end of line";
+ case idsym: return "identifier";
+ default: return "unknown"; // should not happen
+ }
+}
+
+void CParser::Term(int s) {
+ // generates an error if the next symbol isn't the specified symbol s
+ // otherwise, skip the symbol
+ if(s == sym) NextSym();
+ else {
+ STR_String msg;
+ msg.Format("Warning: " + Symbol2Str(s) + " expected\ncontinuing without it");
+
+// AfxMessageBox(msg,MB_ICONERROR);
+
+ trace(msg);
+ }
+}
+
+int CParser::Priority(int optorkind) {
+ // returns the priority of an operator
+ // higher number means higher priority
+ switch(optorkind) {
+ case OPor: return 1;
+ case OPand: return 2;
+ case OPgreater:
+ case OPless:
+ case OPgreaterequal:
+ case OPlessequal:
+ case OPequal:
+ case OPunequal: return 3;
+ case OPplus:
+ case OPminus: return 4;
+ case OPtimes:
+ case OPdivide: return 5;
+ }
+ assert(false);
+ return 0; // should not happen
+}
+
+CExpression *CParser::Ex(int i) {
+ // parses an expression in the imput, starting at priority i, and
+ // returns an CExpression, containing the parsed input
+ CExpression *e1 = NULL, *e2 = NULL;
+ int opkind2;
+
+ if (i < NUM_PRIORITY) {
+ e1 = Ex(i + 1);
+ while ((sym == opsym) && (Priority(opkind) == i)) {
+ opkind2 = opkind;
+ NextSym();
+ e2 = Ex(i + 1);
+ switch(opkind2) {
+ case OPplus: e1 = new COperator2Expr(VALUE_ADD_OPERATOR,e1, e2); break;
+ case OPminus: e1 = new COperator2Expr(VALUE_SUB_OPERATOR,e1, e2); break;
+ case OPtimes: e1 = new COperator2Expr(VALUE_MUL_OPERATOR,e1, e2); break;
+ case OPdivide: e1 = new COperator2Expr(VALUE_DIV_OPERATOR,e1, e2); break;
+ case OPand: e1 = new COperator2Expr(VALUE_AND_OPERATOR,e1, e2); break;
+ case OPor: e1 = new COperator2Expr(VALUE_OR_OPERATOR,e1, e2); break;
+ case OPequal: e1 = new COperator2Expr(VALUE_EQL_OPERATOR,e1, e2); break;
+ case OPunequal: e1 = new COperator2Expr(VALUE_NEQ_OPERATOR,e1, e2); break;
+ case OPgreater: e1 = new COperator2Expr(VALUE_GRE_OPERATOR,e1, e2); break;
+ case OPless: e1 = new COperator2Expr(VALUE_LES_OPERATOR,e1, e2); break;
+ case OPgreaterequal: e1 = new COperator2Expr(VALUE_GEQ_OPERATOR,e1, e2); break;
+ case OPlessequal: e1 = new COperator2Expr(VALUE_LEQ_OPERATOR,e1, e2); break;
+ default: assert(false); break; // should not happen
+ }
+ }
+ } else if (i == NUM_PRIORITY) {
+ if ((sym == opsym)
+ && ( (opkind == OPminus) || (opkind == OPnot) || (opkind == OPplus) )
+ )
+ {
+ NextSym();
+ switch(opkind) {
+ /* +1 is also a valid number! */
+ case OPplus: e1 = new COperator1Expr(VALUE_POS_OPERATOR, Ex(NUM_PRIORITY)); break;
+ case OPminus: e1 = new COperator1Expr(VALUE_NEG_OPERATOR, Ex(NUM_PRIORITY)); break;
+ case OPnot: e1 = new COperator1Expr(VALUE_NOT_OPERATOR, Ex(NUM_PRIORITY)); break;
+ default: {
+ // should not happen
+ e1 = Error("operator +, - or ! expected");
+ }
+ }
+ }
+ else {
+ switch(sym) {
+ case constsym: {
+ switch(constkind) {
+ case booltype:
+ e1 = new CConstExpr(new CBoolValue(boolvalue));
+ break;
+ case inttype:
+ {
+ int temp;
+ temp = atoi(const_as_string);
+ e1 = new CConstExpr(new CIntValue(temp));
+ break;
+ }
+ case floattype:
+ {
+ double temp;
+ temp = atof(const_as_string);
+ e1 = new CConstExpr(new CFloatValue(temp));
+ break;
+ }
+ case stringtype:
+ e1 = new CConstExpr(new CStringValue(const_as_string,""));
+ break;
+ default :
+ assert(false);
+ break;
+ }
+ NextSym();
+ break;
+ }
+ case lbracksym:
+ NextSym();
+ e1 = Ex(1);
+ Term(rbracksym);
+ break;
+ case ifsym:
+ {
+ CExpression *e3;
+ NextSym();
+ Term(lbracksym);
+ e1 = Ex(1);
+ Term(commasym);
+ e2 = Ex(1);
+ if (sym == commasym) {
+ NextSym();
+ e3 = Ex(1);
+ } else {
+ e3 = new CConstExpr(new CEmptyValue());
+ }
+ Term(rbracksym);
+ e1 = new CIfExpr(e1, e2, e3);
+ break;
+ }
+ case idsym:
+ {
+ e1 = new CIdentifierExpr(const_as_string,m_identifierContext);
+ NextSym();
+
+ break;
+ }
+ case errorsym:
+ {
+ assert(!e1);
+ STR_String errtext="[no info]";
+ if (errmsg)
+ {
+ CValue* errmsgval = errmsg->Calculate();
+ errtext=errmsgval->GetText();
+ errmsgval->Release();
+
+ //e1 = Error(errmsg->Calculate()->GetText());//new CConstExpr(errmsg->Calculate());
+
+ if ( !(errmsg->Release()) )
+ {
+ errmsg=NULL;
+ } else {
+ // does this happen ?
+ assert ("does this happen");
+ }
+ }
+ e1 = Error(errtext);
+
+ break;
+ }
+ default:
+ NextSym();
+ //return Error("Expression expected");
+ assert(!e1);
+ e1 = Error("Expression expected");
+ }
+ }
+ }
+ return e1;
+}
+
+CExpression *CParser::Expr() {
+ // parses an expression in the imput, and
+ // returns an CExpression, containing the parsed input
+ return Ex(1);
+}
+
+CExpression* CParser::ProcessText
+(STR_String intext) {
+
+ // and parses the string in intext and returns it.
+
+
+ CExpression* expr;
+ text = intext;
+
+
+ chcount = 0;
+ if (text.Length() == 0) {
+ return NULL;
+ }
+
+ ch = text[0];
+ /*if (ch != '=') {
+ expr = new CConstExpr(new CStringValue(text));
+ *dependant = deplist;
+ return expr;
+ } else
+ */
+ // NextCh();
+ NextSym();
+ expr = Expr();
+ if (sym != eolsym) {
+ CExpression* oldexpr = expr;
+ expr = new COperator2Expr(VALUE_ADD_OPERATOR,
+ oldexpr, Error(STR_String("Extra characters after expression")));//new CConstExpr(new CErrorValue("Extra characters after expression")));
+ }
+ if (errmsg)
+ errmsg->Release();
+
+ return expr;
+}
+
+
+
+float CParser::GetFloat(STR_String txt)
+{
+ // returns parsed text into a float
+ // empty string returns -1
+
+// AfxMessageBox("parsed string="+txt);
+ CValue* val=NULL;
+ float result=-1;
+// String tmpstr;
+
+ CExpression* expr = ProcessText(txt);
+ if (expr) {
+ val = expr->Calculate();
+ result=val->GetNumber();
+
+
+
+ val->Release();
+ expr->Release();
+ }
+// tmpstr.Format("parseresult=%g",result);
+// AfxMessageBox(tmpstr);
+ return result;
+}
+
+CValue* CParser::GetValue(STR_String txt, bool bFallbackToText)
+{
+ // returns parsed text into a value,
+ // empty string returns NULL value !
+ // if bFallbackToText then unparsed stuff is put into text
+
+ CValue* result=NULL;
+ CExpression* expr = ProcessText(txt);
+ if (expr) {
+ result = expr->Calculate();
+ expr->Release();
+ }
+ if (result)
+ {
+ // if the parsed stuff lead to an errorvalue, don't return errors, just NULL
+ if (result->IsError()) {
+ result->Release();
+ result=NULL;
+ if (bFallbackToText) {
+ if (txt.Length()>0)
+ {
+ result = new CStringValue(txt,"");
+ }
+ }
+ }
+ }
+ return result;
+}
+
+void CParser::SetContext(CValue* context)
+{
+ if (m_identifierContext)
+ {
+ m_identifierContext->Release();
+ }
+ m_identifierContext = context;
+}
+
+
+
+
+PyObject* CParserPyMake(PyObject* ignored,PyObject* args)
+{
+ char* txt;
+ Py_Try(PyArg_ParseTuple(args,"s",&txt));
+ CParser parser;
+ CExpression* expr = parser.ProcessText(txt);
+ CValue* val = expr->Calculate();
+ expr->Release();
+ return val;
+}
+
+static PyMethodDef CParserMethods[] =
+{
+ { "calc", CParserPyMake , Py_NEWARGS},
+ { NULL,NULL} // Sentinel
+};
+
+extern "C" {
+ void initExpressionModule(void)
+ {
+ Py_InitModule("Expression",CParserMethods);
+ }
+}
+
diff --git a/source/gameengine/Expressions/InputParser.h b/source/gameengine/Expressions/InputParser.h
new file mode 100644
index 00000000000..43832f9c350
--- /dev/null
+++ b/source/gameengine/Expressions/InputParser.h
@@ -0,0 +1,105 @@
+/*
+ * Parser.h: interface for the CParser class.
+ * Eindhoven University of Technology 1997
+ * OOPS team (Serge vd Boom, Erwin Coumans, Tom Geelen, Wynke Stuylemeier)
+ * $Id$
+ * 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.
+ *
+ */
+#ifndef __INPUTPARSER_H__
+#define __INPUTPARSER_H__
+
+class CParser;
+#include "Expression.h"
+
+
+class CParser
+{
+public:
+ CParser();
+ virtual ~CParser();
+
+ float GetFloat(STR_String txt);
+ CValue* GetValue(STR_String txt, bool bFallbackToText=false);
+ CExpression* ProcessText(STR_String intext);
+ void SetContext(CValue* context);
+
+private:
+ enum symbols {
+ errorsym,
+ lbracksym,
+ rbracksym,
+ cellsym,
+ commasym,
+ opsym,
+ constsym,
+ sumsym,
+ ifsym,
+ whocodedsym,
+ eolsym,
+ idsym
+ }; // all kinds of symbols
+
+ enum optype {
+ OPplus,
+ OPminus,
+ OPtimes,
+ OPdivide,
+ OPand,
+ OPor,
+ OPequal,
+ OPunequal,
+ OPgreater,
+ OPless,
+ OPgreaterequal,
+ OPlessequal,
+ OPnot
+ }; // all kinds of operators
+
+ enum consttype {
+ booltype,
+ inttype,
+ floattype,
+ stringtype
+ }; // all kinds of constants
+
+ int sym, // current symbol
+ opkind, // kind of operator, if symbol is an operator
+ constkind; // kind of operator, if symbol is a constant
+
+ char ch; // current character
+ int chcount; // index to character in input string
+ CExpression *errmsg; // contains a errormessage, if scanner error
+
+ STR_String text, // contains a copy of the original text
+ const_as_string; // string representation of the symbol, if symbol is a constant
+ bool boolvalue; // value of the boolean, if symbol is a constant of type boolean
+ CValue* m_identifierContext;// context in which identifiers are looked up
+
+
+ void ScanError(STR_String str);
+ CExpression* Error(STR_String str);
+ void NextCh();
+ void TermChar(char c);
+ void DigRep();
+ void CharRep();
+ void GrabString(int start);
+ void NextSym();
+ int MakeInt();
+ STR_String Symbol2Str(int s);
+ void Term(int s);
+ int Priority(int optor);
+ CExpression *Ex(int i);
+ CExpression *Expr();
+
+};
+
+#endif
diff --git a/source/gameengine/Expressions/IntValue.cpp b/source/gameengine/Expressions/IntValue.cpp
new file mode 100644
index 00000000000..591fe76cd48
--- /dev/null
+++ b/source/gameengine/Expressions/IntValue.cpp
@@ -0,0 +1,325 @@
+// IntValue.cpp: implementation of the CIntValue 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 "IntValue.h"
+#include "ErrorValue.h"
+#include "FloatValue.h"
+#include "BoolValue.h"
+#include "StringValue.h"
+#include "VoidValue.h"
+//#include "FactoryManager.h"
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CIntValue::CIntValue()
+/*
+pre: false
+effect: constructs a new CIntValue
+*/
+{
+
+#ifdef _DEBUG_
+ m_textval = "Int illegal constructor";
+#endif
+ m_pstrRep=NULL;
+}
+
+
+
+CIntValue::CIntValue(int innie)
+/*
+pre:
+effect: constructs a new CIntValue containing int innie
+*/
+{
+ m_int = innie;
+ m_pstrRep=NULL;
+}
+
+
+
+CIntValue::CIntValue(int innie,STR_String name,AllocationTYPE alloctype)
+{
+ m_int = innie;
+ SetName(name);
+
+ if (alloctype==CValue::STACKVALUE)
+ {
+ CValue::DisableRefCount();
+ }
+ m_pstrRep=NULL;
+
+}
+
+
+
+CIntValue::~CIntValue()
+/*
+pre:
+effect: deletes the object
+*/
+{
+ if (m_pstrRep)
+ delete m_pstrRep;
+}
+
+
+
+CValue* CIntValue::Calc(VALUE_OPERATOR op, CValue *val)
+/*
+pre:
+ret: a new object containing the result of applying operator op to this
+object and val
+*/
+{
+ //return val->CalcInt(op, this);
+ switch (op) {
+ case VALUE_POS_OPERATOR:
+ return new CIntValue (m_int);
+ break;
+ case VALUE_NEG_OPERATOR:
+ return new CIntValue (-m_int);
+ break;
+ case VALUE_NOT_OPERATOR:
+ return new CErrorValue (op2str(op) + "only allowed on booleans");
+ break;
+ case VALUE_AND_OPERATOR:
+ case VALUE_OR_OPERATOR:
+ return new CErrorValue(val->GetText() + op2str(op) + "only allowed on booleans");
+ break;
+ default:
+ return val->CalcFinal(VALUE_INT_TYPE, op, this);
+ break;
+ }
+}
+
+
+
+CValue* CIntValue::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val)
+/*
+pre: the type of val is dtype
+ret: a new object containing the result of applying operator op to val and
+this object
+*/
+{
+ CValue *ret;
+
+ switch(dtype) {
+ case VALUE_EMPTY_TYPE:
+ case VALUE_INT_TYPE:
+ {
+ switch (op) {
+ case VALUE_ADD_OPERATOR:
+ ret = new CIntValue (((CIntValue *) val)->GetInt() + m_int);
+ break;
+ case VALUE_SUB_OPERATOR:
+ ret = new CIntValue (((CIntValue *) val)->GetInt() - m_int);
+ break;
+ case VALUE_MUL_OPERATOR:
+ ret = new CIntValue (((CIntValue *) val)->GetInt() * m_int);
+ break;
+ case VALUE_DIV_OPERATOR:
+ if (m_int == 0)
+ {
+ if (val->GetNumber() == 0)
+ {
+ ret = new CErrorValue("Not a Number");
+ } else
+ {
+ ret = new CErrorValue("Division by zero");
+ }
+ }
+ else
+ ret = new CIntValue (((CIntValue *) val)->GetInt() / m_int);
+ break;
+ case VALUE_EQL_OPERATOR:
+ ret = new CBoolValue(((CIntValue *) val)->GetInt() == m_int);
+ break;
+ case VALUE_NEQ_OPERATOR:
+ ret = new CBoolValue(((CIntValue *) val)->GetInt() != m_int);
+ break;
+ case VALUE_GRE_OPERATOR:
+ ret = new CBoolValue(((CIntValue *) val)->GetInt() > m_int);
+ break;
+ case VALUE_LES_OPERATOR:
+ ret = new CBoolValue(((CIntValue *) val)->GetInt() < m_int);
+ break;
+ case VALUE_GEQ_OPERATOR:
+ ret = new CBoolValue(((CIntValue *) val)->GetInt() >= m_int);
+ break;
+ case VALUE_LEQ_OPERATOR:
+ ret = new CBoolValue(((CIntValue *) val)->GetInt() <= m_int);
+ break;
+ case VALUE_NEG_OPERATOR:
+ ret = new CIntValue (-m_int);
+ break;
+ case VALUE_POS_OPERATOR:
+ ret = new CIntValue (m_int);
+ break;
+ default:
+ ret = new CErrorValue("illegal operator. please send a bug report.");
+ break;
+ }
+ break;
+ }
+ case VALUE_FLOAT_TYPE:
+ {
+ switch (op) {
+ case VALUE_ADD_OPERATOR:
+ ret = new CFloatValue (((CFloatValue *) val)->GetFloat() + m_int);
+ break;
+ case VALUE_SUB_OPERATOR:
+ ret = new CFloatValue (((CFloatValue *) val)->GetFloat() - m_int);
+ break;
+ case VALUE_MUL_OPERATOR:
+ ret = new CFloatValue (((CFloatValue *) val)->GetFloat() * m_int);
+ break;
+ case VALUE_DIV_OPERATOR:
+ if (m_int == 0)
+ ret = new CErrorValue("Division by zero");
+ else
+ ret = new CFloatValue (((CFloatValue *) val)->GetFloat() / m_int);
+ break;
+ case VALUE_EQL_OPERATOR:
+ ret = new CBoolValue(((CFloatValue *) val)->GetFloat() == m_int);
+ break;
+ case VALUE_NEQ_OPERATOR:
+ ret = new CBoolValue(((CFloatValue *) val)->GetFloat() != m_int);
+ break;
+ case VALUE_GRE_OPERATOR:
+ ret = new CBoolValue(((CFloatValue *) val)->GetFloat() > m_int);
+ break;
+ case VALUE_LES_OPERATOR:
+ ret = new CBoolValue(((CFloatValue *) val)->GetFloat() < m_int);
+ break;
+ case VALUE_GEQ_OPERATOR:
+ ret = new CBoolValue(((CFloatValue *) val)->GetFloat() >= m_int);
+ break;
+ case VALUE_LEQ_OPERATOR:
+ ret = new CBoolValue(((CFloatValue *) val)->GetFloat() <= m_int);
+ break;
+ default:
+ ret = new CErrorValue("illegal operator. please send a bug report.");
+ break;
+ }
+ break;
+ }
+ case VALUE_STRING_TYPE:
+ {
+ switch(op) {
+ case VALUE_ADD_OPERATOR:
+ ret = new CStringValue(val->GetText() + GetText(),"");
+ break;
+ case VALUE_EQL_OPERATOR:
+ case VALUE_NEQ_OPERATOR:
+ case VALUE_GRE_OPERATOR:
+ case VALUE_LES_OPERATOR:
+ case VALUE_GEQ_OPERATOR:
+ case VALUE_LEQ_OPERATOR:
+ ret = new CErrorValue("[Cannot compare string with integer]" + op2str(op) + GetText());
+ break;
+ default:
+ ret = new CErrorValue("[operator not allowed on strings]" + op2str(op) + GetText());
+ break;
+ }
+ break;
+ }
+ case VALUE_BOOL_TYPE:
+ ret = new CErrorValue("[operator not valid on boolean and integer]" + op2str(op) + GetText());
+ break;
+ /*
+ case VALUE_EMPTY_TYPE:
+ {
+ switch(op) {
+
+ case VALUE_ADD_OPERATOR:
+ ret = new CIntValue (m_int);
+ break;
+ case VALUE_SUB_OPERATOR:
+ ret = new CIntValue (-m_int);
+ break;
+ default:
+ {
+ ret = new CErrorValue(op2str(op) + GetText());
+ }
+ }
+ break;
+ }
+ */
+ case VALUE_ERROR_TYPE:
+ ret = new CErrorValue(val->GetText() + op2str(op) + GetText());
+ break;
+ default:
+ ret = new CErrorValue("illegal type. contact your dealer (if any)");
+ break;
+ }
+ return ret;
+}
+
+
+
+int CIntValue::GetInt()
+/*
+pre:
+ret: the int stored in the object
+*/
+{
+ return m_int;
+}
+
+
+
+float CIntValue::GetNumber()
+{
+ return (float) m_int;
+}
+
+
+
+const STR_String & CIntValue::GetText()
+{
+ if (!m_pstrRep)
+ m_pstrRep=new STR_String();
+ m_pstrRep->Format("%d",m_int);
+
+ return *m_pstrRep;
+}
+
+
+
+CValue* CIntValue::GetReplica() {
+ CIntValue* replica = new CIntValue(*this);
+ CValue::AddDataToReplica(replica);
+ replica->m_pstrRep = NULL;
+
+ return replica;
+}
+
+
+
+void CIntValue::SetValue(CValue* newval)
+{
+ m_int = (int)newval->GetNumber();
+ SetModified(true);
+}
+
+
+
+PyObject* CIntValue::ConvertValueToPython()
+{
+ return PyInt_FromLong(m_int);
+} \ No newline at end of file
diff --git a/source/gameengine/Expressions/IntValue.h b/source/gameengine/Expressions/IntValue.h
new file mode 100644
index 00000000000..8174c863895
--- /dev/null
+++ b/source/gameengine/Expressions/IntValue.h
@@ -0,0 +1,60 @@
+/*
+ * IntValue.h: interface for the CIntValue class.
+ * $Id$
+ * 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.
+ *
+ */
+#if !defined _INTVALUE_H
+#define _INTVALUE_H
+
+
+#include "Value.h"
+
+
+class CIntValue : public CPropValue
+{
+ //PLUGIN_DECLARE_SERIAL (CIntValue,CValue)
+
+public:
+ virtual const STR_String& GetText();
+ virtual float GetNumber();
+
+ int GetInt();
+ CIntValue();
+ CIntValue(int innie);
+ CIntValue(int innie,
+ STR_String name,
+ AllocationTYPE alloctype=CValue::HEAPVALUE);
+
+ virtual CValue* Calc(VALUE_OPERATOR op,
+ CValue *val);
+
+ virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype,
+ VALUE_OPERATOR op,
+ CValue *val);
+
+ virtual void SetValue(CValue* newval);
+
+ void Configure(CValue* menuvalue);
+ void AddConfigurationData(CValue* menuvalue);
+ virtual CValue* GetReplica();
+ virtual PyObject* ConvertValueToPython();
+
+protected:
+ virtual ~CIntValue();
+
+private:
+ int m_int;
+ STR_String* m_pstrRep;
+
+};
+
+#endif // !defined _INTVALUE_H
diff --git a/source/gameengine/Expressions/KX_HashedPtr.cpp b/source/gameengine/Expressions/KX_HashedPtr.cpp
new file mode 100644
index 00000000000..7d573ebc37d
--- /dev/null
+++ b/source/gameengine/Expressions/KX_HashedPtr.cpp
@@ -0,0 +1,58 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+
+#include "KX_HashedPtr.h"
+
+unsigned int KX_Hash(unsigned int inDWord)
+{
+ unsigned int key = inDWord;
+ key += ~(key << 16);
+ key ^= (key >> 5);
+ key += (key << 3);
+ key ^= (key >> 13);
+ key += ~(key << 9);
+ key ^= (key >> 17);
+ return key;
+};
+
+
+
+CHashedPtr::CHashedPtr(void* val) : m_valptr(val)
+{
+}
+
+
+
+unsigned int CHashedPtr::hash() const
+{
+ return KX_Hash((unsigned int) m_valptr);
+}
diff --git a/source/gameengine/Expressions/KX_HashedPtr.h b/source/gameengine/Expressions/KX_HashedPtr.h
new file mode 100644
index 00000000000..eccd23991bc
--- /dev/null
+++ b/source/gameengine/Expressions/KX_HashedPtr.h
@@ -0,0 +1,53 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef __KX_HASHEDPTR
+#define __KX_HASHEDPTR
+
+unsigned int KX_Hash(unsigned int inDWord);
+
+
+class CHashedPtr
+{
+ void* m_valptr;
+
+public:
+ CHashedPtr(void* val);
+
+ unsigned int hash() const;
+
+ inline friend bool operator ==( const CHashedPtr & rhs,const CHashedPtr & lhs)
+ {
+ return rhs.m_valptr == lhs.m_valptr;
+ }
+};
+
+#endif //__KX_HASHEDPTR
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
diff --git a/source/gameengine/Expressions/ListValue.h b/source/gameengine/Expressions/ListValue.h
new file mode 100644
index 00000000000..fce4e9da8c2
--- /dev/null
+++ b/source/gameengine/Expressions/ListValue.h
@@ -0,0 +1,77 @@
+/*
+ * ListValue.h: interface for the CListValue class.
+ * $Id$
+ * 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.
+ *
+ */
+
+#if !defined _LISTVALUE_H
+#define _LISTVALUE_H
+
+
+#include "Value.h"
+
+class CListValue : public CPropValue
+{
+ Py_Header;
+ //PLUGIN_DECLARE_SERIAL (CListValue,CValue)
+
+public:
+ CListValue(PyTypeObject *T = &Type);
+ virtual ~CListValue();
+
+ void AddConfigurationData(CValue* menuvalue);
+ void Configure(CValue* menuvalue);
+ void Add(CValue* value);
+
+ /** @attention not implemented yet :( */
+ virtual CValue* Calc(VALUE_OPERATOR op,CValue *val);
+ virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype,
+ VALUE_OPERATOR op,
+ CValue* val);
+ virtual float GetNumber();
+ virtual CValue* GetReplica();
+
+public:
+ void MergeList(CListValue* otherlist);
+ bool RemoveValue(CValue* val);
+ void SetReleaseOnDestruct(bool bReleaseContents);
+ bool SearchValue(CValue* val);
+
+ CValue* FindValue(const STR_String & name);
+
+ void ReleaseAndRemoveAll();
+ virtual void SetModified(bool bModified);
+ virtual inline bool IsModified();
+ void Remove(int i);
+ void Resize(int num);
+ void SetValue(int i,CValue* val);
+ CValue* GetValue(int i){ assertd(i < m_pValueArray.size()); return m_pValueArray[i];}
+ int GetCount() { return m_pValueArray.size();};
+ virtual const STR_String & GetText();
+
+ bool CheckEqual(CValue* first,CValue* second);
+
+ virtual PyObject* _getattr(char *attr);
+
+ KX_PYMETHOD(CListValue,append);
+ KX_PYMETHOD(CListValue,reverse);
+ KX_PYMETHOD(CListValue,index);
+ KX_PYMETHOD(CListValue,count);
+
+
+private:
+
+ std::vector<CValue*> m_pValueArray;
+ bool m_bReleaseContents;
+};
+
+#endif // !defined _LISTVALUE_H
diff --git a/source/gameengine/Expressions/Makefile b/source/gameengine/Expressions/Makefile
new file mode 100644
index 00000000000..9199698d3e9
--- /dev/null
+++ b/source/gameengine/Expressions/Makefile
@@ -0,0 +1,45 @@
+#
+# $Id$
+#
+# ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version. The Blender
+# Foundation also sells licenses for use in proprietary software under
+# the Blender License. See http://www.blender.org/BL/ for information
+# about this.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+# The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+# All rights reserved.
+#
+# The Original Code is: all of this file.
+#
+# Contributor(s): none yet.
+#
+# ***** END GPL/BL DUAL LICENSE BLOCK *****
+#
+#
+
+LIBNAME = expression
+DIR = $(OCGDIR)/gameengine/$(LIBNAME)
+
+include nan_compile.mk
+
+CCFLAGS += $(LEVEL_1_CPP_WARNINGS)
+
+CPPFLAGS += -I$(NAN_PYTHON)/include/python$(NAN_PYTHON_VERSION)
+CPPFLAGS += -I$(NAN_STRING)/include
+CPPFLAGS += -I../../kernel/gen_system
+CPPFLAGS += -I../Ketsji
+
diff --git a/source/gameengine/Expressions/Operator1Expr.cpp b/source/gameengine/Expressions/Operator1Expr.cpp
new file mode 100644
index 00000000000..91a3a02aabe
--- /dev/null
+++ b/source/gameengine/Expressions/Operator1Expr.cpp
@@ -0,0 +1,148 @@
+// Operator1Expr.cpp: implementation of the COperator1Expr 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 "Operator1Expr.h"
+//#include "FactoryManager.h"
+#include "EmptyValue.h"
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+COperator1Expr::COperator1Expr()
+/*
+pre:
+effect: constucts an empty COperator1Expr
+*/
+{
+ m_lhs = NULL;
+}
+
+COperator1Expr::COperator1Expr(VALUE_OPERATOR op, CExpression * lhs)
+/*
+pre:
+effect: constucts a COperator1Expr with op and lhs in it
+*/
+{
+ m_lhs = lhs;
+ m_op = op;
+}
+
+COperator1Expr::~COperator1Expr()
+/*
+pre:
+effect: deletes the object
+*/
+{
+ if (m_lhs) m_lhs->Release();
+}
+
+CValue * COperator1Expr::Calculate()
+/*
+pre:
+ret: a new object containing the result of applying the operator m_op to the
+ value of m_lhs
+*/
+{
+ CValue *ret;
+ CValue *temp = m_lhs->Calculate();
+ CValue* empty = new CEmptyValue();
+ ret = empty->Calc(m_op, temp);
+ empty->Release();
+ temp->Release();
+
+ return ret;
+}
+
+/*
+bool COperator1Expr::IsInside(float x, float y, float z,bool bBorderInclude)
+{
+
+ bool result = true;
+ switch (m_op)
+ {
+
+ case VALUE_ADD_OPERATOR:
+ {
+
+ if (m_lhs)
+ {
+ result = result || m_lhs->IsInside(x,y,z,bBorderInclude);
+ }
+ break;
+ }
+ case VALUE_SUB_OPERATOR:
+ {
+ result = true;
+ if (m_lhs)
+ {
+ result = result && (!m_lhs->IsInside(x,y,z,bBorderInclude));
+ }
+ break;
+ }
+ }
+ return result;
+}
+
+*/
+bool COperator1Expr::NeedsRecalculated() {
+
+ return m_lhs->NeedsRecalculated();
+
+}
+
+CExpression* COperator1Expr::CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks) {
+
+ CExpression* newlhs = m_lhs->CheckLink(brokenlinks);
+
+ if (newlhs)
+ {
+ if (newlhs==m_lhs) {
+ // not changed
+ } else {
+ // changed
+ //numchanges++;
+ newlhs->AddRef();
+
+ //m_lhs->Release();
+ brokenlinks.push_back(new CBrokenLinkInfo(&m_lhs,m_lhs));
+
+ m_lhs = newlhs;
+ }
+ return this;
+ } else {
+ //numchanges++;
+ AddRef();
+
+ return Release();
+ }
+
+}
+
+void COperator1Expr::BroadcastOperators(VALUE_OPERATOR op)
+{
+ if (m_lhs)
+ m_lhs->BroadcastOperators(m_op);
+}
+
+
+
+
+bool COperator1Expr::MergeExpression(CExpression *otherexpr)
+{
+ if (m_lhs)
+ return m_lhs->MergeExpression(otherexpr);
+
+ assertd(false); // should not get here, expression is not compatible for merge
+ return false;
+}
diff --git a/source/gameengine/Expressions/Operator1Expr.h b/source/gameengine/Expressions/Operator1Expr.h
new file mode 100644
index 00000000000..9362c568dc9
--- /dev/null
+++ b/source/gameengine/Expressions/Operator1Expr.h
@@ -0,0 +1,53 @@
+/*
+ * Operator1Expr.h: interface for the COperator1Expr class.
+ * $Id$
+ * 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.
+ *
+ */
+
+#if !defined(AFX_OPERATOR1EXPR_H__A1653901_BF41_11D1_A51C_00A02472FC58__INCLUDED_)
+#define AFX_OPERATOR1EXPR_H__A1653901_BF41_11D1_A51C_00A02472FC58__INCLUDED_
+
+
+
+#include "Expression.h"
+
+class COperator1Expr : public CExpression
+{
+ //PLUGIN_DECLARE_SERIAL_EXPRESSION (COperator1Expr,CExpression)
+
+
+
+public:
+ virtual bool MergeExpression(CExpression* otherexpr);
+ void virtual BroadcastOperators(VALUE_OPERATOR op);
+
+ virtual unsigned char GetExpressionID() { return COPERATOR1EXPRESSIONID;};
+ CExpression* CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks);
+ //virtual bool IsInside(float x,float y,float z,bool bBorderInclude = true);
+ virtual bool NeedsRecalculated();
+ void ClearModified() {
+ if (m_lhs)
+ m_lhs->ClearModified();
+ }
+ virtual CValue* Calculate();
+ COperator1Expr(VALUE_OPERATOR op, CExpression *lhs);
+ COperator1Expr();
+ virtual ~COperator1Expr();
+
+
+
+private:
+ VALUE_OPERATOR m_op;
+ CExpression * m_lhs;
+};
+
+#endif // !defined(AFX_OPERATOR1EXPR_H__A1653901_BF41_11D1_A51C_00A02472FC58__INCLUDED_)
diff --git a/source/gameengine/Expressions/Operator2Expr.cpp b/source/gameengine/Expressions/Operator2Expr.cpp
new file mode 100644
index 00000000000..33223b2ae3d
--- /dev/null
+++ b/source/gameengine/Expressions/Operator2Expr.cpp
@@ -0,0 +1,275 @@
+// Operator2Expr.cpp: implementation of the COperator2Expr 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.
+ *
+ */
+// 31 dec 1998 - big update: try to use the cached data for updating, instead of
+// rebuilding completely it from left and right node. Modified flags and bounding boxes
+// have to do the trick
+// when expression is cached, there will be a call to UpdateCalc() instead of Calc()
+
+
+
+#include "Operator2Expr.h"
+#include "StringValue.h"
+#include "VoidValue.h"
+//#include "FactoryManager.h"
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+COperator2Expr::COperator2Expr(VALUE_OPERATOR op, CExpression *lhs, CExpression *rhs)
+:
+m_cached_calculate(NULL),
+m_op(op),
+m_lhs(lhs),
+m_rhs(rhs)
+/*
+pre:
+effect: constucts a COperator2Expr with op, lhs and rhs in it
+*/
+{
+
+}
+
+COperator2Expr::COperator2Expr():
+m_cached_calculate(NULL),
+m_lhs(NULL),
+m_rhs(NULL)
+
+/*
+pre:
+effect: constucts an empty COperator2Expr
+*/
+{
+
+}
+
+COperator2Expr::~COperator2Expr()
+/*
+pre:
+effect: deletes the object
+*/
+{
+ if (m_lhs)
+ m_lhs->Release();
+ if (m_rhs)
+ m_rhs->Release();
+ if (m_cached_calculate)
+ m_cached_calculate->Release();
+
+}
+CValue* COperator2Expr::Calculate()
+/*
+pre:
+ret: a new object containing the result of applying operator m_op to m_lhs
+and m_rhs
+*/
+{
+
+ bool leftmodified,rightmodified;
+ leftmodified = m_lhs->NeedsRecalculated();
+ rightmodified = m_rhs->NeedsRecalculated();
+
+ // if no modifications on both left and right subtree, and result is already calculated
+ // then just return cached result...
+ if (!leftmodified && !rightmodified && (m_cached_calculate))
+ {
+ // not modified, just return m_cached_calculate
+ } else {
+ // if not yet calculated, or modified...
+
+
+ if (m_cached_calculate) {
+ m_cached_calculate->Release();
+ m_cached_calculate=NULL;
+ }
+
+ CValue* ffleft = m_lhs->Calculate();
+ CValue* ffright = m_rhs->Calculate();
+
+ ffleft->SetOwnerExpression(this);//->m_pOwnerExpression=this;
+ ffright->SetOwnerExpression(this);//->m_pOwnerExpression=this;
+
+ m_cached_calculate = ffleft->Calc(m_op,ffright);
+
+ //if (m_cached_calculate)
+ // m_cached_calculate->Action(CValue::SETOWNEREXPR,&CVoidValue(this,false,CValue::STACKVALUE));
+
+ ffleft->Release();
+ ffright->Release();
+ }
+
+ return m_cached_calculate->AddRef();
+
+}
+
+/*
+bool COperator2Expr::IsInside(float x, float y, float z,bool bBorderInclude)
+{
+ bool inside;
+ inside = false;
+
+ switch (m_op)
+ {
+ case VALUE_ADD_OPERATOR: {
+ // inside = first || second; // optimized with early out if first is inside
+ // todo: calculate smallest leaf first ! is much faster...
+
+ bool second;//first ;//,second;
+
+ //first = m_lhs->IsInside(x,y,z) ;
+ second = m_rhs->IsInside(x,y,z,bBorderInclude) ;
+ if (second)
+ return true; //early out
+
+ // second = m_rhs->IsInside(x,y,z) ;
+
+ return m_lhs->IsInside(x,y,z,bBorderInclude) ;
+
+ break;
+ }
+
+ case VALUE_SUB_OPERATOR: {
+ //inside = first && !second; // optimized with early out
+ // todo: same as with add_operator: calc smallest leaf first
+
+ bool second;//first ;//,second;
+ //first = m_lhs->IsInside(x,y,z) ;
+ second = m_rhs->IsInside(x,y,z,bBorderInclude);
+ if (second)
+ return false;
+
+ // second space get subtracted -> negate!
+ //second = m_rhs->IsInside(x,y,z);
+
+ return (m_lhs->IsInside(x,y,z,bBorderInclude));
+
+
+ break;
+ }
+ default:{
+ assert(false);
+ // not yet implemented, only add or sub csg operations
+ }
+ }
+
+ return inside;
+}
+
+
+
+bool COperator2Expr::IsRightInside(float x, float y, float z,bool bBorderInclude) {
+
+ return m_rhs->IsInside(x,y,z,bBorderInclude) ;
+
+}
+
+bool COperator2Expr::IsLeftInside(float x, float y, float z,bool bBorderInclude) {
+ return m_lhs->IsInside(x,y,z,bBorderInclude);
+}
+*/
+bool COperator2Expr::NeedsRecalculated() {
+ // added some lines, just for debugging purposes, it could be a one-liner :)
+ //bool modleft
+ //bool modright;
+ assertd(m_lhs);
+ assertd(m_rhs);
+
+ //modright = m_rhs->NeedsRecalculated();
+ if (m_rhs->NeedsRecalculated()) // early out
+ return true;
+ return m_lhs->NeedsRecalculated();
+ //modleft = m_lhs->NeedsRecalculated();
+ //return (modleft || modright);
+
+}
+
+
+
+CExpression* COperator2Expr::CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks) {
+// if both children are 'dead', return NULL
+// if only one child is alive, return that child
+// if both childresn are alive, return this
+
+
+// bool leftalive = true,rightalive=true;
+ /* Does this mean the function will always bomb? */
+ assertd(false);
+ assert(m_lhs);
+ assert(m_rhs);
+/*
+ if (m_cached_calculate)
+ m_cached_calculate->Action(CValue::REFRESH_CACHE);
+
+ CExpression* newlhs = m_lhs->CheckLink(brokenlinks);
+ CExpression* newrhs = m_rhs->CheckLink(brokenlinks);
+
+ if (m_lhs != newlhs)
+ {
+ brokenlinks.push_back(new CBrokenLinkInfo(&m_lhs,m_lhs));
+ }
+
+ if (m_rhs != newrhs)
+ {
+ brokenlinks.push_back(new CBrokenLinkInfo(&m_rhs,m_rhs));
+ }
+
+
+
+ m_lhs = newlhs;
+ m_rhs = newrhs;
+
+ if (m_lhs && m_rhs) {
+ return this;
+ }
+
+ AddRef();
+ if (m_lhs)
+ return Release(m_lhs->AddRef());
+
+ if (m_rhs)
+ return Release(m_rhs->AddRef());
+/
+
+ */
+ return Release();
+
+
+
+}
+
+
+bool COperator2Expr::MergeExpression(CExpression *otherexpr)
+{
+ if (m_lhs)
+ {
+ if (m_lhs->GetExpressionID() == CExpression::CCONSTEXPRESSIONID)
+ {
+ // cross fingers ;) replace constexpr by new tree...
+ m_lhs->Release();
+ m_lhs = otherexpr->AddRef();
+ return true;
+ }
+ }
+
+ assertd(false);
+ return false;
+}
+
+
+void COperator2Expr::BroadcastOperators(VALUE_OPERATOR op)
+{
+ if (m_lhs)
+ m_lhs->BroadcastOperators(m_op);
+ if (m_rhs)
+ m_rhs->BroadcastOperators(m_op);
+}
diff --git a/source/gameengine/Expressions/Operator2Expr.h b/source/gameengine/Expressions/Operator2Expr.h
new file mode 100644
index 00000000000..7e1dc3ed250
--- /dev/null
+++ b/source/gameengine/Expressions/Operator2Expr.h
@@ -0,0 +1,59 @@
+/*
+ * Operator2Expr.h: interface for the COperator2Expr class.
+ * $Id$
+ * 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.
+ *
+ */
+
+#if !defined _OPERATOR2EXPR_H
+#define _OPERATOR2EXPR_H
+
+
+#include "Expression.h"
+#include "Value.h" // Added by ClassView
+
+
+class COperator2Expr : public CExpression
+{
+ //PLUGIN_DECLARE_SERIAL_EXPRESSION (COperator2Expr,CExpression)
+
+public:
+ virtual bool MergeExpression(CExpression* otherexpr);
+ virtual unsigned char GetExpressionID() { return COPERATOR2EXPRESSIONID;};
+ virtual void BroadcastOperators(VALUE_OPERATOR op);
+ CExpression* CheckLink(std::vector<CBrokenLinkInfo*>& brokenlinks);
+ //virtual bool IsInside(float x,float y,float z,bool bBorderInclude=true);
+ //virtual bool IsLeftInside(float x,float y,float z,bool bBorderInclude);
+ //virtual bool IsRightInside(float x,float y,float z,bool bBorderInclude);
+ bool NeedsRecalculated();
+ void ClearModified() {
+ if (m_lhs)
+ m_lhs->ClearModified();
+ if (m_rhs)
+ m_rhs->ClearModified();
+ }
+ virtual CValue* Calculate();
+ COperator2Expr(VALUE_OPERATOR op, CExpression *lhs, CExpression *rhs);
+ COperator2Expr();
+ virtual ~COperator2Expr();
+
+
+protected:
+ CExpression * m_rhs;
+ CExpression * m_lhs;
+ CValue* m_cached_calculate; // cached result
+
+private:
+ VALUE_OPERATOR m_op;
+
+};
+
+#endif // !defined _OPERATOR2EXPR_H
diff --git a/source/gameengine/Expressions/PyObjectPlus.cpp b/source/gameengine/Expressions/PyObjectPlus.cpp
new file mode 100644
index 00000000000..7b93b1d4daa
--- /dev/null
+++ b/source/gameengine/Expressions/PyObjectPlus.cpp
@@ -0,0 +1,157 @@
+/**
+ * $Id$
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+
+#ifndef NO_EXP_PYTHON_EMBEDDING
+
+/*------------------------------
+ * PyObjectPlus cpp
+ *
+ * C++ library routines for Crawl 3.2
+ *
+ * Derived from work by
+ * David Redish
+ * graduate student
+ * Computer Science Department
+ * Carnegie Mellon University (CMU)
+ * Center for the Neural Basis of Cognition (CNBC)
+ * http://www.python.org/doc/PyCPP.html
+ *
+------------------------------*/
+#include <assert.h>
+#include "stdlib.h"
+#include "PyObjectPlus.h"
+#include "STR_String.h"
+/*------------------------------
+ * PyObjectPlus Type -- Every class, even the abstract one should have a Type
+------------------------------*/
+
+PyTypeObject PyObjectPlus::Type = {
+ PyObject_HEAD_INIT(&PyType_Type)
+ 0, /*ob_size*/
+ "PyObjectPlus", /*tp_name*/
+ sizeof(PyObjectPlus), /*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*/
+ 0, /*tp_as_sequence*/
+ 0, /*tp_as_mapping*/
+ 0, /*tp_hash*/
+ 0, /*tp_call */
+};
+
+PyObjectPlus::PyObjectPlus(PyTypeObject *T) // constructor
+{
+ assert(T != NULL);
+ this->ob_type = T;
+ _Py_NewReference(this);
+};
+
+/*------------------------------
+ * PyObjectPlus Methods -- Every class, even the abstract one should have a Methods
+------------------------------*/
+PyMethodDef PyObjectPlus::Methods[] = {
+ {"isA", (PyCFunction) sPy_isA, Py_NEWARGS},
+ {NULL, NULL} /* Sentinel */
+};
+
+/*------------------------------
+ * PyObjectPlus Parents -- Every class, even the abstract one should have parents
+------------------------------*/
+PyParentObject PyObjectPlus::Parents[] = {&PyObjectPlus::Type, NULL};
+
+/*------------------------------
+ * PyObjectPlus attributes -- attributes
+------------------------------*/
+PyObject *PyObjectPlus::_getattr(char *attr)
+{
+ //if (streq(attr, "type"))
+ // return Py_BuildValue("s", (*(GetParents()))->tp_name);
+
+ return Py_FindMethod(Methods, this, attr);
+}
+
+int PyObjectPlus::_setattr(char *attr, PyObject *value)
+{
+ //return PyObject::_setattr(attr,value);
+ //cerr << "Unknown attribute" << endl;
+ return 1;
+}
+
+/*------------------------------
+ * PyObjectPlus repr -- representations
+------------------------------*/
+PyObject *PyObjectPlus::_repr(void)
+{
+ Py_Error(PyExc_SystemError, "Representation not overridden by object.");
+}
+
+/*------------------------------
+ * PyObjectPlus isA -- the isA functions
+------------------------------*/
+bool PyObjectPlus::isA(PyTypeObject *T) // if called with a Type, use "typename"
+{
+ return isA(T->tp_name);
+}
+
+
+bool PyObjectPlus::isA(const char *mytypename) // check typename of each parent
+{
+ int i;
+ PyParentObject P;
+ PyParentObject *Ps = GetParents();
+
+ for (P = Ps[i=0]; P != NULL; P = Ps[i++])
+ {
+ if (STR_String(P->tp_name) == STR_String(mytypename) )
+ return true;
+ }
+
+ return false;
+}
+
+PyObject *PyObjectPlus::Py_isA(PyObject *args) // Python wrapper for isA
+{
+ char *mytypename;
+ Py_Try(PyArg_ParseTuple(args, "s", &mytypename));
+ if(isA(mytypename))
+ {Py_INCREF(Py_True); return Py_True;}
+ else
+ {Py_INCREF(Py_False); return Py_False;};
+}
+
+#endif //NO_EXP_PYTHON_EMBEDDING
+
diff --git a/source/gameengine/Expressions/PyObjectPlus.h b/source/gameengine/Expressions/PyObjectPlus.h
new file mode 100644
index 00000000000..e88ea2b255a
--- /dev/null
+++ b/source/gameengine/Expressions/PyObjectPlus.h
@@ -0,0 +1,135 @@
+/**
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef NO_EXP_PYTHON_EMBEDDING
+
+#ifndef _adr_py_lib_h_ // only process once,
+#define _adr_py_lib_h_ // even if multiply included
+
+#ifndef __cplusplus // c++ only
+#error Must be compiled with C++
+#endif
+
+#include "KX_Python.h"
+
+/*------------------------------
+ * Python defines
+------------------------------*/
+
+ // some basic python macros
+#define Py_NEWARGS 1
+#define Py_Return Py_INCREF(Py_None); return Py_None;
+
+#define Py_Error(E, M) {PyErr_SetString(E, M); return NULL;}
+#define Py_Try(F) {if (!(F)) return NULL;}
+#define Py_Assert(A,E,M) {if (!(A)) {PyErr_SetString(E, M); return NULL;}}
+
+inline void Py_Fatal(char *M) {
+ //cout << M << endl;
+ exit(-1);
+};
+
+ // This must be the first line of each
+ // PyC++ class
+#define Py_Header \
+ public: \
+ static PyTypeObject Type; \
+ static PyMethodDef Methods[]; \
+ static PyParentObject Parents[]; \
+ virtual PyTypeObject *GetType(void) {return &Type;}; \
+ virtual PyParentObject *GetParents(void) {return Parents;}
+
+ // This defines the _getattr_up macro
+ // which allows attribute and method calls
+ // to be properly passed up the hierarchy.
+#define _getattr_up(Parent) \
+ PyObject *rvalue = Py_FindMethod(Methods, this, attr); \
+ if (rvalue == NULL) \
+ { \
+ PyErr_Clear(); \
+ return Parent::_getattr(attr); \
+ } \
+ else \
+ return rvalue
+
+
+/*------------------------------
+ * PyObjectPlus
+------------------------------*/
+typedef PyTypeObject * PyParentObject; // Define the PyParent Object
+
+class PyObjectPlus : public PyObject { // The PyObjectPlus abstract class
+
+ Py_Header; // Always start with Py_Header
+
+ public:
+ PyObjectPlus(PyTypeObject *T);
+
+ virtual ~PyObjectPlus() {}; // destructor
+ static void PyDestructor(PyObject *P) // python wrapper
+ {
+ delete ((PyObjectPlus *) P);
+ };
+
+ //void INCREF(void) {
+// Py_INCREF(this);
+// }; // incref method
+ //void DECREF(void) {
+// Py_DECREF(this);
+// }; // decref method
+
+ virtual PyObject *_getattr(char *attr); // _getattr method
+ static PyObject *__getattr(PyObject * PyObj, char *attr) // This should be the entry in Type.
+ { return ((PyObjectPlus*) PyObj)->_getattr(attr); };
+
+ virtual int _setattr(char *attr, PyObject *value); // _setattr method
+ static int __setattr(PyObject *PyObj, // This should be the entry in Type.
+ char *attr,
+ PyObject *value)
+ { return ((PyObjectPlus*) PyObj)->_setattr(attr, value); };
+
+ virtual PyObject *_repr(void); // _repr method
+ static PyObject *__repr(PyObject *PyObj) // This should be the entry in Type.
+ { return ((PyObjectPlus*) PyObj)->_repr(); };
+
+
+ // isA methods
+ bool isA(PyTypeObject *T);
+ bool isA(const char *mytypename);
+ PyObject *Py_isA(PyObject *args);
+ static PyObject *sPy_isA(PyObject *self, PyObject *args, PyObject *kwd)
+ {return ((PyObjectPlus*)self)->Py_isA(args);};
+};
+
+#endif // _adr_py_lib_h_
+
+#endif //NO_EXP_PYTHON_EMBEDDING
+
diff --git a/source/gameengine/Expressions/StringValue.cpp b/source/gameengine/Expressions/StringValue.cpp
new file mode 100644
index 00000000000..7bdb841e1e4
--- /dev/null
+++ b/source/gameengine/Expressions/StringValue.cpp
@@ -0,0 +1,139 @@
+// StringValue.cpp: implementation of the CStringValue 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 "StringValue.h"
+#include "BoolValue.h"
+#include "ErrorValue.h"
+#include "VoidValue.h"
+//#include "FactoryManager.h"
+
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CStringValue::CStringValue()
+/*
+pre: false
+effect: constructs a new CStringValue
+*/
+{
+ m_strString = "[Illegal String constructor call]";
+}
+
+CStringValue::CStringValue(STR_String txt,STR_String name,AllocationTYPE alloctype)
+/*
+pre:
+effect: constructs a new CStringValue containing text txt
+*/
+{
+ m_strString = txt;
+ SetName(name);
+
+ if (alloctype==CValue::STACKVALUE)
+ {
+ CValue::DisableRefCount();
+
+ }
+
+
+}
+
+
+CValue* CStringValue::Calc(VALUE_OPERATOR op, CValue *val)
+/*
+pre:
+ret: a new object containing the result of applying operator op to this
+object and val
+*/
+{
+ //return val->CalrcString(op, this);
+ return val->CalcFinal(VALUE_STRING_TYPE, op, this);
+}
+
+CValue* CStringValue::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val)
+/*
+pre: the type of val is dtype
+ret: a new object containing the result of applying operator op to val and
+this object
+*/
+{
+ CValue *ret;
+
+ if (op == VALUE_ADD_OPERATOR) {
+ if (dtype == VALUE_ERROR_TYPE)
+ ret = new CErrorValue(val->GetText() + op2str(op) + GetText());
+ else
+ ret = new CStringValue(val->GetText() + GetText(),"");
+ } else {
+
+ if (dtype == VALUE_STRING_TYPE || dtype == VALUE_EMPTY_TYPE) {
+ switch(op) {
+ case VALUE_EQL_OPERATOR:
+ ret = new CBoolValue(val->GetText() == GetText());
+ break;
+ case VALUE_NEQ_OPERATOR:
+ ret = new CBoolValue(val->GetText() != GetText());
+ break;
+ case VALUE_GRE_OPERATOR:
+ ret = new CBoolValue(val->GetText() > GetText());
+ break;
+ case VALUE_LES_OPERATOR:
+ ret = new CBoolValue(val->GetText() < GetText());
+ break;
+ case VALUE_GEQ_OPERATOR:
+ ret = new CBoolValue(val->GetText() >= GetText());
+ break;
+ case VALUE_LEQ_OPERATOR:
+ ret = new CBoolValue(val->GetText() <= GetText());
+ break;
+ default:
+ ret = new CErrorValue(val->GetText() + op2str(op) + "[operator not allowed on strings]");
+ break;
+ }
+ } else {
+ ret = new CErrorValue(val->GetText() + op2str(op) + "[operator not allowed on strings]");
+ }
+ }
+ return ret;
+}
+
+
+
+float CStringValue::GetNumber()
+{
+ return -1;
+}
+
+
+
+const STR_String & CStringValue::GetText()
+{
+ return m_strString;
+}
+
+bool CStringValue::IsEqual(const STR_String & other)
+{
+ return (m_strString == other);
+}
+
+CValue* CStringValue::GetReplica()
+{
+ CStringValue* replica = new CStringValue(*this);
+ CValue::AddDataToReplica(replica);
+ return replica;
+};
+
+
diff --git a/source/gameengine/Expressions/StringValue.h b/source/gameengine/Expressions/StringValue.h
new file mode 100644
index 00000000000..6f90536a98b
--- /dev/null
+++ b/source/gameengine/Expressions/StringValue.h
@@ -0,0 +1,51 @@
+/*
+ * StringValue.h: interface for the CStringValue class.
+ * $Id$
+ * 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.
+ *
+ */
+
+#ifndef __STRINGVALUE_H__
+#define __STRINGVALUE_H__
+
+#include "Value.h"
+
+class CStringValue : public CPropValue
+{
+
+
+ //PLUGIN_DECLARE_SERIAL(CStringValue,CValue)
+public:
+ /// Construction / destruction
+ CStringValue();
+ CStringValue (STR_String txt, STR_String name , AllocationTYPE alloctype = CValue::HEAPVALUE);
+
+ virtual ~CStringValue() {
+ };
+ /// CValue implementation
+ virtual bool IsEqual(const STR_String & other);
+ virtual const STR_String & GetText();
+ virtual float GetNumber();
+
+ virtual CValue* Calc(VALUE_OPERATOR op, CValue *val);
+ virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val);
+ virtual void SetValue(CValue* newval) { m_strString = newval->GetText(); SetModified(true); };
+ virtual CValue* GetReplica();
+ virtual PyObject* ConvertValueToPython() {
+ return PyString_FromString(m_strString.Ptr());
+ }
+
+private:
+ // data member
+ STR_String m_strString;
+};
+
+#endif
diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp
new file mode 100644
index 00000000000..e2a7189fb02
--- /dev/null
+++ b/source/gameengine/Expressions/Value.cpp
@@ -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);
+}
+///////////////////////////////////////////////////////////////////////////////////////////////
+///////////////////////////////////////////////////////////////////////////////////////////////
+
diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h
new file mode 100644
index 00000000000..8131cc152bc
--- /dev/null
+++ b/source/gameengine/Expressions/Value.h
@@ -0,0 +1,467 @@
+/*
+ * Value.h: interface for the CValue class.
+ * $Id$
+ * 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.
+ *
+ */
+
+#ifdef WIN32
+#pragma warning (disable:4786)
+#endif //WIN32
+
+/////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////
+////
+//// Baseclass CValue
+//// Together with CExpression, CValue and it's derived classes can be used to
+//// parse expressions into a parsetree with error detecting/correcting capabilities
+//// also expandible by a CFactory pluginsystem
+////
+//// Features:
+//// Reference Counting (AddRef() / Release())
+//// Calculations (Calc() / CalcFinal())
+//// Configuration (Configure())
+//// Serialization (EdSerialize() / EdIdSerialize() / EdPtrSerialize() and macro PLUGIN_DECLARE_SERIAL
+//// Property system (SetProperty() / GetProperty() / FindIdentifier())
+//// Replication (GetReplica())
+//// Flags (IsSelected() / IsModified() / SetSelected()...)
+////
+//// Some small editor-specific things added
+//// A helperclass CompressorArchive handles the serialization
+////
+////////////////////////////////////////////////////////////////////////////////////
+/////////////////////////////////////////////////////////////////////////////////////
+#ifndef __VALUE_H__
+#define __VALUE_H__
+
+#include <map> // array functionality for the propertylist
+#include "STR_String.h" // STR_String class
+
+
+
+
+#ifndef GEN_NO_ASSERT
+#undef assert
+#define assert(exp) ((void)NULL)
+#endif
+
+
+#ifndef GEN_NO_TRACE
+#undef trace
+#define trace(exp) ((void)NULL)
+#endif
+
+#ifndef GEN_NO_DEBUG
+#undef debug
+#define debug(exp) ((void)NULL)
+#endif
+
+
+
+
+#ifndef GEN_NO_ASSERTD
+#undef assertd
+#define assertd(exp) ((void)NULL)
+#endif
+
+
+#ifndef USE_PRAGMA_ONCE
+#ifdef WIN32
+ #pragma once
+
+#endif //WIN32
+#endif
+
+#define EDITOR_LEVEL_VERSION 0x06
+
+enum VALUE_OPERATOR {
+
+ VALUE_ADD_OPERATOR, // +
+ VALUE_SUB_OPERATOR, // -
+ VALUE_MUL_OPERATOR, // *
+ VALUE_DIV_OPERATOR, // /
+ VALUE_NEG_OPERATOR, // -
+ VALUE_POS_OPERATOR, // +
+ VALUE_AND_OPERATOR, // &&
+ VALUE_OR_OPERATOR, // ||
+ VALUE_EQL_OPERATOR, // ==
+ VALUE_NEQ_OPERATOR, // !=
+ VALUE_GRE_OPERATOR, // >
+ VALUE_LES_OPERATOR, // <
+ VALUE_GEQ_OPERATOR, // >=
+ VALUE_LEQ_OPERATOR, // <=
+ VALUE_NOT_OPERATOR, // !
+ VALUE_NO_OPERATOR // no operation at all
+};
+
+enum VALUE_DATA_TYPE {
+ VALUE_NO_TYPE, // abstract baseclass
+ VALUE_INT_TYPE,
+ VALUE_FLOAT_TYPE,
+ VALUE_STRING_TYPE,
+ VALUE_BOOL_TYPE,
+ VALUE_ERROR_TYPE,
+ VALUE_EMPTY_TYPE,
+ VALUE_SOLID_TYPE,
+ VALUE_COMBISOLID_TYPE,
+ VALUE_VECTOR_TYPE,
+ VALUE_MENU_TYPE,
+ VALUE_ACTOR_TYPE,
+ VALUE_MAX_TYPE //only here to provide number of types
+};
+
+
+
+#ifdef _DEBUG
+//extern int gRefCountValue; // debugonly variable to check if all CValue Refences are Dereferenced at programexit
+#endif
+
+struct HashableInt
+{
+ HashableInt(int id) : mData(id) { }
+
+ unsigned long Hash() const { return 0;} ////}gHash(&mData, sizeof(int));}
+
+ bool operator==(HashableInt rhs) { return mData == rhs.mData; }
+
+ int mData;
+};
+
+
+//
+// Bitfield that stores the flags for each CValue derived class
+//
+struct ValueFlags {
+ ValueFlags() :
+ Modified(true),
+ Selected(false),
+ Affected(false),
+ ReleaseRequested(false),
+ Error(false),
+ RefCountDisabled(false),
+ HasProperties(false),
+ HasName(false),
+ Visible(true),
+ CustomFlag1(false),
+ CustomFlag2(false)
+ {
+ }
+
+ unsigned short Modified : 1;
+ unsigned short Selected : 1;
+ unsigned short Affected : 1;
+ unsigned short ReleaseRequested : 1;
+ unsigned short Error : 1;
+ unsigned short RefCountDisabled : 1;
+ unsigned short HasProperties : 1;
+ unsigned short HasName : 1;
+ unsigned short Visible : 1;
+ unsigned short CustomFlag1 : 1;
+ unsigned short CustomFlag2 : 1;
+
+
+};
+
+/**
+ * Base Class for all Actions performed on CValue's. Can be extended for undo/redo system in future.
+*/
+class CAction
+{
+public:
+ CAction() {
+ };
+ virtual ~CAction(){
+ };
+ virtual void Execute() const =0;
+};
+
+//
+// CValue
+//
+// Base class for all editor functionality, flexible object type that allows
+// calculations and uses reference counting for memory management.
+//
+//
+
+/**
+ * These macros are helpfull when embedding Python routines. The second
+ * macro is one that also requires a documentation string
+ */
+#define KX_PYMETHOD(class_name, method_name) \
+ PyObject* Py##method_name(PyObject* self, PyObject* args, PyObject* kwds); \
+ static PyObject* sPy##method_name( PyObject* self, PyObject* args, PyObject* kwds) { \
+ return ((class_name*) self)->Py##method_name(self, args, kwds); \
+ }; \
+
+#define KX_PYMETHOD_DOC(class_name, method_name) \
+ PyObject* Py##method_name(PyObject* self, PyObject* args, PyObject* kwds); \
+ static PyObject* sPy##method_name( PyObject* self, PyObject* args, PyObject* kwds) { \
+ return ((class_name*) self)->Py##method_name(self, args, kwds); \
+ }; \
+ static char method_name##_doc[]; \
+
+/* The line above should remain empty */
+
+#ifndef NO_EXP_PYTHON_EMBEDDING
+#include "PyObjectPlus.h"
+#include "object.h"
+class CValue : public PyObjectPlus
+#else
+class CValue
+#endif //NO_EXP_PYTHON_EMBEDDING
+
+
+{
+#ifndef NO_EXP_PYTHON_EMBEDDING
+Py_Header;
+#endif //NO_EXP_PYTHON_EMBEDDING
+public:
+ enum AllocationTYPE {
+ STACKVALUE = 0,
+ HEAPVALUE = 1
+ };
+
+ enum DrawTYPE {
+ STARTFRAME = 0,
+ ENDFRAME = 1,
+ INTERFRAME = 2
+ };
+
+
+ // Construction / Destruction
+#ifndef NO_EXP_PYTHON_EMBEDDING
+
+ CValue(PyTypeObject *T = &Type);
+ //static PyObject* PyMake(PyObject*,PyObject*);
+ virtual PyObject *_repr(void)
+ {
+ return Py_BuildValue("s",(const char*)GetText());
+ }
+
+
+
+ PyObject* _getattr(char* attr);
+
+ void SpecialRelease()
+ {
+ int i=0;
+ if (ob_refcnt == 0)
+ {
+ _Py_NewReference(this);
+
+ } else
+ {
+ i++;
+ }
+ Release();
+ }
+ static void PyDestructor(PyObject *P) // python wrapper
+ {
+ ((CValue*)P)->SpecialRelease();
+ };
+
+ virtual PyObject* ConvertValueToPython() {
+ return NULL;
+ }
+
+ virtual CValue* ConvertPythonToValue(PyObject* pyobj);
+
+
+ int _setattr(char* attr,PyObject* value);
+
+ KX_PYMETHOD(CValue,GetName);
+
+#else
+ CValue();
+#endif //NO_EXP_PYTHON_EMBEDDING
+
+
+
+ // Expression Calculation
+ virtual CValue* Calc(VALUE_OPERATOR op, CValue *val) = 0;
+ virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val) = 0;
+ virtual void SetOwnerExpression(class CExpression* expr);
+
+
+
+ void Execute(const CAction& a)
+ {
+ a.Execute();
+ };
+
+ /// Reference Counting
+ int GetRefCount() { return m_refcount; }
+ virtual CValue* AddRef(); // Add a reference to this value
+ virtual int Release(); // Release a reference to this value (when reference count reaches 0, the value is removed from the heap)
+
+ /// Property Management
+ virtual void SetProperty(const STR_String& name,CValue* ioProperty); // Set property <ioProperty>, overwrites and releases a previous property with the same name if needed
+ virtual CValue* GetProperty(const STR_String & inName); // Get pointer to a property with name <inName>, returns NULL if there is no property named <inName>
+ STR_String GetPropertyText(const STR_String & inName,const STR_String& deftext=""); // Get text description of property with name <inName>, returns an empty string if there is no property named <inName>
+ float GetPropertyNumber(const STR_String& inName,float defnumber);
+ virtual bool RemoveProperty(const STR_String & inName); // Remove the property named <inName>, returns true if the property was succesfully removed, false if property was not found or could not be removed
+ virtual void ClearProperties(); // Clear all properties
+
+ virtual void SetPropertiesModified(bool inModified); // Set all properties' modified flag to <inModified>
+ virtual bool IsAnyPropertyModified(); // Check if any of the properties in this value have been modified
+
+ virtual CValue* GetProperty(int inIndex); // Get property number <inIndex>
+ virtual int GetPropertyCount(); // Get the amount of properties assiocated with this value
+
+ virtual void CloneProperties(CValue* replica);
+ virtual CValue* FindIdentifier(const STR_String& identifiername);
+ /** Set the wireframe color of this value depending on the CSG
+ * operator type <op>
+ * @attention: not implemented */
+ virtual void SetColorOperator(VALUE_OPERATOR op);
+
+ virtual const STR_String & GetText() = 0;
+ virtual float GetNumber() = 0;
+ double* ZeroVector() { return m_sZeroVec; };
+ virtual double* GetVector3(bool bGetTransformedVec = false);
+
+ virtual STR_String GetName() = 0; // Retrieve the name of the value
+ virtual void SetName(STR_String name) = 0; // Set the name of the value
+ virtual void ReplicaSetName(STR_String name) = 0;
+ /** Sets the value to this cvalue.
+ * @attention this particular function should never be called. Why not abstract? */
+ virtual void SetValue(CValue* newval);
+ virtual CValue* GetReplica() =0;
+ //virtual CValue* Copy() = 0;
+
+
+ STR_String op2str(VALUE_OPERATOR op);
+
+ // setting / getting flags
+ inline void SetSelected(bool bSelected) { m_ValFlags.Selected = bSelected; }
+ virtual void SetModified(bool bModified) { m_ValFlags.Modified = bModified; }
+ virtual void SetAffected(bool bAffected=true) { m_ValFlags.Affected = bAffected; }
+ inline void SetReleaseRequested(bool bReleaseRequested) { m_ValFlags.ReleaseRequested=bReleaseRequested; }
+ inline void SetError(bool err) { m_ValFlags.Error=err; }
+ inline void SetVisible (bool vis) { m_ValFlags.Visible=vis; }
+
+ virtual bool IsModified() { return m_ValFlags.Modified; }
+ inline bool IsError() { return m_ValFlags.Error; }
+ virtual bool IsAffected() { return m_ValFlags.Affected || m_ValFlags.Modified; }
+ virtual bool IsSelected() { return m_ValFlags.Selected; }
+ inline bool IsReleaseRequested() { return m_ValFlags.ReleaseRequested; }
+ virtual bool IsVisible() { return m_ValFlags.Visible;}
+ virtual void SetCustomFlag1(bool bCustomFlag) { m_ValFlags.CustomFlag1 = bCustomFlag;};
+ virtual bool IsCustomFlag1() { return m_ValFlags.CustomFlag1;};
+
+ virtual void SetCustomFlag2(bool bCustomFlag) { m_ValFlags.CustomFlag2 = bCustomFlag;};
+ virtual bool IsCustomFlag2() { return m_ValFlags.CustomFlag2;};
+
+protected:
+ virtual void DisableRefCount(); // Disable reference counting for this value
+ virtual void AddDataToReplica(CValue* replica);
+ virtual ~CValue();
+private:
+ // Member variables
+ std::map<const STR_String,CValue*>* m_pNamedPropertyArray; // Properties for user/game etc
+ ValueFlags m_ValFlags; // Frequently used flags in a bitfield (low memoryusage)
+ int m_refcount; // Reference Counter
+ static double m_sZeroVec[3];
+
+};
+
+
+
+//
+// Declare a CValue or CExpression or CWhatever to be serialized by the editor.
+//
+// This macro introduces the EdSerialize() function (which must be implemented by
+// the client) and the EdIdSerialize() function (which is implemented by this macro).
+//
+// The generated Copy() function returns a pointer to <root_base_class_name> type
+// of object. So, for *any* CValue-derived object this should be set to CValue,
+// for *any* CExpression-derived object this should be set to CExpression.
+//
+#define PLUGIN_DECLARE_SERIAL(class_name, root_base_class_name) \
+public: \
+ virtual root_base_class_name * Copy() { return new class_name; } \
+ virtual bool EdSerialize(CompressorArchive& arch,class CFactoryManager* facmgr,bool bIsStoring); \
+ virtual bool EdIdSerialize(CompressorArchive& arch,class CFactoryManager* facmgr,bool bIsStoring) \
+{ \
+ if (bIsStoring) \
+ arch.StoreString(#class_name); \
+ \
+ return false; \
+} \
+
+
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+////////////////////////////////////////////////////////////////////////////////
+
+// CPropValue is a CValue derived class, that implements the identification (String name)
+// SetName() / GetName(),
+// normal classes should derive from CPropValue, real lightweight classes straight from CValue
+
+
+class CPropValue : public CValue
+{
+public:
+
+#ifndef NO_EXP_PYTHON_EMBEDDING
+ CPropValue(PyTypeObject* T=&Type) :
+ CValue(T),
+#else
+ CPropValue() :
+#endif //NO_EXP_PYTHON_EMBEDDING
+ m_pstrNewName(NULL)
+
+ {
+ }
+
+ virtual ~CPropValue()
+ {
+ if (m_pstrNewName)
+ {
+ delete m_pstrNewName;
+ m_pstrNewName = NULL;
+ }
+ }
+
+ virtual void SetName(STR_String name) {
+ if (m_pstrNewName)
+ {
+ delete m_pstrNewName;
+ m_pstrNewName = NULL;
+ }
+ if (name.Length())
+ m_pstrNewName = new STR_String(name);
+ }
+ virtual void ReplicaSetName(STR_String name) {
+ m_pstrNewName=NULL;
+ if (name.Length())
+ m_pstrNewName = new STR_String(name);
+ }
+
+ virtual STR_String GetName() {
+ //STR_String namefromprop = GetPropertyText("Name");
+ //if (namefromprop.Length() > 0)
+ // return namefromprop;
+
+ if (m_pstrNewName)
+ {
+ return *m_pstrNewName;
+ }
+ return STR_String("");
+ }; // name of Value
+
+protected:
+ STR_String* m_pstrNewName; // Identification
+};
+
+
+
+#endif // !defined _VALUEBASECLASS_H
diff --git a/source/gameengine/Expressions/VectorValue.cpp b/source/gameengine/Expressions/VectorValue.cpp
new file mode 100644
index 00000000000..6aa7926bfa7
--- /dev/null
+++ b/source/gameengine/Expressions/VectorValue.cpp
@@ -0,0 +1,213 @@
+// VectorValue.cpp: implementation of the CVectorValue 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.
+ *
+ */
+
+#ifdef WIN32
+#pragma warning (disable:4786)
+#endif
+
+#include "Value.h"
+#include "VectorValue.h"
+#include "ErrorValue.h"
+//#include "MatrixValue.h"
+#include "VoidValue.h"
+#include "StringValue.h"
+//#include "FactoryManager.h"
+
+
+
+//////////////////////////////////////////////////////////////////////
+// Construction/Destruction
+//////////////////////////////////////////////////////////////////////
+
+CVectorValue::CVectorValue(float x,float y,float z, AllocationTYPE alloctype)
+{
+ SetCustomFlag1(false);//FancyOutput=false;
+
+ if (alloctype == STACKVALUE)
+ {
+ CValue::DisableRefCount();
+ };
+
+ m_vec[KX_X] = m_transformedvec[KX_X] = x;
+ m_vec[KX_Y] = m_transformedvec[KX_Y] = y;
+ m_vec[KX_Z] = m_transformedvec[KX_Z] = z;
+
+}
+CVectorValue::CVectorValue(double vec[],STR_String name,AllocationTYPE alloctype) {
+
+ SetCustomFlag1(false);//FancyOutput=false;
+
+ m_vec[KX_X] = m_transformedvec[KX_X] = vec[KX_X];
+ m_vec[KX_Y] = m_transformedvec[KX_Y] = vec[KX_Y];
+ m_vec[KX_Z] = m_transformedvec[KX_Z] = vec[KX_Z];
+
+ if (alloctype == STACKVALUE)
+ {
+ CValue::DisableRefCount();
+
+ }
+
+ SetName(name);
+}
+
+CVectorValue::CVectorValue(double vec[],AllocationTYPE alloctype) {
+
+ SetCustomFlag1(false);//FancyOutput=false;
+
+ m_vec[KX_X] = m_transformedvec[KX_X] = vec[KX_X];
+ m_vec[KX_Y] = m_transformedvec[KX_Y] = vec[KX_Y];
+ m_vec[KX_Z] = m_transformedvec[KX_Z] = vec[KX_Z];
+
+ if (alloctype == STACKVALUE)
+ {
+ CValue::DisableRefCount();
+
+ }
+
+
+}
+CVectorValue::~CVectorValue()
+{
+
+}
+
+CValue* CVectorValue::CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val)
+/*
+pre: the type of val is dtype
+ret: a new object containing the result of applying operator op to val and
+this object
+*/
+{
+ CValue *ret = NULL;
+
+ switch(op)
+ {
+ case VALUE_ADD_OPERATOR:
+ {
+ switch (dtype)
+ {
+ case VALUE_EMPTY_TYPE:
+ case VALUE_VECTOR_TYPE:
+ {
+ ret = new CVectorValue(
+ val->GetVector3()[KX_X] + GetVector3()[KX_X],
+ val->GetVector3()[KX_Y] + GetVector3()[KX_Y],
+ val->GetVector3()[KX_Z] + GetVector3()[KX_Z],
+ CValue::HEAPVALUE);
+ ret->SetName(GetName());
+ break;
+ }
+
+ default:
+ ret = new CErrorValue(val->GetText() + op2str(op) + GetText());
+ }
+ break;
+ }
+ case VALUE_MUL_OPERATOR:
+ {
+ switch (dtype)
+ {
+
+ case VALUE_EMPTY_TYPE:
+ case VALUE_VECTOR_TYPE:
+ {
+ //MT_Vector3 supports 'scaling' by another vector, instead of using general transform, Gino?
+ //ret = new CVectorValue(val->GetVector3().Scaled(GetVector3()),GetName());
+ break;
+ }
+ case VALUE_FLOAT_TYPE:
+ {
+ ret = new CVectorValue(
+ val->GetVector3()[KX_X] * GetVector3()[KX_X],
+ val->GetVector3()[KX_Y] * GetVector3()[KX_Y],
+ val->GetVector3()[KX_Z] * GetVector3()[KX_Z],
+ CValue::HEAPVALUE);
+ ret->SetName(GetName());
+ break;
+ }
+
+ default:
+ ret = new CErrorValue(val->GetText() + op2str(op) + GetText());
+ }
+ break;
+
+ }
+
+ default:
+ ret = new CErrorValue(val->GetText() + op2str(op) + GetText());
+ }
+
+
+ return ret;
+}
+
+float CVectorValue::GetNumber()
+{
+ return m_vec[KX_X];
+}
+
+
+double* CVectorValue::GetVector3(bool bGetTransformedVec)
+{
+ if (bGetTransformedVec)
+ return m_transformedvec;
+ // else
+ return m_vec;
+}
+
+
+
+
+
+void CVectorValue::SetVector(double newvec[])
+{
+ m_vec[KX_X] = m_transformedvec[KX_X] = newvec[KX_X];
+ m_vec[KX_Y] = m_transformedvec[KX_Y] = newvec[KX_Y];
+ m_vec[KX_Z] = m_transformedvec[KX_Z] = newvec[KX_Z];
+
+ SetModified(true);
+}
+
+
+void CVectorValue::SetValue(CValue *newval)
+{
+
+ double* newvec = ((CVectorValue*)newval)->GetVector3();
+ m_vec[KX_X] = m_transformedvec[KX_X] = newvec[KX_X];
+ m_vec[KX_Y] = m_transformedvec[KX_Y] = newvec[KX_Y];
+ m_vec[KX_Z] = m_transformedvec[KX_Z] = newvec[KX_Z];
+
+ SetModified(true);
+}
+
+static const STR_String gstrVectorStr=STR_String();
+const STR_String & CVectorValue::GetText()
+{
+ assertd(false);
+ return gstrVectorStr;
+}
+
+CValue* CVectorValue::GetReplica() {
+ CVectorValue* replica = new CVectorValue(*this);
+ CValue::AddDataToReplica(replica);
+ return replica;
+};
+
+/*void CVectorValue::Transform(rcMatrix4x4 mat)
+{
+ m_transformedvec = mat*m_vec;
+}
+*/
+
+
diff --git a/source/gameengine/Expressions/VectorValue.h b/source/gameengine/Expressions/VectorValue.h
new file mode 100644
index 00000000000..8ed671721a3
--- /dev/null
+++ b/source/gameengine/Expressions/VectorValue.h
@@ -0,0 +1,86 @@
+/*
+ * VectorValue.h: interface for the CVectorValue class.
+ * $Id$
+ * 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.
+ *
+ */
+#if !defined _VECTORVALUE_H
+#define _VECTORVALUE_H
+
+
+#include "Value.h"
+
+#define KX_X 0
+#define KX_Y 1
+#define KX_Z 2
+
+
+class CVectorValue : public CPropValue
+{
+ //PLUGIN_DECLARE_SERIAL(CVectorValue,CValue)
+
+public:
+ //void Transform(rcMatrix4x4 mat);
+ virtual void SetValue(CValue* newval);
+ void SetVector(double newvec[]);
+ void Configure(CValue* menuvalue);
+ virtual double* GetVector3(bool bGetTransformedVec=false);
+ virtual float GetNumber();
+
+ CValue* Calc(VALUE_OPERATOR op, CValue *val) {
+ return val->CalcFinal(VALUE_VECTOR_TYPE, op, this);
+ }
+
+ CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue *val);
+
+
+ CVectorValue(double vec[],STR_String name,AllocationTYPE alloctype=CValue::HEAPVALUE);
+ CVectorValue() {};
+
+ CVectorValue(double vec[],AllocationTYPE alloctype=CValue::HEAPVALUE);
+ CVectorValue(float x,float y,float z, AllocationTYPE alloctype = CValue::HEAPVALUE);
+ virtual ~CVectorValue();
+ //virtual bool ExportT3D(File *txtfile,bool bNoName=false);
+ void AddConfigurationData(CValue* menuvalue);
+
+
+
+ virtual CValue* GetReplica();
+ virtual const STR_String & GetText();
+
+/*
+ void SnapPoint(float num,int snap)
+ {
+ if (num > 0) num += ((float)snap / 2);
+ else num -= ((float)snap / 2);
+ num = (long)(((long)(num / snap)) * snap);
+ };
+
+ void SnapPosition(const double snapvec[])
+ {
+
+ if (snapvec[KX_X] >= 1)
+ SnapPoint(m_vec[KX_X],snapvec[KX_X]);
+ if (snapvec[KX_Y] >= 1)
+ SnapPoint(m_vec[KX_Y],snapvec[KX_Y]);
+ if (snapvec[KX_Z] >= 1)
+ SnapPoint(m_vec[KX_Z],snapvec[KX_Z]);
+
+ }
+*/
+
+protected:
+ double m_vec[3];
+ double m_transformedvec[3];
+};
+
+#endif // !defined _VECTORVALUE_H
+
diff --git a/source/gameengine/Expressions/VoidValue.h b/source/gameengine/Expressions/VoidValue.h
new file mode 100644
index 00000000000..5cf40268b97
--- /dev/null
+++ b/source/gameengine/Expressions/VoidValue.h
@@ -0,0 +1,68 @@
+/**
+ * VoidValue.h: interface for the CVoidValue class.
+ * $Id$
+ *
+ * ***** BEGIN GPL/BL DUAL LICENSE BLOCK *****
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version 2
+ * of the License, or (at your option) any later version. The Blender
+ * Foundation also sells licenses for use in proprietary software under
+ * the Blender License. See http://www.blender.org/BL/ for information
+ * about this.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ *
+ * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
+ * All rights reserved.
+ *
+ * The Original Code is: all of this file.
+ *
+ * Contributor(s): none yet.
+ *
+ * ***** END GPL/BL DUAL LICENSE BLOCK *****
+ */
+#ifndef __VOIDVALUE_H__
+#define __VOIDVALUE_H__
+
+#include "Value.h"
+
+
+//
+// Void value, used to transport *any* type of data
+//
+class CVoidValue : public CPropValue
+{
+ //PLUGIN_DECLARE_SERIAL (CVoidValue,CValue)
+
+public:
+ /// Construction/destruction
+ CVoidValue() : m_pAnything(NULL), m_bDeleteOnDestruct(false) { }
+ CVoidValue(void * voidptr, bool bDeleteOnDestruct, AllocationTYPE alloctype) : m_pAnything(voidptr), m_bDeleteOnDestruct(bDeleteOnDestruct) { if (alloctype == STACKVALUE) CValue::DisableRefCount(); }
+ virtual ~CVoidValue(); // Destruct void value, delete memory if we're owning it
+
+ /// Value -> String or number
+ virtual const STR_String & GetText(); // Get string description of void value (unimplemented)
+ virtual float GetNumber() { return -1; }
+
+ /// Value calculation
+ virtual CValue* Calc(VALUE_OPERATOR op, CValue *val);
+ virtual CValue* CalcFinal(VALUE_DATA_TYPE dtype, VALUE_OPERATOR op, CValue* val);
+
+ /// Value replication
+ virtual CValue* GetReplica();
+
+ /// Data members
+ bool m_bDeleteOnDestruct;
+ void* m_pAnything;
+};
+
+#endif // !defined _VOIDVALUE_H