2nd try to merge sim_physics with trunk rev 19825
[blender.git] / source / gameengine / Ketsji / KX_ParentActuator.cpp
1 /**
2  * Set or remove an objects parent
3  *
4  * $Id: KX_ParentActuator.cpp 19794 2009-04-19 17:29:07Z campbellbarton $
5  *
6  * ***** BEGIN GPL LICENSE BLOCK *****
7  *
8  * This program is free software; you can redistribute it and/or
9  * modify it under the terms of the GNU General Public License
10  * as published by the Free Software Foundation; either version 2
11  * of the License, or (at your option) any later version. The Blender
12  * Foundation also sells licenses for use in proprietary software under
13  * the Blender License.  See http://www.blender.org/BL/ for information
14  * about this.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software Foundation,
23  * Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
24  *
25  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
26  * All rights reserved.
27  *
28  * The Original Code is: all of this file.
29  *
30  * Contributor(s): none yet.
31  *
32  * ***** END GPL LICENSE BLOCK *****
33  */
34
35 #include "KX_ParentActuator.h"
36 #include "KX_GameObject.h"
37 #include "KX_PythonInit.h"
38
39 #include "PyObjectPlus.h" 
40
41 #ifdef HAVE_CONFIG_H
42 #include <config.h>
43 #endif
44
45 /* ------------------------------------------------------------------------- */
46 /* Native functions                                                          */
47 /* ------------------------------------------------------------------------- */
48
49 KX_ParentActuator::KX_ParentActuator(SCA_IObject *gameobj, 
50                                                                          int mode,
51                                                                          SCA_IObject *ob,
52                                                                          PyTypeObject* T)
53         : SCA_IActuator(gameobj, T),
54           m_mode(mode),
55           m_ob(ob)
56 {
57         if (m_ob)
58                 m_ob->RegisterActuator(this);
59
60
61
62
63 KX_ParentActuator::~KX_ParentActuator()
64 {
65         if (m_ob)
66                 m_ob->UnregisterActuator(this);
67
68
69
70
71 CValue* KX_ParentActuator::GetReplica()
72 {
73         KX_ParentActuator* replica = new KX_ParentActuator(*this);
74         // replication just copy the m_base pointer => common random generator
75         replica->ProcessReplica();
76         CValue::AddDataToReplica(replica);
77
78         return replica;
79 }
80
81 void KX_ParentActuator::ProcessReplica()
82 {
83         if (m_ob)
84                 m_ob->RegisterActuator(this);
85         SCA_IActuator::ProcessReplica();
86 }
87
88
89 bool KX_ParentActuator::UnlinkObject(SCA_IObject* clientobj)
90 {
91         if (clientobj == m_ob)
92         {
93                 // this object is being deleted, we cannot continue to track it.
94                 m_ob = NULL;
95                 return true;
96         }
97         return false;
98 }
99
100 void KX_ParentActuator::Relink(GEN_Map<GEN_HashedPtr, void*> *obj_map)
101 {
102         void **h_obj = (*obj_map)[m_ob];
103         if (h_obj) {
104                 if (m_ob)
105                         m_ob->UnregisterActuator(this);
106                 m_ob = (SCA_IObject*)(*h_obj);
107                 m_ob->RegisterActuator(this);
108         }
109 }
110
111
112
113 bool KX_ParentActuator::Update()
114 {
115         bool bNegativeEvent = IsNegativeEvent();
116         RemoveAllEvents();
117
118         if (bNegativeEvent)
119                 return false; // do nothing on negative events
120
121         KX_GameObject *obj = (KX_GameObject*) GetParent();
122         KX_Scene *scene = KX_GetActiveScene();
123         switch (m_mode) {
124                 case KX_PARENT_SET:
125                         if (m_ob)
126                                 obj->SetParent(scene, (KX_GameObject*)m_ob);
127                         break;
128                 case KX_PARENT_REMOVE:
129                         obj->RemoveParent(scene);
130                         break;
131         };
132         
133         return false;
134 }
135
136 /* ------------------------------------------------------------------------- */
137 /* Python functions                                                          */
138 /* ------------------------------------------------------------------------- */
139
140 /* Integration hooks ------------------------------------------------------- */
141 PyTypeObject KX_ParentActuator::Type = {
142         PyObject_HEAD_INIT(NULL)
143         0,
144         "KX_ParentActuator",
145         sizeof(PyObjectPlus_Proxy),
146         0,
147         py_base_dealloc,
148         0,
149         0,
150         0,
151         0,
152         py_base_repr,
153         0,0,0,0,0,0,
154         py_base_getattro,
155         py_base_setattro,
156         0,0,0,0,0,0,0,0,0,
157         Methods
158 };
159
160 PyParentObject KX_ParentActuator::Parents[] = {
161         &KX_ParentActuator::Type,
162         &SCA_IActuator::Type,
163         &SCA_ILogicBrick::Type,
164         &CValue::Type,
165         NULL
166 };
167
168 PyMethodDef KX_ParentActuator::Methods[] = {
169         // Deprecated ----->
170         {"setObject", (PyCFunction) KX_ParentActuator::sPySetObject, METH_O, (PY_METHODCHAR)SetObject_doc},
171         {"getObject", (PyCFunction) KX_ParentActuator::sPyGetObject, METH_VARARGS, (PY_METHODCHAR)GetObject_doc},
172         // <-----
173         {NULL,NULL} //Sentinel
174 };
175
176 PyAttributeDef KX_ParentActuator::Attributes[] = {
177         KX_PYATTRIBUTE_RW_FUNCTION("object", KX_ParentActuator, pyattr_get_object, pyattr_set_object),
178         { NULL }        //Sentinel
179 };
180
181 PyObject* KX_ParentActuator::pyattr_get_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
182 {
183         KX_ParentActuator* actuator = static_cast<KX_ParentActuator*>(self);
184         if (!actuator->m_ob)    
185                 Py_RETURN_NONE;
186         else
187                 return actuator->m_ob->GetProxy();
188 }
189
190 int KX_ParentActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
191 {
192         KX_ParentActuator* actuator = static_cast<KX_ParentActuator*>(self);
193         KX_GameObject *gameobj;
194                 
195         if (!ConvertPythonToGameObject(value, &gameobj, true))
196                 return 1; // ConvertPythonToGameObject sets the error
197                 
198         if (actuator->m_ob != NULL)
199                 actuator->m_ob->UnregisterActuator(actuator);   
200
201         actuator->m_ob = (SCA_IObject*) gameobj;
202                 
203         if (actuator->m_ob)
204                 actuator->m_ob->RegisterActuator(actuator);
205                 
206         return 0;
207 }
208
209
210 PyObject* KX_ParentActuator::py_getattro(PyObject *attr) {      
211         py_getattro_up(SCA_IActuator);
212 }
213
214 int KX_ParentActuator::py_setattro(PyObject *attr, PyObject* value) {
215         py_setattro_up(SCA_IActuator);
216 }
217
218 /* Deprecated -----> */
219 /* 1. setObject                                                            */
220 const char KX_ParentActuator::SetObject_doc[] = 
221 "setObject(object)\n"
222 "\t- object: KX_GameObject, string or None\n"
223 "\tSet the object to set as parent.\n";
224 PyObject* KX_ParentActuator::PySetObject(PyObject* value) {
225         KX_GameObject *gameobj;
226         
227         ShowDeprecationWarning("setObject()", "the object property");
228         
229         if (!ConvertPythonToGameObject(value, &gameobj, true))
230                 return NULL; // ConvertPythonToGameObject sets the error
231         
232         if (m_ob != NULL)
233                 m_ob->UnregisterActuator(this); 
234
235         m_ob = (SCA_IObject*)gameobj;
236         if (m_ob)
237                 m_ob->RegisterActuator(this);
238         
239         Py_RETURN_NONE;
240 }
241
242 /* 2. getObject                                                            */
243
244 /* get obj  ---------------------------------------------------------- */
245 const char KX_ParentActuator::GetObject_doc[] = 
246 "getObject(name_only = 1)\n"
247 "name_only - optional arg, when true will return the KX_GameObject rather then its name\n"
248 "\tReturns the object that is set to.\n";
249 PyObject* KX_ParentActuator::PyGetObject(PyObject* args)
250 {
251         int ret_name_only = 1;
252         
253         ShowDeprecationWarning("getObject()", "the object property");
254         
255         if (!PyArg_ParseTuple(args, "|i:getObject", &ret_name_only))
256                 return NULL;
257         
258         if (!m_ob)
259                 Py_RETURN_NONE;
260         
261         if (ret_name_only)
262                 return PyString_FromString(m_ob->GetName());
263         else
264                 return m_ob->GetProxy();
265 }
266 /* <----- */
267
268 /* eof */