Files
Webcam/include/engine/ui/ui_nml.cpp

217 lines
5.9 KiB
C++

/* -----------------------------------------------------------------------------
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 <Scene2D> 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 <class T> static T *LoadItemDerived(Scene *scene, T *i, GS::Map <uint, uint> &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 <uint, uint> 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 <Items>.\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 <Items> 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 <Links> root tag.\n", NULL)
return root;
}
//------------------------------------------------------------------------------