// clears meshes, and hashmaps from blender to gameengine data
// delete sumoshapes
- if (m_threadinfo) {
- BLI_task_pool_work_and_wait(m_threadinfo->m_pool);
- BLI_task_pool_free(m_threadinfo->m_pool);
-
- BLI_mutex_end(&m_threadinfo->m_mutex);
- delete m_threadinfo;
- }
-
int numAdtLists = m_map_blender_to_gameAdtList.size();
for (int i = 0; i < numAdtLists; i++) {
BL_InterpolatorList *adtList = *m_map_blender_to_gameAdtList.at(i);
}
m_DynamicMaggie.clear();
+
+ if (m_threadinfo) {
+ /* Thread infos like mutex must be freed after FreeBlendFile function.
+ Because it needs to lock the mutex, even if there's no active task when it's
+ in the scene converter destructor. */
+ BLI_task_pool_free(m_threadinfo->m_pool);
+ BLI_mutex_end(&m_threadinfo->m_mutex);
+ delete m_threadinfo;
+ }
}
void KX_BlenderSceneConverter::SetNewFileName(const STR_String &filename)
BLI_mutex_unlock(&m_threadinfo->m_mutex);
}
+void KX_BlenderSceneConverter::FinalizeAsyncLoads()
+{
+ // Finish all loading libraries.
+ if (m_threadinfo) {
+ BLI_task_pool_work_and_wait(m_threadinfo->m_pool);
+ }
+ // Merge all libraries data in the current scene, to avoid memory leak of unmerged scenes.
+ MergeAsyncLoads();
+}
+
void KX_BlenderSceneConverter::AddScenesToMergeQueue(KX_LibLoadStatus *status)
{
BLI_mutex_lock(&m_threadinfo->m_mutex);
if (maggie == NULL)
return false;
-
+
+ // If the given library is currently in loading, we do nothing.
+ if (m_status_map.count(maggie->name)) {
+ BLI_mutex_lock(&m_threadinfo->m_mutex);
+ const bool finished = m_status_map[maggie->name]->IsFinished();
+ BLI_mutex_unlock(&m_threadinfo->m_mutex);
+
+ if (!finished) {
+ printf("Library (%s) is currently being loaded asynchronously, and cannot be freed until this process is done\n", maggie->name);
+ return false;
+ }
+ }
+
/* tag all false except the one we remove */
for (vector<Main *>::iterator it = m_DynamicMaggie.begin(); !(it == m_DynamicMaggie.end()); it++) {
Main *main = *it;
m_mergescene(merge_scene),
m_data(NULL),
m_libname(path),
- m_progress(0.f)
+ m_progress(0.0f),
+ m_finished(false)
#ifdef WITH_PYTHON
,
m_finish_cb(NULL),
void KX_LibLoadStatus::Finish()
{
+ m_finished = true;
m_progress = 1.f;
m_endtime = PIL_check_seconds_timer();
KX_PYATTRIBUTE_FLOAT_RO("progress", KX_LibLoadStatus, m_progress),
KX_PYATTRIBUTE_STRING_RO("libraryName", KX_LibLoadStatus, m_libname),
KX_PYATTRIBUTE_RO_FUNCTION("timeTaken", KX_LibLoadStatus, pyattr_get_timetaken),
+ KX_PYATTRIBUTE_BOOL_RO("finished", KX_LibLoadStatus, m_finished),
{ NULL } //Sentinel
};