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
		
			
				
	
	
		
			294 lines
		
	
	
		
			6.7 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			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 */
 |