remove header text:
[blender.git] / source / gameengine / Ketsji / KX_ParentActuator.cpp
1 /*
2  * Set or remove an objects parent
3  *
4  *
5  * ***** BEGIN GPL LICENSE BLOCK *****
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
20  *
21  * The Original Code is Copyright (C) 2001-2002 by NaN Holding BV.
22  * All rights reserved.
23  *
24  * The Original Code is: all of this file.
25  *
26  * Contributor(s): none yet.
27  *
28  * ***** END GPL LICENSE BLOCK *****
29  */
30
31 /** \file gameengine/Ketsji/KX_ParentActuator.cpp
32  *  \ingroup ketsji
33  */
34
35
36 #include "KX_ParentActuator.h"
37 #include "KX_GameObject.h"
38 #include "KX_PythonInit.h"
39
40 #include "PyObjectPlus.h" 
41
42 /* ------------------------------------------------------------------------- */
43 /* Native functions                                                          */
44 /* ------------------------------------------------------------------------- */
45
46 KX_ParentActuator::KX_ParentActuator(SCA_IObject *gameobj, 
47                                                                          int mode,
48                                                                          bool addToCompound,
49                                                                          bool ghost,
50                                                                          SCA_IObject *ob)
51         : SCA_IActuator(gameobj, KX_ACT_PARENT),
52           m_mode(mode),
53           m_addToCompound(addToCompound),
54           m_ghost(ghost),
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         return replica;
77 }
78
79 void KX_ParentActuator::ProcessReplica()
80 {
81         if (m_ob)
82                 m_ob->RegisterActuator(this);
83         SCA_IActuator::ProcessReplica();
84 }
85
86
87 bool KX_ParentActuator::UnlinkObject(SCA_IObject* clientobj)
88 {
89         if (clientobj == m_ob)
90         {
91                 // this object is being deleted, we cannot continue to track it.
92                 m_ob = NULL;
93                 return true;
94         }
95         return false;
96 }
97
98 void KX_ParentActuator::Relink(CTR_Map<CTR_HashedPtr, void*> *obj_map)
99 {
100         void **h_obj = (*obj_map)[m_ob];
101         if (h_obj) {
102                 if (m_ob)
103                         m_ob->UnregisterActuator(this);
104                 m_ob = (SCA_IObject*)(*h_obj);
105                 m_ob->RegisterActuator(this);
106         }
107 }
108
109
110
111 bool KX_ParentActuator::Update()
112 {
113         bool bNegativeEvent = IsNegativeEvent();
114         RemoveAllEvents();
115
116         if (bNegativeEvent)
117                 return false; // do nothing on negative events
118
119         KX_GameObject *obj = (KX_GameObject*) GetParent();
120         KX_Scene *scene = KX_GetActiveScene();
121         switch (m_mode) {
122                 case KX_PARENT_SET:
123                         if (m_ob)
124                                 obj->SetParent(scene, (KX_GameObject*)m_ob, m_addToCompound, m_ghost);
125                         break;
126                 case KX_PARENT_REMOVE:
127                         obj->RemoveParent(scene);
128                         break;
129         };
130         
131         return false;
132 }
133
134 #ifdef WITH_PYTHON
135
136 /* ------------------------------------------------------------------------- */
137 /* Python functions                                                          */
138 /* ------------------------------------------------------------------------- */
139
140 /* Integration hooks ------------------------------------------------------- */
141 PyTypeObject KX_ParentActuator::Type = {
142         PyVarObject_HEAD_INIT(NULL, 0)
143         "KX_ParentActuator",
144         sizeof(PyObjectPlus_Proxy),
145         0,
146         py_base_dealloc,
147         0,
148         0,
149         0,
150         0,
151         py_base_repr,
152         0,0,0,0,0,0,0,0,0,
153         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
154         0,0,0,0,0,0,0,
155         Methods,
156         0,
157         0,
158         &SCA_IActuator::Type,
159         0,0,0,0,0,0,
160         py_base_new
161 };
162
163 PyMethodDef KX_ParentActuator::Methods[] = {
164         {NULL,NULL} //Sentinel
165 };
166
167 PyAttributeDef KX_ParentActuator::Attributes[] = {
168         KX_PYATTRIBUTE_RW_FUNCTION("object", KX_ParentActuator, pyattr_get_object, pyattr_set_object),
169         KX_PYATTRIBUTE_INT_RW("mode", KX_PARENT_NODEF+1, KX_PARENT_MAX-1, true, KX_ParentActuator, m_mode),
170         KX_PYATTRIBUTE_BOOL_RW("compound", KX_ParentActuator, m_addToCompound),
171         KX_PYATTRIBUTE_BOOL_RW("ghost", KX_ParentActuator, m_ghost),
172         { NULL }        //Sentinel
173 };
174
175 PyObject* KX_ParentActuator::pyattr_get_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef)
176 {
177         KX_ParentActuator* actuator = static_cast<KX_ParentActuator*>(self);
178         if (!actuator->m_ob)    
179                 Py_RETURN_NONE;
180         else
181                 return actuator->m_ob->GetProxy();
182 }
183
184 int KX_ParentActuator::pyattr_set_object(void *self, const struct KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
185 {
186         KX_ParentActuator* actuator = static_cast<KX_ParentActuator*>(self);
187         KX_GameObject *gameobj;
188                 
189         if (!ConvertPythonToGameObject(value, &gameobj, true, "actuator.object = value: KX_ParentActuator"))
190                 return PY_SET_ATTR_FAIL; // ConvertPythonToGameObject sets the error
191                 
192         if (actuator->m_ob != NULL)
193                 actuator->m_ob->UnregisterActuator(actuator);   
194
195         actuator->m_ob = (SCA_IObject*) gameobj;
196                 
197         if (actuator->m_ob)
198                 actuator->m_ob->RegisterActuator(actuator);
199                 
200         return PY_SET_ATTR_SUCCESS;
201 }
202
203 #endif // WITH_PYTHON
204
205 /* eof */