bool Universe::IsValidObject(vm_oop_t obj) { if (IS_TAGGED(obj)) return true; if (obj == INVALID_VM_POINTER // || obj == nullptr ) { assert(false); return false; } if (obj == nullptr) return true; if (vt_symbol == nullptr) // initialization not yet completed return true; void* vt = *(void**) obj; bool b = vt == vt_array || vt == vt_block || vt == vt_class || vt == vt_double || vt == vt_eval_primitive || vt == vt_frame || vt == vt_integer || vt == vt_method || vt == vt_object || vt == vt_primitive || vt == vt_string || vt == vt_symbol; assert(b); return b; }
void gc_keep(PObject **objs, uint32_t nobjs) { while (nobjs--) { PObject *obj = objs[nobjs]; if (obj) { if (!IS_TAGGED(obj)) { mark_it: if (GCH_FLAG(obj) == GC_USED) { GCH_NEXT_SET2(obj, _phead); _phead = obj; //mark it! if it is kept again, it will not be added GC_MARK(obj); } } else { if (TAGTYPE(obj) == PCELL) { debug("marking cell %x %x\n", obj, PCELL_ARG(obj)); //vosThSleep(TIME_U(1,SECONDS)); obj = PCELL_ARG(obj); goto mark_it; } } } // if (obj && !IS_TAGGED(obj) && GCH_FLAG(obj) == GC_USED) { // GCH_NEXT_SET2(obj, _phead); // _phead = obj; // //mark it! if it is kept again, it will not be added // GC_MARK(obj); // } } }
void BL_ActionManager::RemoveTaggedActions() { for (BL_ActionMap::iterator it = m_layers.begin(); it != m_layers.end();) { if (IS_TAGGED(it->second->GetAction())) { delete it->second; m_layers.erase(it++); } else ++it; } }
void VMMethod::SetHolderAll(VMClass* hld) { long numIndexableFields = GetNumberOfIndexableFields(); for (long i = 0; i < numIndexableFields; ++i) { vm_oop_t o = GetIndexableField(i); if (!IS_TAGGED(o)) { VMInvokable* vmi = dynamic_cast<VMInvokable*>(AS_OBJ(o)); if (vmi != nullptr) { vmi->SetHolder(hld); } } } }
void Interpreter::doPopField(long bytecodeIndex) { uint8_t field_index = method->GetBytecode(bytecodeIndex + 1); vm_oop_t self = GetSelf(); vm_oop_t o = GetFrame()->Pop(); if (unlikely(IS_TAGGED(self))) { GetUniverse()->ErrorExit("Integers do not have fields that can be set"); } else { ((VMObject*) self)->SetField(field_index, o); } }
void Interpreter::doPushField(long bytecodeIndex) { uint8_t fieldIndex = method->GetBytecode(bytecodeIndex + 1); vm_oop_t self = GetSelf(); vm_oop_t o; if (unlikely(IS_TAGGED(self))) { o = nullptr; Universe()->ErrorExit("Integers do not have fields!"); } else { o = ((VMObject*)self)->GetField(fieldIndex); } GetFrame()->Push(o); }
lky_object *stlcon_to_int(lky_func_bundle *bundle) { lky_object_seq *args = BUW_ARGS(bundle); lky_object *from = (lky_object *)args->value; if(IS_TAGGED(from) || from->type == LBI_INTEGER) return from; if(from->type == LBI_FLOAT) return lobjb_build_int(OBJ_NUM_UNWRAP(from)); long val; sscanf(stlstr_unwrap(from), "%ld", &val); return lobjb_build_int(val); }
// // RunCmd is a private function to work around an obscure protocol // bug in 2000.[12] servers. Running a "p4 -Ztag client -o" messes up the // protocol so if they're running this command then we disconnect and // reconnect to refresh it. For efficiency, we only do this if the // server2 protocol is either 9 or 10 as other versions aren't affected. // void P4ClientApi::RunCmd( const char *cmd, ClientUser *ui, int argc, char * const *argv, int table ) { client.SetProg( &prog ); if( version.Length() ) client.SetVersion( &version ); if( mode & M_TAGGED ) client.SetVar( "tag" ); // If maxresults or maxscanrows is set, enforce them now if( maxResults ) client.SetVar( "maxResults", maxResults ); if( maxScanRows ) client.SetVar( "maxScanRows", maxScanRows ); if( maxLockTime ) client.SetVar( "maxLockTime", maxLockTime ); client.SetBreak( &cb ); client.SetArgv( argc, argv ); client.Run( cmd, ui ); // Have to request server2 protocol *after* a command has been run. I // don't know why, but that's the way it is. if ( ! server2 ) { StrPtr *pv = client.GetProtocol( "server2" ); if ( pv ) server2 = pv->Atoi(); } if ( IS_TAGGED(mode) && StrRef( cmd ) == "client" && server2 >= 9 && server2 <= 10 ) { if ( argc && ( StrRef( argv[ 0 ] ) == "-o" ) ) { if ( P4LUADEBUG_COMMANDS ) printf( "Resetting client to avoid 2000.[12] protocol bug\n" ); Error e; client.Final( &e ); client.Init( &e ); // Pass any errors down to the UI, so they'll get picked up. if ( e.Test() ) ui->HandleError( &e ); } } }
/* Note m_map_*** are all ok and don't need to be freed * most are temp and NewRemoveObject frees m_map_gameobject_to_blender */ bool KX_BlenderSceneConverter::FreeBlendFile(struct Main *maggie) { int maggie_index= -1; int i=0; if (maggie==NULL) 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; if (main != maggie) { tag_main(main, 0); } else { maggie_index= i; } i++; } /* should never happen but just to be safe */ if (maggie_index == -1) return false; m_DynamicMaggie.erase(m_DynamicMaggie.begin() + maggie_index); tag_main(maggie, 1); /* free all tagged objects */ KX_SceneList* scenes = m_ketsjiEngine->CurrentScenes(); int numScenes = scenes->size(); for (int scene_idx=0;scene_idx<numScenes;scene_idx++) { KX_Scene* scene = scenes->at(scene_idx); if (IS_TAGGED(scene->GetBlenderScene())) { RemoveScene(scene); // XXX - not tested yet scene_idx--; numScenes--; } else { /* in case the mesh might be refered to later */ { CTR_Map<STR_HashedString,void*> &mapStringToMeshes = scene->GetLogicManager()->GetMeshMap(); for (int i=0; i<mapStringToMeshes.size(); i++) { RAS_MeshObject *meshobj= (RAS_MeshObject *) *mapStringToMeshes.at(i); if (meshobj && IS_TAGGED(meshobj->GetMesh())) { STR_HashedString mn = meshobj->GetName(); mapStringToMeshes.remove(mn); m_map_mesh_to_gamemesh.remove(CHashedPtr(meshobj->GetMesh())); i--; } } } /* Now unregister actions */ { CTR_Map<STR_HashedString,void*> &mapStringToActions = scene->GetLogicManager()->GetActionMap(); for (int i=0; i<mapStringToActions.size(); i++) { ID *action= (ID*) *mapStringToActions.at(i); if (IS_TAGGED(action)) { STR_HashedString an = action->name+2; mapStringToActions.remove(an); i--; } } } //scene->FreeTagged(); /* removed tagged objects and meshes*/ CListValue *obj_lists[] = {scene->GetObjectList(), scene->GetInactiveList(), NULL}; for (int ob_ls_idx=0; obj_lists[ob_ls_idx]; ob_ls_idx++) { CListValue *obs= obj_lists[ob_ls_idx]; RAS_MeshObject* mesh; for (int ob_idx = 0; ob_idx < obs->GetCount(); ob_idx++) { KX_GameObject* gameobj = (KX_GameObject*)obs->GetValue(ob_idx); if (IS_TAGGED(gameobj->GetBlenderObject())) { int size_before = obs->GetCount(); /* Eventually calls RemoveNodeDestructObject * frees m_map_gameobject_to_blender from UnregisterGameObject */ scene->RemoveObject(gameobj); if (size_before != obs->GetCount()) ob_idx--; else { printf("ERROR COULD NOT REMOVE \"%s\"\n", gameobj->GetName().ReadPtr()); } } else { /* free the mesh, we could be referecing a linked one! */ int mesh_index= gameobj->GetMeshCount(); while(mesh_index--) { mesh= gameobj->GetMesh(mesh_index); if (IS_TAGGED(mesh->GetMesh())) { gameobj->RemoveMeshes(); /* XXX - slack, should only remove meshes that are library items but mostly objects only have 1 mesh */ break; } } /* make sure action actuators are not referencing tagged actions */ for (unsigned int act_idx=0; act_idx<gameobj->GetActuators().size(); act_idx++) { if (gameobj->GetActuators()[act_idx]->IsType(SCA_IActuator::KX_ACT_ACTION)) { BL_ActionActuator *act = (BL_ActionActuator*)gameobj->GetActuators()[act_idx]; if (IS_TAGGED(act->GetAction())) act->SetAction(NULL); } } } } } } } int size; // delete the entities of this scene /* TODO - */ #if 0 vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator worldit; size = m_worldinfos.size(); for (i=0, worldit=m_worldinfos.begin(); i<size; ) { if ((*worldit).second) { delete (*worldit).second; *worldit = m_worldinfos.back(); m_worldinfos.pop_back(); size--; } else { i++; worldit++; } } #endif /* Worlds don't reference original blender data so we need to make a set from them */ typedef std::set<KX_WorldInfo*> KX_WorldInfoSet; KX_WorldInfoSet worldset; for (int scene_idx=0;scene_idx<numScenes;scene_idx++) { KX_Scene* scene = scenes->at(scene_idx); if (scene->GetWorldInfo()) worldset.insert( scene->GetWorldInfo() ); } vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator worldit; size = m_worldinfos.size(); for (i=0, worldit=m_worldinfos.begin(); i<size; ) { if ((*worldit).second && (worldset.count((*worldit).second)) == 0) { delete (*worldit).second; *worldit = m_worldinfos.back(); m_worldinfos.pop_back(); size--; } else { i++; worldit++; } } worldset.clear(); /* done freeing the worlds */ vector<pair<KX_Scene*,RAS_IPolyMaterial*> >::iterator polymit; size = m_polymaterials.size(); for (i=0, polymit=m_polymaterials.begin(); i<size; ) { RAS_IPolyMaterial *mat= (*polymit).second; Material *bmat= NULL; /* Why do we need to check for RAS_BLENDERMAT if both are cast to a (PyObject*)? - Campbell */ if (mat->GetFlag() & RAS_BLENDERMAT) { KX_BlenderMaterial *bl_mat = static_cast<KX_BlenderMaterial*>(mat); bmat= bl_mat->GetBlenderMaterial(); } else { KX_PolygonMaterial *kx_mat = static_cast<KX_PolygonMaterial*>(mat); bmat= kx_mat->GetBlenderMaterial(); } if (IS_TAGGED(bmat)) { /* only remove from bucket */ ((*polymit).first)->GetBucketManager()->RemoveMaterial(mat); } i++; polymit++; } for (i=0, polymit=m_polymaterials.begin(); i<size; ) { RAS_IPolyMaterial *mat= (*polymit).second; Material *bmat= NULL; /* Why do we need to check for RAS_BLENDERMAT if both are cast to a (PyObject*)? - Campbell */ if (mat->GetFlag() & RAS_BLENDERMAT) { KX_BlenderMaterial *bl_mat = static_cast<KX_BlenderMaterial*>(mat); bmat= bl_mat->GetBlenderMaterial(); } else { KX_PolygonMaterial *kx_mat = static_cast<KX_PolygonMaterial*>(mat); bmat= kx_mat->GetBlenderMaterial(); } if (bmat) { //printf("FOUND MAT '%s' !!! ", ((ID*)bmat)->name+2); } else { //printf("LOST MAT !!!"); } if (IS_TAGGED(bmat)) { delete (*polymit).second; *polymit = m_polymaterials.back(); m_polymaterials.pop_back(); size--; //printf("tagged !\n"); } else { i++; polymit++; //printf("(un)tagged !\n"); } } vector<pair<KX_Scene*,BL_Material*> >::iterator matit; size = m_materials.size(); for (i=0, matit=m_materials.begin(); i<size; ) { BL_Material *mat= (*matit).second; if (IS_TAGGED(mat->material)) { delete (*matit).second; *matit = m_materials.back(); m_materials.pop_back(); size--; } else { i++; matit++; } } vector<pair<KX_Scene*,RAS_MeshObject*> >::iterator meshit; size = m_meshobjects.size(); for (i=0, meshit=m_meshobjects.begin(); i<size; ) { RAS_MeshObject *me= (*meshit).second; if (IS_TAGGED(me->GetMesh())) { delete (*meshit).second; *meshit = m_meshobjects.back(); m_meshobjects.pop_back(); size--; } else { i++; meshit++; } } free_main(maggie); return true; }
/* Note m_map_*** are all ok and don't need to be freed * most are temp and NewRemoveObject frees m_map_gameobject_to_blender */ bool KX_BlenderSceneConverter::FreeBlendFile(Main *maggie) { int maggie_index = -1; int i = 0; 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; if (main != maggie) { BKE_main_id_tag_all(main, LIB_TAG_DOIT, false); } else { maggie_index = i; } i++; } /* should never happen but just to be safe */ if (maggie_index == -1) return false; m_DynamicMaggie.erase(m_DynamicMaggie.begin() + maggie_index); BKE_main_id_tag_all(maggie, LIB_TAG_DOIT, true); /* free all tagged objects */ KX_SceneList *scenes = m_ketsjiEngine->CurrentScenes(); int numScenes = scenes->size(); for (int scene_idx = 0; scene_idx < numScenes; scene_idx++) { KX_Scene *scene = scenes->at(scene_idx); if (IS_TAGGED(scene->GetBlenderScene())) { m_ketsjiEngine->RemoveScene(scene->GetName()); m_mat_cache.erase(scene); m_polymat_cache.erase(scene); scene_idx--; numScenes--; } else { /* in case the mesh might be refered to later */ { CTR_Map<STR_HashedString, void *> &mapStringToMeshes = scene->GetLogicManager()->GetMeshMap(); for (int i = 0; i < mapStringToMeshes.size(); i++) { RAS_MeshObject *meshobj = (RAS_MeshObject *) *mapStringToMeshes.at(i); if (meshobj && IS_TAGGED(meshobj->GetMesh())) { STR_HashedString mn = meshobj->GetName(); mapStringToMeshes.remove(mn); m_map_mesh_to_gamemesh.remove(CHashedPtr(meshobj->GetMesh())); i--; } } } /* Now unregister actions */ { CTR_Map<STR_HashedString, void *> &mapStringToActions = scene->GetLogicManager()->GetActionMap(); for (int i = 0; i < mapStringToActions.size(); i++) { ID *action = (ID*) *mapStringToActions.at(i); if (IS_TAGGED(action)) { STR_HashedString an = action->name + 2; mapStringToActions.remove(an); m_map_blender_to_gameAdtList.remove(CHashedPtr(action)); i--; } } } //scene->FreeTagged(); /* removed tagged objects and meshes*/ CListValue *obj_lists[] = {scene->GetObjectList(), scene->GetInactiveList(), NULL}; for (int ob_ls_idx = 0; obj_lists[ob_ls_idx]; ob_ls_idx++) { CListValue *obs = obj_lists[ob_ls_idx]; RAS_MeshObject *mesh; for (int ob_idx = 0; ob_idx < obs->GetCount(); ob_idx++) { KX_GameObject *gameobj = (KX_GameObject*)obs->GetValue(ob_idx); if (IS_TAGGED(gameobj->GetBlenderObject())) { int size_before = obs->GetCount(); /* Eventually calls RemoveNodeDestructObject * frees m_map_gameobject_to_blender from UnregisterGameObject */ scene->RemoveObject(gameobj); if (size_before != obs->GetCount()) ob_idx--; else { printf("ERROR COULD NOT REMOVE \"%s\"\n", gameobj->GetName().ReadPtr()); } } else { gameobj->RemoveTaggedActions(); /* free the mesh, we could be referecing a linked one! */ int mesh_index = gameobj->GetMeshCount(); while (mesh_index--) { mesh = gameobj->GetMesh(mesh_index); if (IS_TAGGED(mesh->GetMesh())) { gameobj->RemoveMeshes(); /* XXX - slack, should only remove meshes that are library items but mostly objects only have 1 mesh */ break; } else { /* also free the mesh if it's using a tagged material */ int mat_index = mesh->NumMaterials(); while (mat_index--) { if (IS_TAGGED(mesh->GetMeshMaterial(mat_index)->m_bucket->GetPolyMaterial()->GetBlenderMaterial())) { gameobj->RemoveMeshes(); /* XXX - slack, same as above */ break; } } } } /* make sure action actuators are not referencing tagged actions */ for (unsigned int act_idx = 0; act_idx < gameobj->GetActuators().size(); act_idx++) { if (gameobj->GetActuators()[act_idx]->IsType(SCA_IActuator::KX_ACT_ACTION)) { BL_ActionActuator *act = (BL_ActionActuator *)gameobj->GetActuators()[act_idx]; if (IS_TAGGED(act->GetAction())) act->SetAction(NULL); } } } } } } } int size; // delete the entities of this scene /* TODO - */ #if 0 vector<pair<KX_Scene*,KX_WorldInfo*> >::iterator worldit; size = m_worldinfos.size(); for (i=0, worldit=m_worldinfos.begin(); i<size; ) { if ((*worldit).second) { delete (*worldit).second; *worldit = m_worldinfos.back(); m_worldinfos.pop_back(); size--; } else { i++; worldit++; } } #endif /* Worlds don't reference original blender data so we need to make a set from them */ typedef std::set<KX_WorldInfo *> KX_WorldInfoSet; KX_WorldInfoSet worldset; for (int scene_idx = 0; scene_idx < numScenes; scene_idx++) { KX_Scene *scene = scenes->at(scene_idx); if (scene->GetWorldInfo()) worldset.insert(scene->GetWorldInfo()); } vector<pair<KX_Scene *, KX_WorldInfo *> >::iterator worldit; size = m_worldinfos.size(); for (i = 0, worldit = m_worldinfos.begin(); i < size;) { if (worldit->second && (worldset.count(worldit->second)) == 0) { delete worldit->second; *worldit = m_worldinfos.back(); m_worldinfos.pop_back(); size--; } else { i++; worldit++; } } worldset.clear(); /* done freeing the worlds */ vector<pair<KX_Scene *, RAS_IPolyMaterial *> >::iterator polymit; size = m_polymaterials.size(); for (i = 0, polymit = m_polymaterials.begin(); i < size; ) { RAS_IPolyMaterial *mat = polymit->second; Material *bmat = NULL; KX_BlenderMaterial *bl_mat = static_cast<KX_BlenderMaterial *>(mat); bmat = bl_mat->GetBlenderMaterial(); if (IS_TAGGED(bmat)) { /* only remove from bucket */ polymit->first->GetBucketManager()->RemoveMaterial(mat); } i++; polymit++; } for (i = 0, polymit = m_polymaterials.begin(); i < size; ) { RAS_IPolyMaterial *mat = polymit->second; Material *bmat = NULL; KX_BlenderMaterial *bl_mat = static_cast<KX_BlenderMaterial*>(mat); bmat = bl_mat->GetBlenderMaterial(); if (IS_TAGGED(bmat)) { // Remove the poly material coresponding to this Blender Material. m_polymat_cache[polymit->first].erase(bmat); delete polymit->second; *polymit = m_polymaterials.back(); m_polymaterials.pop_back(); size--; } else { i++; polymit++; } } vector<pair<KX_Scene *, BL_Material *> >::iterator matit; size = m_materials.size(); for (i = 0, matit = m_materials.begin(); i < size; ) { BL_Material *mat = matit->second; if (IS_TAGGED(mat->material)) { // Remove the bl material coresponding to this Blender Material. m_mat_cache[matit->first].erase(mat->material); delete matit->second; *matit = m_materials.back(); m_materials.pop_back(); size--; } else { i++; matit++; } } vector<pair<KX_Scene *, RAS_MeshObject *> >::iterator meshit; RAS_BucketManager::BucketList::iterator bit; list<RAS_MeshSlot>::iterator msit; RAS_BucketManager::BucketList buckets; size = m_meshobjects.size(); for (i = 0, meshit = m_meshobjects.begin(); i < size;) { RAS_MeshObject *me = meshit->second; if (IS_TAGGED(me->GetMesh())) { // Before deleting the mesh object, make sure the rasterizer is // no longer referencing it. buckets = meshit->first->GetBucketManager()->GetSolidBuckets(); for (bit = buckets.begin(); bit != buckets.end(); bit++) { msit = (*bit)->msBegin(); while (msit != (*bit)->msEnd()) { if (msit->m_mesh == meshit->second) (*bit)->RemoveMesh(&(*msit++)); else msit++; } } // And now the alpha buckets buckets = meshit->first->GetBucketManager()->GetAlphaBuckets(); for (bit = buckets.begin(); bit != buckets.end(); bit++) { msit = (*bit)->msBegin(); while (msit != (*bit)->msEnd()) { if (msit->m_mesh == meshit->second) (*bit)->RemoveMesh(&(*msit++)); else msit++; } } // Now it should be safe to delete delete meshit->second; *meshit = m_meshobjects.back(); m_meshobjects.pop_back(); size--; } else { i++; meshit++; } } #ifdef WITH_PYTHON /* make sure this maggie is removed from the import list if it's there * (this operation is safe if it isn't in the list) */ removeImportMain(maggie); #endif delete m_status_map[maggie->name]; m_status_map.erase(maggie->name); BKE_main_free(maggie); return true; }
static inline int HAS_MARK(markable_t x) { return (IS_TAGGED(x, 0x1) == 0x1); }