add missing files after merging
[blender.git] / source / gameengine / Ketsji / KX_ParentActuator.cpp
1 /*
2  * Set or remove an objects parent
3  *
4  * $Id$
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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, 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 /** \file gameengine/Ketsji/KX_ParentActuator.cpp
36  *  \ingroup ketsji
37  */
38
39
40 #include "KX_ParentActuator.h"
41 #include "KX_GameObject.h"
42 #include "KX_PythonInit.h"
43
44 #include "PyObjectPlus.h" 
45
46 /* ------------------------------------------------------------------------- */
47 /* Native functions                                                          */
48 /* ------------------------------------------------------------------------- */
49
50 KX_ParentActuator::KX_ParentActuator(SCA_IObject *gameobj, 
51                                                                          int mode,
52                                                                          bool addToCompound,
53                                                                          bool ghost,
54                                                                          SCA_IObject *ob)
55         : SCA_IActuator(gameobj, KX_ACT_PARENT),
56           m_mode(mode),
57           m_addToCompound(addToCompound),
58           m_ghost(ghost),
59           m_ob(ob)
60 {
61         if (m_ob)
62                 m_ob->RegisterActuator(this);
63
64
65
66
67 KX_ParentActuator::~KX_ParentActuator()
68 {
69         if (m_ob)
70                 m_ob->UnregisterActuator(this);
71
72
73
74
75 CValue* KX_ParentActuator::GetReplica()
76 {
77         KX_ParentActuator* replica = new KX_ParentActuator(*this);
78         // replication just copy the m_base pointer => common random generator
79         replica->ProcessReplica();
80         return replica;
81 }
82
83 void KX_ParentActuator::ProcessReplica()
84 {
85         if (m_ob)
86                 m_ob->RegisterActuator(this);
87         SCA_IActuator::ProcessReplica();
88 }
89
90
91 bool KX_ParentActuator::UnlinkObject(SCA_IObject* clientobj)
92 {
93         if (clientobj == m_ob)
94         {
95                 // this object is being deleted, we cannot continue to track it.
96                 m_ob = NULL;
97                 return true;
98         }
99         return false;
100 }
101
102 void KX_ParentActuator::Relink(CTR_Map<CTR_HashedPtr, void*> *obj_map)
103 {
104         void **h_obj = (*obj_map)[m_ob];
105         if (h_obj) {
106                 if (m_ob)
107                         m_ob->UnregisterActuator(this);
108                 m_ob = (SCA_IObject*)(*h_obj);
109                 m_ob->RegisterActuator(this);
110         }
111 }
112
113
114
115 bool KX_ParentActuator::Update()
116 {
117         bool bNegativeEvent = IsNegativeEvent();
118         RemoveAllEvents();
119
120         if (bNegativeEvent)
121                 return false; // do nothing on negative events
122
123         KX_GameObject *obj = (KX_GameObject*) GetParent();
124         KX_Scene *scene = KX_GetActiveScene();
125         switch (m_mode) {
126                 case KX_PARENT_SET:
127                         if (m_ob)
128                                 obj->SetParent(scene, (KX_GameObject*)m_ob, m_addToCompound, m_ghost);
129                         break;
130                 case KX_PARENT_REMOVE:
131                         obj->RemoveParent(scene);
132                         break;
133         };
134         
135         return false;
136 }
137
138 #ifdef WITH_PYTHON
139
140 /* ------------------------------------------------------------------------- */
141 /* Python functions                                                          */
142 /* ------------------------------------------------------------------------- */
143
144 /* Integration hooks ------------------------------------------------------- */
145 PyTypeObject KX_ParentActuator::Type = {
146         PyVarObject_HEAD_INIT(NULL, 0)
147         "KX_ParentActuator",
148         sizeof(PyObjectPlus_Proxy),
149         0,
150         py_base_dealloc,
151         0,
152         0,
153         0,
154         0,
155         py_base_repr,
156         0,0,0,0,0,0,0,0,0,
157         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
158         0,0,0,0,0,0,0,
159         Methods,
160         0,
161         0,
162         &SCA_IActuator::Type,
163         0,0,0,0,0,0,
164         py_base_new
165 };
166
167 PyMethodDef KX_ParentActuator::Methods[] = {
168         {NULL,NULL} //Sentinel
169 };
170
171 PyAttributeDef KX_ParentActuator::Attributes[] = {
172         KX_PYATTRIBUTE_RW_FUNCTION("object", KX_ParentActuator, pyattr_get_object, pyattr_set_object),
173         KX_PYATTRIBUTE_INT_RW("mode", KX_PARENT_NODEF+1, KX_PARENT_MAX-1, true, KX_ParentActuator, m_mode),
174         KX_PYATTRIBUTE_BOOL_RW("compound", KX_ParentActuator, m_addToCompound),
175         KX_PYATTRIBUTE_BOOL_RW("ghost", KX_ParentActuator, m_ghost),
176         { NULL }        //Sentinel
177 };
178
179 PyObject* KX_ParentActuator::pyattr_get_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
180 {
181         KX_ParentActuator* actuator = static_cast<KX_ParentActuator*>(self);
182         if (!actuator->m_ob)    
183                 Py_RETURN_NONE;
184         else
185                 return actuator->m_ob->GetProxy();
186 }
187
188 int KX_ParentActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
189 {
190         KX_ParentActuator* actuator = static_cast<KX_ParentActuator*>(self);
191         KX_GameObject *gameobj;
192                 
193         if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: KX_ParentActuator"))
194                 return PY_SET_ATTR_FAIL; // ConvertPythonToGameObject sets the error
195                 
196         if (actuator->m_ob != NULL)
197                 actuator->m_ob->UnregisterActuator(actuator);   
198
199         actuator->m_ob = (SCA_IObject*) gameobj;
200                 
201         if (actuator->m_ob)
202                 actuator->m_ob->RegisterActuator(actuator);
203                 
204         return PY_SET_ATTR_SUCCESS;
205 }
206
207 #endif // WITH_PYTHON
208
209 /* eof */