BGE: Some various changes to make moving the character physics type easier:
[blender.git] / source / gameengine / Converter / KX_LibLoadStatus.cpp
1 /*
2  * ***** BEGIN GPL LICENSE BLOCK *****
3  *
4  * This program is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU General Public License
6  * as published by the Free Software Foundation; either version 2
7  * of the License, or (at your option) any later version.
8  *
9  * This program is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  * GNU General Public License for more details.
13  *
14  * You should have received a copy of the GNU General Public License
15  * along with this program; if not, write to the Free Software Foundation,
16  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17  *
18  * Contributor(s): Mitchell Stokes
19  *
20  * ***** END GPL LICENSE BLOCK *****
21  */
22
23 /** \file KX_LibLoadStatus.cpp
24  *  \ingroup bgeconv
25  */
26
27 #include "KX_LibLoadStatus.h"
28 #include "PIL_time.h"
29
30 KX_LibLoadStatus::KX_LibLoadStatus(class KX_BlenderSceneConverter* kx_converter,
31                                 class KX_KetsjiEngine* kx_engine,
32                                 class KX_Scene* merge_scene,
33                                 const char *path) :
34                         m_converter(kx_converter),
35                         m_engine(kx_engine),
36                         m_mergescene(merge_scene),
37                         m_data(NULL),
38                         m_libname(path),
39                         m_progress(0.f),
40 #ifdef WITH_PYTHON
41                         m_finish_cb(NULL),
42                         m_progress_cb(NULL)
43 #endif
44 {
45         m_endtime = m_starttime = PIL_check_seconds_timer();
46 }
47
48 void KX_LibLoadStatus::Finish()
49 {
50         m_progress = 1.f;
51         m_endtime = PIL_check_seconds_timer();
52
53         RunFinishCallback();
54         RunProgressCallback();
55 }
56
57 void KX_LibLoadStatus::RunFinishCallback()
58 {
59 #ifdef WITH_PYTHON
60         if (m_finish_cb) {
61                 PyObject* args = Py_BuildValue("(O)", GetProxy());
62
63                 if (!PyObject_Call(m_finish_cb, args, NULL)) {
64                         PyErr_Print();
65                         PyErr_Clear();
66                 }
67
68                 Py_DECREF(args);
69         }
70 #endif
71 }
72
73 void KX_LibLoadStatus::RunProgressCallback()
74 {
75 // Progess callbacks are causing threading problems with Python, so they're disabled for now
76 #if 0
77 #ifdef WITH_PYTHON
78         if (m_progress_cb) {
79                 //PyGILState_STATE gstate = PyGILState_Ensure();
80                 PyObject* args = Py_BuildValue("(O)", GetProxy());
81
82                 if (!PyObject_Call(m_progress_cb, args, NULL)) {
83                         PyErr_Print();
84                         PyErr_Clear();
85                 }
86
87                 Py_DECREF(args);
88                 //PyGILState_Release(gstate);
89         }
90 #endif
91 #endif
92 }
93
94 class KX_BlenderSceneConverter *KX_LibLoadStatus::GetConverter()
95 {
96         return m_converter;
97 }
98
99 class KX_KetsjiEngine *KX_LibLoadStatus::GetEngine()
100 {
101         return m_engine;
102 }
103
104 class KX_Scene *KX_LibLoadStatus::GetMergeScene()
105 {
106         return m_mergescene;
107 }
108
109 void KX_LibLoadStatus::SetLibName(const char *name)
110 {
111         m_libname = name;
112 }
113
114 const char *KX_LibLoadStatus::GetLibName()
115 {
116         return m_libname;
117 }
118
119 void KX_LibLoadStatus::SetData(void *data)
120 {
121         m_data = data;
122 }
123
124 void *KX_LibLoadStatus::GetData()
125 {
126         return m_data;
127 }
128
129 void KX_LibLoadStatus::SetProgress(float progress)
130 {
131         m_progress = progress;
132         RunProgressCallback();
133 }
134
135 float KX_LibLoadStatus::GetProgress()
136 {
137         return m_progress;
138 }
139
140 void KX_LibLoadStatus::AddProgress(float progress)
141 {
142         m_progress += progress;
143         RunProgressCallback();
144 }
145
146 #ifdef WITH_PYTHON
147
148 PyMethodDef KX_LibLoadStatus::Methods[] = 
149 {
150         {NULL} //Sentinel
151 };
152
153 PyAttributeDef KX_LibLoadStatus::Attributes[] = {
154         KX_PYATTRIBUTE_RW_FUNCTION("onFinish", KX_LibLoadStatus, pyattr_get_onfinish, pyattr_set_onfinish),
155         // KX_PYATTRIBUTE_RW_FUNCTION("onProgress", KX_LibLoadStatus, pyattr_get_onprogress, pyattr_set_onprogress),
156         KX_PYATTRIBUTE_FLOAT_RO("progress", KX_LibLoadStatus, m_progress),
157         KX_PYATTRIBUTE_STRING_RO("libraryName", KX_LibLoadStatus, m_libname),
158         KX_PYATTRIBUTE_RO_FUNCTION("timeTaken", KX_LibLoadStatus, pyattr_get_timetaken),
159         { NULL }        //Sentinel
160 };
161
162 PyTypeObject KX_LibLoadStatus::Type = {
163         PyVarObject_HEAD_INIT(NULL, 0)
164         "KX_LibLoadStatus",
165         sizeof(PyObjectPlus_Proxy),
166         0,
167         py_base_dealloc,
168         0,
169         0,
170         0,
171         0,
172         py_base_repr,
173         0,0,0,0,0,0,0,0,0,
174         Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
175         0,0,0,0,0,0,0,
176         Methods,
177         0,
178         0,
179         &PyObjectPlus::Type,
180         0,0,0,0,0,0,
181         py_base_new
182 };
183
184
185 PyObject* KX_LibLoadStatus::pyattr_get_onfinish(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
186 {
187         KX_LibLoadStatus* self = static_cast<KX_LibLoadStatus*>(self_v);
188         
189         if (self->m_finish_cb) {
190                 Py_INCREF(self->m_finish_cb);
191                 return self->m_finish_cb;
192         }
193
194         Py_RETURN_NONE;
195 }
196
197 int KX_LibLoadStatus::pyattr_set_onfinish(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
198 {
199         KX_LibLoadStatus* self = static_cast<KX_LibLoadStatus*>(self_v);
200
201         if (!PyCallable_Check(value)) {
202                 PyErr_SetString(PyExc_TypeError, "KX_LibLoadStatus.onFinished requires a callable object");
203                 return PY_SET_ATTR_FAIL;
204         }
205
206         if (self->m_finish_cb)
207                 Py_DECREF(self->m_finish_cb);
208
209         Py_INCREF(value);
210         self->m_finish_cb = value;
211
212         return PY_SET_ATTR_SUCCESS;
213 }
214
215 PyObject* KX_LibLoadStatus::pyattr_get_onprogress(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
216 {
217         KX_LibLoadStatus* self = static_cast<KX_LibLoadStatus*>(self_v);
218         
219         if (self->m_progress_cb) {
220                 Py_INCREF(self->m_progress_cb);
221                 return self->m_progress_cb;
222         }
223
224         Py_RETURN_NONE;
225 }
226
227 int KX_LibLoadStatus::pyattr_set_onprogress(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef, PyObject *value)
228 {
229         KX_LibLoadStatus* self = static_cast<KX_LibLoadStatus*>(self_v);
230
231         if (!PyCallable_Check(value)) {
232                 PyErr_SetString(PyExc_TypeError, "KX_LibLoadStatus.onProgress requires a callable object");
233                 return PY_SET_ATTR_FAIL;
234         }
235
236         if (self->m_progress_cb)
237                 Py_DECREF(self->m_progress_cb);
238
239         Py_INCREF(value);
240         self->m_progress_cb = value;
241
242         return PY_SET_ATTR_SUCCESS;
243 }
244
245 PyObject* KX_LibLoadStatus::pyattr_get_timetaken(void *self_v, const KX_PYATTRIBUTE_DEF *attrdef)
246 {
247         KX_LibLoadStatus* self = static_cast<KX_LibLoadStatus*>(self_v);
248
249         return PyFloat_FromDouble(self->m_endtime - self->m_starttime);
250 }
251 #endif // WITH_PYTHON