blender/source/gameengine/GameLogic/SCA_PropertyActuator.cpp
Jorge Bernal 6ffc988ae3 BGE Clean-up: New EXP prefix for the BGE Expression module
The expression module now uses an EXP prefix and it follows a
distribution similar to blender.

Additionally the hash function in EXP_HashedPtr.h was simplified and the
files EXP_C-Api.h &.EXP_C-Api.cpp were deleted because were unused.

Reviewers: campbellbarton, moguri, sybren, hg1

Projects: #game_engine

Differential Revision: https://developer.blender.org/D1221
2015-07-12 16:58:12 +02:00

294 lines
6.7 KiB
C++

/*
* Assign, change, copy properties
*
*
* ***** BEGIN GPL 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.
*
* 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 LICENSE BLOCK *****
*/
/** \file gameengine/GameLogic/SCA_PropertyActuator.cpp
* \ingroup gamelogic
*/
#include <stddef.h>
#include "SCA_PropertyActuator.h"
#include "EXP_InputParser.h"
#include "EXP_Operator2Expr.h"
#include "EXP_ConstExpr.h"
/* ------------------------------------------------------------------------- */
/* Native functions */
/* ------------------------------------------------------------------------- */
SCA_PropertyActuator::SCA_PropertyActuator(SCA_IObject* gameobj,SCA_IObject* sourceObj,const STR_String& propname,const STR_String& expr,int acttype)
: SCA_IActuator(gameobj, KX_ACT_PROPERTY),
m_type(acttype),
m_propname(propname),
m_exprtxt(expr),
m_sourceObj(sourceObj)
{
// protect ourselves against someone else deleting the source object
// don't protect against ourselves: it would create a dead lock
if (m_sourceObj)
m_sourceObj->RegisterActuator(this);
}
SCA_PropertyActuator::~SCA_PropertyActuator()
{
if (m_sourceObj)
m_sourceObj->UnregisterActuator(this);
}
bool SCA_PropertyActuator::Update()
{
bool result = false;
bool bNegativeEvent = IsNegativeEvent();
RemoveAllEvents();
CValue* propowner = GetParent();
if (bNegativeEvent)
{
if (m_type==KX_ACT_PROP_LEVEL)
{
CValue* newval = new CBoolValue(false);
CValue* oldprop = propowner->GetProperty(m_propname);
if (oldprop)
{
oldprop->SetValue(newval);
}
newval->Release();
}
return false;
}
CParser parser;
parser.SetContext( propowner->AddRef());
CExpression* userexpr= NULL;
if (m_type==KX_ACT_PROP_TOGGLE)
{
/* don't use */
CValue* newval;
CValue* oldprop = propowner->GetProperty(m_propname);
if (oldprop)
{
newval = new CBoolValue((oldprop->GetNumber()==0.0) ? true:false);
oldprop->SetValue(newval);
} else
{ /* as not been assigned, evaluate as false, so assign true */
newval = new CBoolValue(true);
propowner->SetProperty(m_propname,newval);
}
newval->Release();
}
else if (m_type==KX_ACT_PROP_LEVEL)
{
CValue* newval = new CBoolValue(true);
CValue* oldprop = propowner->GetProperty(m_propname);
if (oldprop)
{
oldprop->SetValue(newval);
} else
{
propowner->SetProperty(m_propname,newval);
}
newval->Release();
}
else if ((userexpr = parser.ProcessText(m_exprtxt))) {
switch (m_type)
{
case KX_ACT_PROP_ASSIGN:
{
CValue* newval = userexpr->Calculate();
CValue* oldprop = propowner->GetProperty(m_propname);
if (oldprop)
{
oldprop->SetValue(newval);
} else
{
propowner->SetProperty(m_propname,newval);
}
newval->Release();
break;
}
case KX_ACT_PROP_ADD:
{
CValue* oldprop = propowner->GetProperty(m_propname);
if (oldprop)
{
// int waarde = (int)oldprop->GetNumber(); /*unused*/
CExpression* expr = new COperator2Expr(VALUE_ADD_OPERATOR,new CConstExpr(oldprop->AddRef()),
userexpr->AddRef());
CValue* newprop = expr->Calculate();
oldprop->SetValue(newprop);
newprop->Release();
expr->Release();
}
break;
}
case KX_ACT_PROP_COPY:
{
if (m_sourceObj)
{
CValue* copyprop = m_sourceObj->GetProperty(m_exprtxt);
if (copyprop)
{
CValue *val = copyprop->GetReplica();
GetParent()->SetProperty(
m_propname,
val);
val->Release();
}
}
break;
}
/* case KX_ACT_PROP_TOGGLE: */ /* accounted for above, no need for userexpr */
default:
{
}
}
userexpr->Release();
}
return result;
}
bool
SCA_PropertyActuator::
isValid(
SCA_PropertyActuator::KX_ACT_PROP_MODE mode
) {
bool res = false;
res = ((mode > KX_ACT_PROP_NODEF) && (mode < KX_ACT_PROP_MAX));
return res;
}
CValue*
SCA_PropertyActuator::
GetReplica()
{
SCA_PropertyActuator* replica = new SCA_PropertyActuator(*this);
replica->ProcessReplica();
return replica;
};
void SCA_PropertyActuator::ProcessReplica()
{
// no need to check for self reference like in the constructor:
// the replica will always have a different parent
if (m_sourceObj)
m_sourceObj->RegisterActuator(this);
SCA_IActuator::ProcessReplica();
}
bool SCA_PropertyActuator::UnlinkObject(SCA_IObject* clientobj)
{
if (clientobj == m_sourceObj)
{
// this object is being deleted, we cannot continue to track it.
m_sourceObj = NULL;
return true;
}
return false;
}
void SCA_PropertyActuator::Relink(CTR_Map<CTR_HashedPtr, void*> *obj_map)
{
void **h_obj = (*obj_map)[m_sourceObj];
if (h_obj) {
if (m_sourceObj)
m_sourceObj->UnregisterActuator(this);
m_sourceObj = (SCA_IObject*)(*h_obj);
m_sourceObj->RegisterActuator(this);
}
}
#ifdef WITH_PYTHON
/* ------------------------------------------------------------------------- */
/* Python functions */
/* ------------------------------------------------------------------------- */
/* Integration hooks ------------------------------------------------------- */
PyTypeObject SCA_PropertyActuator::Type = {
PyVarObject_HEAD_INIT(NULL, 0)
"SCA_PropertyActuator",
sizeof(PyObjectPlus_Proxy),
0,
py_base_dealloc,
0,
0,
0,
0,
py_base_repr,
0,0,0,0,0,0,0,0,0,
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
0,0,0,0,0,0,0,
Methods,
0,
0,
&SCA_IActuator::Type,
0,0,0,0,0,0,
py_base_new
};
PyMethodDef SCA_PropertyActuator::Methods[] = {
{NULL,NULL} //Sentinel
};
PyAttributeDef SCA_PropertyActuator::Attributes[] = {
KX_PYATTRIBUTE_STRING_RW_CHECK("propName",0,MAX_PROP_NAME,false,SCA_PropertyActuator,m_propname,CheckProperty),
KX_PYATTRIBUTE_STRING_RW("value",0,100,false,SCA_PropertyActuator,m_exprtxt),
KX_PYATTRIBUTE_INT_RW("mode", KX_ACT_PROP_NODEF+1, KX_ACT_PROP_MAX-1, false, SCA_PropertyActuator, m_type), /* ATTR_TODO add constents to game logic dict */
{ NULL } //Sentinel
};
#endif
/* eof */