diff options
-rw-r--r-- | source/gameengine/Expressions/FloatValue.cpp | 6 | ||||
-rw-r--r-- | source/gameengine/Expressions/InputParser.cpp | 5 | ||||
-rw-r--r-- | source/gameengine/Expressions/InputParser.h | 1 | ||||
-rw-r--r-- | source/gameengine/Expressions/IntValue.cpp | 6 | ||||
-rw-r--r-- | source/gameengine/Expressions/Value.cpp | 9 | ||||
-rw-r--r-- | source/gameengine/Expressions/Value.h | 1 | ||||
-rw-r--r-- | source/gameengine/GameLogic/SCA_ExpressionController.cpp | 35 | ||||
-rw-r--r-- | source/gameengine/GameLogic/SCA_ExpressionController.h | 6 | ||||
-rw-r--r-- | source/gameengine/GameLogic/SCA_ILogicBrick.h | 1 | ||||
-rw-r--r-- | source/gameengine/GameLogic/SCA_IObject.cpp | 4 | ||||
-rw-r--r-- | source/gameengine/GameLogic/SCA_ISensor.h | 5 | ||||
-rw-r--r-- | source/gameengine/GameLogic/SCA_PropertySensor.h | 4 |
12 files changed, 68 insertions, 15 deletions
diff --git a/source/gameengine/Expressions/FloatValue.cpp b/source/gameengine/Expressions/FloatValue.cpp index 93f102d04a6..460eaa73f35 100644 --- a/source/gameengine/Expressions/FloatValue.cpp +++ b/source/gameengine/Expressions/FloatValue.cpp @@ -127,6 +127,9 @@ ret: a new object containing the result of applying operator op to val and { switch (op) { + case VALUE_MOD_OPERATOR: + ret = new CFloatValue(fmod(((CIntValue *) val)->GetInt(), m_float)); + break; case VALUE_ADD_OPERATOR: ret = new CFloatValue(((CIntValue *) val)->GetInt() + m_float); break; @@ -171,6 +174,9 @@ ret: a new object containing the result of applying operator op to val and { switch (op) { + case VALUE_MOD_OPERATOR: + ret = new CFloatValue(fmod(((CFloatValue *) val)->GetFloat(), m_float)); + break; case VALUE_ADD_OPERATOR: ret = new CFloatValue(((CFloatValue *) val)->GetFloat() + m_float); break; diff --git a/source/gameengine/Expressions/InputParser.cpp b/source/gameengine/Expressions/InputParser.cpp index e016fb8d007..94663c4a365 100644 --- a/source/gameengine/Expressions/InputParser.cpp +++ b/source/gameengine/Expressions/InputParser.cpp @@ -175,6 +175,9 @@ void CParser::NextSym() case ',': sym = commasym; NextCh(); break; + case '%' : + sym = opsym; opkind = OPmodulus; NextCh(); + break; case '+' : sym = opsym; opkind = OPplus; NextCh(); break; @@ -370,6 +373,7 @@ int CParser::Priority(int optorkind) { case OPunequal: return 3; case OPplus: case OPminus: return 4; + case OPmodulus: case OPtimes: case OPdivide: return 5; } @@ -390,6 +394,7 @@ CExpression *CParser::Ex(int i) { NextSym(); e2 = Ex(i + 1); switch(opkind2) { + case OPmodulus: e1 = new COperator2Expr(VALUE_MOD_OPERATOR,e1, e2); break; 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; diff --git a/source/gameengine/Expressions/InputParser.h b/source/gameengine/Expressions/InputParser.h index 4caa47cbb0c..f51c473ba18 100644 --- a/source/gameengine/Expressions/InputParser.h +++ b/source/gameengine/Expressions/InputParser.h @@ -49,6 +49,7 @@ private: }; // all kinds of symbols enum optype { + OPmodulus, OPplus, OPminus, OPtimes, diff --git a/source/gameengine/Expressions/IntValue.cpp b/source/gameengine/Expressions/IntValue.cpp index fbf4f4f59e0..fb586cb4979 100644 --- a/source/gameengine/Expressions/IntValue.cpp +++ b/source/gameengine/Expressions/IntValue.cpp @@ -125,6 +125,9 @@ this object case VALUE_INT_TYPE: { switch (op) { + case VALUE_MOD_OPERATOR: + ret = new CIntValue (((CIntValue *) val)->GetInt() % m_int); + break; case VALUE_ADD_OPERATOR: ret = new CIntValue (((CIntValue *) val)->GetInt() + m_int); break; @@ -181,6 +184,9 @@ this object case VALUE_FLOAT_TYPE: { switch (op) { + case VALUE_MOD_OPERATOR: + ret = new CFloatValue(fmod(((CFloatValue *) val)->GetFloat(), m_int)); + break; case VALUE_ADD_OPERATOR: ret = new CFloatValue (((CFloatValue *) val)->GetFloat() + m_int); break; diff --git a/source/gameengine/Expressions/Value.cpp b/source/gameengine/Expressions/Value.cpp index d29e3961c65..ebb12636ac2 100644 --- a/source/gameengine/Expressions/Value.cpp +++ b/source/gameengine/Expressions/Value.cpp @@ -52,6 +52,10 @@ PyObject* cvalue_div(PyObject*v, PyObject*w) { return ((CValue*)v)->Calc(VALUE_DIV_OPERATOR,(CValue*)w); } +PyObject* cvalue_mod(PyObject*v, PyObject*w) +{ + return ((CValue*)v)->Calc(VALUE_MOD_OPERATOR,(CValue*)w); +} PyObject* cvalue_neg(PyObject*v) { return ((CValue*)v)->Calc(VALUE_NEG_OPERATOR,(CValue*)v); @@ -112,7 +116,7 @@ static PyNumberMethods cvalue_as_number = { (binaryfunc)cvalue_sub, /*nb_subtract*/ (binaryfunc)cvalue_mul, /*nb_multiply*/ (binaryfunc)cvalue_div, /*nb_divide*/ - 0,//(binaryfunc)cvalue_remainder, /*nb_remainder*/ + (binaryfunc)cvalue_mod, /*nb_remainder*/ 0,//(binaryfunc)cvalue_divmod, /*nb_divmod*/ 0,//0,//0,//0,//(ternaryfunc)cvalue_pow, /*nb_power*/ (unaryfunc)cvalue_neg, /*nb_negative*/ @@ -257,6 +261,9 @@ STR_String CValue::op2str (VALUE_OPERATOR op) STR_String opmsg; switch (op) { + case VALUE_MOD_OPERATOR: + opmsg = " % "; + break; case VALUE_ADD_OPERATOR: opmsg = " + "; break; diff --git a/source/gameengine/Expressions/Value.h b/source/gameengine/Expressions/Value.h index 854334b892b..caf1064dc32 100644 --- a/source/gameengine/Expressions/Value.h +++ b/source/gameengine/Expressions/Value.h @@ -75,6 +75,7 @@ enum VALUE_OPERATOR { + VALUE_MOD_OPERATOR, // % VALUE_ADD_OPERATOR, // + VALUE_SUB_OPERATOR, // - VALUE_MUL_OPERATOR, // * diff --git a/source/gameengine/GameLogic/SCA_ExpressionController.cpp b/source/gameengine/GameLogic/SCA_ExpressionController.cpp index e9a543c9f31..8ed46beb7f3 100644 --- a/source/gameengine/GameLogic/SCA_ExpressionController.cpp +++ b/source/gameengine/GameLogic/SCA_ExpressionController.cpp @@ -49,7 +49,8 @@ SCA_ExpressionController::SCA_ExpressionController(SCA_IObject* gameobj, const STR_String& exprtext, PyTypeObject* T) :SCA_IController(gameobj,T), - m_exprText(exprtext) + m_exprText(exprtext), + m_exprCache(NULL) { } @@ -57,6 +58,8 @@ SCA_ExpressionController::SCA_ExpressionController(SCA_IObject* gameobj, SCA_ExpressionController::~SCA_ExpressionController() { + if (m_exprCache) + m_exprCache->Release(); } @@ -65,6 +68,7 @@ CValue* SCA_ExpressionController::GetReplica() { SCA_ExpressionController* replica = new SCA_ExpressionController(*this); replica->m_exprText = m_exprText; + replica->m_exprCache = NULL; // this will copy properties and so on... CValue::AddDataToReplica(replica); @@ -72,18 +76,32 @@ CValue* SCA_ExpressionController::GetReplica() } +// Forced deletion of precalculated expression to break reference loop +// Use this function when you know that you won't use the sensor anymore +void SCA_ExpressionController::Delete() +{ + if (m_exprCache) + { + m_exprCache->Release(); + m_exprCache = NULL; + } + Release(); +} + void SCA_ExpressionController::Trigger(SCA_LogicManager* logicmgr) { bool expressionresult = false; - - CParser parser; - parser.SetContext(this->AddRef()); - CExpression* expr = parser.ProcessText(m_exprText); - if (expr) + if (!m_exprCache) + { + CParser parser; + parser.SetContext(this->AddRef()); + m_exprCache = parser.ProcessText(m_exprText); + } + if (m_exprCache) { - CValue* value = expr->Calculate(); + CValue* value = m_exprCache->Calculate(); if (value) { if (value->IsError()) @@ -97,7 +115,8 @@ void SCA_ExpressionController::Trigger(SCA_LogicManager* logicmgr) value->Release(); } - expr->Release(); + //m_exprCache->Release(); + //m_exprCache = NULL; } /* diff --git a/source/gameengine/GameLogic/SCA_ExpressionController.h b/source/gameengine/GameLogic/SCA_ExpressionController.h index 20e1eb77771..79c26eea1e7 100644 --- a/source/gameengine/GameLogic/SCA_ExpressionController.h +++ b/source/gameengine/GameLogic/SCA_ExpressionController.h @@ -38,6 +38,7 @@ class SCA_ExpressionController : public SCA_IController { // Py_Header; STR_String m_exprText; + CExpression* m_exprCache; public: SCA_ExpressionController(SCA_IObject* gameobj, @@ -48,6 +49,11 @@ public: virtual CValue* GetReplica(); virtual void Trigger(SCA_LogicManager* logicmgr); virtual CValue* FindIdentifier(const STR_String& identifiername); + /** + * used to release the expression cache + * so that self references are removed before the controller itself is released + */ + virtual void Delete(); /* --------------------------------------------------------------------- */ /* Python interface ---------------------------------------------------- */ diff --git a/source/gameengine/GameLogic/SCA_ILogicBrick.h b/source/gameengine/GameLogic/SCA_ILogicBrick.h index cde1353275b..70d49941613 100644 --- a/source/gameengine/GameLogic/SCA_ILogicBrick.h +++ b/source/gameengine/GameLogic/SCA_ILogicBrick.h @@ -62,6 +62,7 @@ public: SCA_IObject* GetParent(); virtual void ReParent(SCA_IObject* parent); virtual void Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map); + virtual void Delete() { Release(); } // act as a BoolValue (with value IsPositiveTrigger) virtual CValue* Calc(VALUE_OPERATOR op, CValue *val); diff --git a/source/gameengine/GameLogic/SCA_IObject.cpp b/source/gameengine/GameLogic/SCA_IObject.cpp index d8f5f3eede5..debd62d44e6 100644 --- a/source/gameengine/GameLogic/SCA_IObject.cpp +++ b/source/gameengine/GameLogic/SCA_IObject.cpp @@ -59,7 +59,9 @@ SCA_IObject::~SCA_IObject() SCA_ControllerList::iterator itc; for (itc = m_controllers.begin(); !(itc == m_controllers.end()); ++itc) { - ((CValue*)(*itc))->Release(); + //Use Delete for controller to ensure proper cleaning (expression controller) + (*itc)->Delete(); + //((CValue*)(*itc))->Release(); } SCA_ActuatorList::iterator ita; for (ita = m_registeredActuators.begin(); !(ita==m_registeredActuators.end()); ++ita) diff --git a/source/gameengine/GameLogic/SCA_ISensor.h b/source/gameengine/GameLogic/SCA_ISensor.h index 5ae7ced2a2a..23f2c76c19f 100644 --- a/source/gameengine/GameLogic/SCA_ISensor.h +++ b/source/gameengine/GameLogic/SCA_ISensor.h @@ -105,11 +105,6 @@ public: bool negmode, int freq); - /** Release sensor - * For property sensor, it is used to release the pre-calculated expression - * so that self references are removed before the sensor itself is released - */ - virtual void Delete() { Release(); } /** Set inversion of pulses on or off. */ void SetInvert(bool inv); /** set the level detection on or off */ diff --git a/source/gameengine/GameLogic/SCA_PropertySensor.h b/source/gameengine/GameLogic/SCA_PropertySensor.h index 933de49de18..2594e3fca9d 100644 --- a/source/gameengine/GameLogic/SCA_PropertySensor.h +++ b/source/gameengine/GameLogic/SCA_PropertySensor.h @@ -70,6 +70,10 @@ public: KX_PROPSENSOR_TYPE checktype, PyTypeObject* T=&Type ); + /** + * For property sensor, it is used to release the pre-calculated expression + * so that self references are removed before the sensor itself is released + */ virtual void Delete(); virtual ~SCA_PropertySensor(); virtual CValue* GetReplica(); |