/* ----------------------------------------------------------------------------- GSFramework Copyright 2001-2013 Emmanuel Julien. All Rights Reserved. ----------------------------------------------------------------------------- */ #include "ui/ui.h" #include "ui/ui_window.h" #include "ui/ui_group.h" #include "core/tool_mode.h" #include "script/scripted_object.h" #include "script/script_unit.h" #include "timing/benchmark.h" #include "metafile/nml.h" #include "log/log.h" using namespace GS::NML; using namespace GS::S2D; //------------------------------------------------------------------------------ bool Scene::FromMetaFileStoreGroup(const char *path, Group **group, uint flag, GS::ToolMode tool_mode, int load_level) { NML::File file; if (!NML::Parser::Load(path, file)) return false; if (Tag *scene_tag = file.GetTag("Scene2D")) { if (FromMetaTagStoreGroup(*scene_tag, group, flag, tool_mode, load_level)) name = path; } else __ERR__(__LOG_E__ << "No tag in '" << path << "'.\n", false) if (group && group[0]) group[0]->name = path; return true; } static bool ShouldLoadItem(GS::ToolMode mode, Tag *pt, uint flag, int load_level) { if (pt->GetTag("Item:ToolSpecific;") || pt->GetTag("Item:Helper;")) { if (!(flag & SceneIOHelper)) return false; // Do not load tool specific items in no tool or project preview modes. if ((mode == GS::NoTool) || (mode == GS::ToolProjectPreview)) return false; // Do not load tool specific items in no tool mode above the first load level. if (load_level > 0) return false; } return true; } template static T *LoadItemDerived(Scene *scene, T *i, GS::Map &uid_map, Tag *t, uint type_flag, const uint load_flag, int load_level, GS::ToolMode tool_mode) { if (!(load_flag & type_flag) || !ShouldLoadItem(tool_mode, t, load_flag, load_level)) { delete i; return NULL; } scene->SetupItemComponents(i); if (i->FromMetaTag(*t)) { uint olduid = i->GetUid(); // uid from source scene scene->AddItem(i, false); // add to live scene uid_map.Add(olduid, i->GetUid()); // store map from source to live scene } return i; } bool Scene::FromMetaTagStoreGroup(const Tag &tag, Group **group, uint load_flag, GS::ToolMode tool_mode, int load_level) { if (tag.name != "Scene2D") __ERR__(__LOG_E__ << "Could not parse UI scene, incorrect root tag (" << tag.name << ").\n", false) Benchmark bench(true); // Read items and setup uid remap array. Map uid_map; if (Tag *itag = tag.GetTag("Items")) { // Item count in scene. uint item_to_load = 0; NMLTagForeach(pt, *itag) if (Tag *item_tag = pt->GetTag("Item;")) item_to_load++; NMLTagForeach(pt, *itag) { Item *citem = NULL; if (pt->name == "Sprite") citem = LoadItemDerived(this, new Sprite, uid_map, pt, SceneIOSprite, load_flag, load_level, tool_mode); else if (pt->name == "Window") citem = LoadItemDerived(this, new Window, uid_map, pt, SceneIOWindow, load_flag, load_level, tool_mode); else __LOG_W__ << "Unexpected <" << pt->name << "> sub-tag in .\n"; if (citem) { // Add item to the scene group. if (group && group[0]) group[0]->item_list.Add(citem); } } } // Script unit. if (load_flag & SceneIOScript) { if (Tag *stag = tag.GetTag("ScriptedObject")) scripted_object->FromMetaTag(*stag); #if 1 // Compatibility else if (Tag *stag = tag.GetTag("ScriptUnit")) if (Script::Unit *unit = scripted_object->AddUnit(scripted_object->NewUnit())) unit->FromMetaTag(*stag); #endif } // Motion sets. if (load_flag & SceneIOMotion) if (Tag *ctag = tag.GetTag("SceneMotionContainer")) motion.FromMetaTag(*ctag, &uid_map); return true; } //------------------------------------------------------------------------------ //------------------------------------------------------------------------------ bool Scene::IsItemToBeSaved(Item *i, const Group *group, uint flag) const { if (!i) return false; // Filter out irrelevant items. if (group && !group->IsMember(i)) return false; switch (i->GetItemType()) { case Item::Type_Sprite: if (!(flag & SceneIOSprite)) return false; break; case Item::Type_Window: if (!(flag & SceneIOWindow)) return false; break; } return true; } Tag *Scene::LinkInfoAsMetaTag(Item *i, const Group *group, uint flag) const { if (!IsItemToBeSaved(i, group, flag)) return NULL; Item *l = i->GetParent(); if (!l) return NULL; if (!IsItemToBeSaved(l, group, flag)) return NULL; // Save link information. Tag *tag = new Tag("Link"); if (tag) { tag->AddChild("Item", i->GetUid()); tag->AddChild("Link", l->GetUid()); } return tag; } Tag *Scene::AsMetaTag(const Group *group, uint save_flag, GS::ToolMode tool_mode) const { Tag *root = new Tag("Scene2D"); if (!root) __ERR__(__LOG_E__ << "Could not create root tag to serialize.\n", NULL) // Write script object. if (scripted_object.IsValid() && !group) root->AddChild(scripted_object->AsMetaTag()); // Write motion sets. if (save_flag & SceneIOMotion) root->AddChild(motion.AsMetaTag()); // Write managed items. if (Tag *itag = root->AddChild("Items")) ListForeachPtr(Item *, i, item_list) { if (group && !group->item_list.Find(i)) continue; switch (i->GetItemType()) { case Item::Type_Sprite: if (!(save_flag & SceneIOSprite)) continue; break; case Item::Type_Window: if (!(save_flag & SceneIOWindow)) continue; break; } itag->AddChild(i->AsMetaTag()); } else __ERR__(__LOG_E__ << "Failed to allocate root tag.\n", NULL); // Write link informations. if (Tag *ltag = root->AddChild("Links")) ListForeachPtr(Item *, i, item_list) ltag->AddChild(LinkInfoAsMetaTag(i, group, save_flag)); else __ERR__(__LOG_E__ << "Failed to allocate root tag.\n", NULL) return root; } //------------------------------------------------------------------------------