503 lines
13 KiB
C++
503 lines
13 KiB
C++
/* -----------------------------------------------------------------------------
|
|
GSFramework
|
|
Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
|
|
----------------------------------------------------------------------------- */
|
|
|
|
|
|
#include "binding_helpers.h"
|
|
#include "metafile/nml.h"
|
|
|
|
using namespace GS;
|
|
using namespace GS::NML;
|
|
using namespace GS::Script;
|
|
|
|
|
|
//-----------------------------------------------------------------------------
|
|
SQInteger MetafileGetRoots(HSQUIRRELVM vm)
|
|
{
|
|
__SQ_GETSINGLESAFEPTR(metafile, File, typetag_Metafile)
|
|
|
|
sq_newarray(vm, 0);
|
|
if (metafile)
|
|
{
|
|
NMLFileForeach(tag, *metafile)
|
|
{
|
|
CObject::Push(vm, tag, typetag_Metatag, false);
|
|
sq_arrayappend(vm, -2);
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
SQInteger MetatagGetChildren(HSQUIRRELVM vm)
|
|
{
|
|
__SQ_GETSINGLESAFEPTR(metatag, Tag, typetag_Metatag)
|
|
|
|
sq_newarray(vm, 0);
|
|
if (metatag)
|
|
{
|
|
NMLTagForeach(tag, *metatag)
|
|
{
|
|
CObject::Push(vm, tag, typetag_Metatag, false);
|
|
sq_arrayappend(vm, -2);
|
|
}
|
|
}
|
|
return 1;
|
|
}
|
|
|
|
SQInteger MetafileNew(HSQUIRRELVM vm)
|
|
{ __SQ_RETURNMANAGEDSAFEPTR(new File, typetag_Metafile) }
|
|
SQInteger MetafileDelete(HSQUIRRELVM vm)
|
|
{ __SQ_RETURN }
|
|
|
|
SQInteger MetafileLoadFromString(HSQUIRRELVM vm)
|
|
{
|
|
__SQ_GETSTART(2)
|
|
__SQ_GETSAFEPTR(mf, File, typetag_Metafile)
|
|
__SQ_GETSTRING(file)
|
|
bool success = Parser::LoadFromMemory((char *)file, String::strlen(file), *mf);
|
|
__SQ_GETEND
|
|
__SQ_RETURNBOOL(success)
|
|
}
|
|
SQInteger MetafileLoad(HSQUIRRELVM vm)
|
|
{
|
|
__SQ_GETSTART(2)
|
|
__SQ_GETSAFEPTR(mf, File, typetag_Metafile)
|
|
__SQ_GETSTRING(uri)
|
|
bool success = Parser::Load(uri, *mf); // take care of the string
|
|
__SQ_GETEND
|
|
__SQ_RETURNBOOL(success)
|
|
}
|
|
SQInteger MetafileSave(HSQUIRRELVM vm)
|
|
{
|
|
__SQ_GETSTART(2)
|
|
__SQ_GETSAFEPTR(mf, File, typetag_Metafile)
|
|
__SQ_GETSTRING(uri)
|
|
bool success = Parser::Save(uri, *mf);
|
|
__SQ_GETEND
|
|
__SQ_RETURNBOOL(success)
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
static Tag *CreateMetatagFromSquirrelStackEntry(HSQUIRRELVM vm, int idx, const char *path)
|
|
{
|
|
Tag *tag = NULL;
|
|
switch (sq_gettype(vm, idx))
|
|
{
|
|
case OT_NULL:
|
|
tag = new Tag(path);
|
|
break;
|
|
|
|
case OT_INTEGER:
|
|
{
|
|
SQInteger value;
|
|
sq_getinteger(vm, idx, &value);
|
|
tag = new Tag(path, (int)value);
|
|
}
|
|
break;
|
|
|
|
case OT_FLOAT:
|
|
{
|
|
float value;
|
|
sq_getfloat(vm, idx, &value);
|
|
tag = new Tag(path, value);
|
|
}
|
|
break;
|
|
|
|
case OT_BOOL:
|
|
{
|
|
SQBool value;
|
|
sq_getbool(vm, idx, &value);
|
|
tag = new Tag(path, value ? true : false);
|
|
}
|
|
break;
|
|
|
|
case OT_STRING:
|
|
{
|
|
const char *value;
|
|
sq_getstring(vm, idx, &value);
|
|
tag = new Tag(path, value);
|
|
}
|
|
break;
|
|
|
|
case OT_TABLE:
|
|
case OT_ARRAY:
|
|
default:
|
|
__LOG_E__ << "Cannot convert input Squirrel type to metatag value.\n";
|
|
break;
|
|
}
|
|
return tag;
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//-----------------------------------------------------------------------------
|
|
SQInteger MetafileAddRoot(HSQUIRRELVM vm)
|
|
{
|
|
__SQ_GETSTART(2)
|
|
__SQ_GETSAFEPTR(mf, File, typetag_Metafile)
|
|
__SQ_GETSTRING(path)
|
|
Tag *tag = new Tag(path);
|
|
if (!tag)
|
|
return sq_throwerror(vm, "Failed to allocate metatag.");
|
|
mf->AddRoot(tag);
|
|
__SQ_GETEND
|
|
__SQ_RETURNSAFEPTR(tag, typetag_Metatag)
|
|
}
|
|
SQInteger MetatagAddChild(HSQUIRRELVM vm)
|
|
{
|
|
__SQ_GETSTART(2)
|
|
__SQ_GETSAFEPTR(itg, Tag, typetag_Metatag)
|
|
__SQ_GETSTRING(path)
|
|
Tag *tag = new Tag(path);
|
|
if (!tag)
|
|
return sq_throwerror(vm, "Failed to allocate metatag.");
|
|
itg->AddChild(tag);
|
|
__SQ_GETEND
|
|
__SQ_RETURNSAFEPTR(tag, typetag_Metatag)
|
|
}
|
|
SQInteger MetatagDeleteChild(HSQUIRRELVM vm)
|
|
{
|
|
__SQ_GETSTART(2)
|
|
__SQ_GETSAFEPTR(tag, Tag, typetag_Metatag)
|
|
__SQ_GETSAFEPTR(child, Tag, typetag_Metatag)
|
|
__SQ_GETEND
|
|
|
|
if (!tag->RemoveTag(child))
|
|
return sq_throwerror(vm, "Child tag does not belong to this tag.");
|
|
|
|
__SQ_INVALIDATENATIVEREF(child);
|
|
_safe_delete(child); // tags are not managed
|
|
__SQ_RETURN
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//-----------------------------------------------------------------------------
|
|
SQInteger MetafileAddRootWithValue(HSQUIRRELVM vm)
|
|
{
|
|
__SQ_GETSTART(3)
|
|
__SQ_GETSAFEPTR(mf, File, typetag_Metafile)
|
|
__SQ_GETSTRING(path)
|
|
Tag *tag = CreateMetatagFromSquirrelStackEntry(vm, __SQ_STACKPOS, path);
|
|
__SQ_GETUPDATESTACK
|
|
__SQ_GETEND
|
|
if (!tag)
|
|
return sq_throwerror(vm, "Failed to add root tag to metafile.");
|
|
mf->AddRoot(tag);
|
|
__SQ_RETURNSAFEPTR(tag, typetag_Metatag)
|
|
}
|
|
SQInteger MetatagAddChildWithValue(HSQUIRRELVM vm)
|
|
{
|
|
__SQ_GETSTART(3)
|
|
__SQ_GETSAFEPTR(itg, Tag, typetag_Metatag)
|
|
__SQ_GETSTRING(path)
|
|
Tag *tag = CreateMetatagFromSquirrelStackEntry(vm, __SQ_STACKPOS, path);
|
|
__SQ_GETUPDATESTACK
|
|
__SQ_GETEND
|
|
if (!tag)
|
|
return sq_throwerror(vm, "Failed to add child tag.");
|
|
itg->AddChild(tag);
|
|
__SQ_RETURNSAFEPTR(tag, typetag_Metatag)
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//-----------------------------------------------------------------------------
|
|
SQInteger MetafileGetTag(HSQUIRRELVM vm)
|
|
{
|
|
__SQ_GETSTART(2)
|
|
__SQ_GETSAFEPTR(mf, File, typetag_Metafile)
|
|
__SQ_GETSTRING(path)
|
|
Tag *tag = mf->GetTag(path);
|
|
__SQ_GETEND
|
|
__SQ_RETURNSAFEPTR(tag, typetag_Metatag)
|
|
}
|
|
SQInteger MetafileGetTypedTag(HSQUIRRELVM vm)
|
|
{
|
|
__SQ_GETSTART(3)
|
|
__SQ_GETSAFEPTR(mf, File, typetag_Metafile)
|
|
__SQ_GETSTRING(path)
|
|
__SQ_GETINT(type)
|
|
Tag *tag = mf->GetTypedTag(path, (GS::Variant::Type)type);
|
|
__SQ_GETEND
|
|
__SQ_RETURNSAFEPTR(tag, typetag_Metatag)
|
|
}
|
|
SQInteger MetatagGetTag(HSQUIRRELVM vm)
|
|
{
|
|
__SQ_GETSTART(2)
|
|
__SQ_GETSAFEPTR(mf, Tag, typetag_Metatag)
|
|
__SQ_GETSTRING(path)
|
|
Tag *tag = mf->GetTag(path);
|
|
__SQ_GETEND
|
|
__SQ_RETURNSAFEPTR(tag, typetag_Metatag)
|
|
}
|
|
SQInteger MetatagGetTypedTag(HSQUIRRELVM vm)
|
|
{
|
|
__SQ_GETSTART(3)
|
|
__SQ_GETSAFEPTR(mf, Tag, typetag_Metatag)
|
|
__SQ_GETSTRING(path)
|
|
__SQ_GETINT(type)
|
|
Tag *tag = mf->GetTypedTag(path, (GS::Variant::Type)type);
|
|
__SQ_GETEND
|
|
__SQ_RETURNSAFEPTR(tag, typetag_Metatag)
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//-----------------------------------------------------------------------------
|
|
SQInteger MetatagGetType(HSQUIRRELVM vm)
|
|
{
|
|
__SQ_GETSINGLESAFEPTR(tag, Tag, typetag_Metatag)
|
|
__SQ_RETURNINT((int)tag->GetValue().GetType())
|
|
}
|
|
SQInteger MetatagGetName(HSQUIRRELVM vm)
|
|
{
|
|
__SQ_GETSINGLESAFEPTR(tag, Tag, typetag_Metatag)
|
|
__SQ_RETURNSTRING(tag->name.c_str())
|
|
}
|
|
SQInteger MetatagSetName(HSQUIRRELVM vm)
|
|
{
|
|
__SQ_GETSTART(2)
|
|
__SQ_GETSAFEPTR(tag, Tag, typetag_Metatag)
|
|
__SQ_GETSTRING(_name)
|
|
tag->name = _name;
|
|
__SQ_GETEND
|
|
__SQ_RETURN
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//-----------------------------------------------------------------------------
|
|
SQInteger MetatagGetValue(HSQUIRRELVM vm)
|
|
{
|
|
__SQ_GETSINGLESAFEPTR(tag, Tag, typetag_Metatag)
|
|
|
|
switch (tag->GetValue().GetType())
|
|
{
|
|
default:
|
|
case GS::Variant::VariantNone:
|
|
case GS::Variant::VariantBinary:
|
|
break;
|
|
|
|
case GS::Variant::VariantBool:
|
|
__SQ_RETURNBOOL(tag->GetBool())
|
|
case GS::Variant::VariantInteger:
|
|
__SQ_RETURNINT(tag->GetInteger())
|
|
case GS::Variant::VariantFloat:
|
|
__SQ_RETURNFLOAT(tag->GetReal())
|
|
case GS::Variant::VariantString:
|
|
__SQ_RETURNSTRING(tag->GetString())
|
|
}
|
|
|
|
__LOG_E__ << "Cannot get value from tag '" << tag->name << "'. Unsupported type.\n";
|
|
__SQ_RETURNINT(-1)
|
|
}
|
|
SQInteger MetatagSetValue(HSQUIRRELVM vm)
|
|
{
|
|
__SQ_GETSTART(2)
|
|
__SQ_GETSAFEPTR(tag, Tag, typetag_Metatag)
|
|
|
|
switch (sq_gettype(vm, -1))
|
|
{
|
|
case OT_INTEGER:
|
|
{
|
|
__SQ_GETINT(value)
|
|
tag->SetInteger(value);
|
|
}
|
|
break;
|
|
|
|
case OT_FLOAT:
|
|
{
|
|
__SQ_GETFLOAT(value)
|
|
tag->SetReal(value);
|
|
}
|
|
break;
|
|
|
|
case OT_BOOL:
|
|
{
|
|
__SQ_GETBOOL(value)
|
|
tag->SetBool(value ? true : false);
|
|
}
|
|
break;
|
|
|
|
case OT_STRING:
|
|
{
|
|
__SQ_GETSTRING(value)
|
|
tag->SetString(value);
|
|
}
|
|
break;
|
|
|
|
case OT_NULL:
|
|
case OT_TABLE:
|
|
case OT_ARRAY:
|
|
default:
|
|
return sq_throwerror(vm, "Type cannot be converted to metatag value.");
|
|
}
|
|
|
|
__SQ_GETEND
|
|
__SQ_RETURN
|
|
}
|
|
//-----------------------------------------------------------------------------
|
|
|
|
//-----------------------------------------------------------------------------
|
|
void RegisterNMLBinding(HSQUIRRELVM vm)
|
|
{
|
|
/*#
|
|
Topic: Metafile
|
|
Type: Metafile
|
|
Type: Metatag
|
|
Desc: A metafile is very similar to an XML file, it is mostly used to store data in a structured way.
|
|
#*/
|
|
|
|
/*#
|
|
Section: MetaFile
|
|
Desc: File functions
|
|
#*/
|
|
/*#
|
|
Func: MetafileNew
|
|
Proto: Metafile:
|
|
Desc: Create a new metafile, this object is managed, the VM will free it.
|
|
#*/
|
|
sq_register(vm, MetafileNew, "MetafileNew", _SC("."));
|
|
// Obsolete
|
|
sq_register(vm, MetafileDelete, "MetafileDelete", _SC(".x"));
|
|
/*#
|
|
Func: MetafileLoadFromString
|
|
Proto: bool:Metafile,string content
|
|
Desc: Load metafile from a string.
|
|
#*/
|
|
sq_register(vm, MetafileLoadFromString, "MetafileLoadFromString", _SC(".xs"));
|
|
/*#
|
|
Func: MetafileLoad
|
|
Proto: bool:Metafile,string path
|
|
Desc: Load metafile from file system.
|
|
#*/
|
|
sq_register(vm, MetafileLoad, "MetafileLoad", _SC(".xs"));
|
|
/*#
|
|
Func: MetafileSave
|
|
Proto: bool:Metafile,string path
|
|
Desc: Save metafile to file system.
|
|
#*/
|
|
sq_register(vm, MetafileSave, "MetafileSave", _SC(".xs"));
|
|
/*#
|
|
Func: MetafileAddRoot
|
|
Proto: Metatag:Metafile,string tag_name
|
|
Desc: Add metafile root, returns the newly created metatag.
|
|
#*/
|
|
sq_register(vm, MetafileAddRoot, "MetafileAddRoot", _SC(".xs"));
|
|
/*#
|
|
Func: MetafileAddRootWithValue
|
|
Proto: Metatag:Metafile,string tag_name,...
|
|
Desc: Add metafile root, returns the newly created metatag.
|
|
#*/
|
|
sq_register(vm, MetafileAddRootWithValue, "MetafileAddRootWithValue", _SC(".xs."));
|
|
/*#
|
|
Func: MetafileGetRoots
|
|
Proto: array:Metafile
|
|
Desc: Return all root tags of a metafile in an array.
|
|
#*/
|
|
sq_register(vm, MetafileGetRoots, "MetafileGetRoots", _SC(".x"));
|
|
/*#
|
|
Func: MetafileGetTag
|
|
Proto: Metatag:Metafile,string tag_path
|
|
Desc: Get metatag from metafile, the metatag path is formatted as follow: tag:child:tag_id; (eg: 'Pref:Sound:Volume;').
|
|
#*/
|
|
sq_register(vm, MetafileGetTag, "MetafileGetTag", _SC(".xs"));
|
|
/*#
|
|
Func: MetafileGetTypedTag
|
|
Proto: Metatag:Metafile,string tag_path,TagType
|
|
Desc: Get metatag of a specific value type from a metafile.
|
|
#*/
|
|
sq_register(vm, MetafileGetTypedTag, "MetafileGetTypedTag", _SC(".xsi"));
|
|
|
|
/*#
|
|
Section: MetaTag
|
|
Desc: Tag functions
|
|
#*/
|
|
/*#
|
|
Func: MetatagGetName
|
|
Proto: string:Metatag
|
|
Desc: Get metatag name.
|
|
#*/
|
|
sq_register(vm, MetatagGetName, "MetatagGetName", _SC(".x"));
|
|
/*#
|
|
Func: MetatagSetName
|
|
Proto: void:Metatag,String
|
|
Desc: Set metatag name.
|
|
#*/
|
|
sq_register(vm, MetatagSetName, "MetatagSetName", _SC(".xs"));
|
|
/*#
|
|
Func: MetatagGetType
|
|
Proto: TagType:Metatag
|
|
Desc: Get metatag type.
|
|
#*/
|
|
sq_register(vm, MetatagGetType, "MetatagGetType", _SC(".x"));
|
|
/*#
|
|
Func: MetatagGetValue
|
|
Proto: ...:Metatag
|
|
Desc: Get metatag value.
|
|
#*/
|
|
sq_register(vm, MetatagGetValue, "MetatagGetValue", _SC(".x"));
|
|
/*#
|
|
Func: MetatagSetValue
|
|
Proto: void:Metatag,...
|
|
Desc: Set metatag value, the value type is automatically handled.
|
|
#*/
|
|
sq_register(vm, MetatagSetValue, "MetatagSetValue", _SC(".x."));
|
|
|
|
/*#
|
|
Func: MetatagDeleteChild
|
|
Proto: void:Metatag tag, Metatag child
|
|
Desc: Delete a metatag child tag.
|
|
Note: The removed child tag is freed and all existing script references to it are invalidated.
|
|
#*/
|
|
sq_register(vm, MetatagDeleteChild, "MetatagDeleteChild", _SC(".xx"));
|
|
/*#
|
|
Func: MetatagAddChild
|
|
Proto: Metatag:Metatag,string tag_name
|
|
Desc: Add metatag child, returns the newly created metatag.
|
|
#*/
|
|
sq_register(vm, MetatagAddChild, "MetatagAddChild", _SC(".xs"));
|
|
/*#
|
|
Func: MetatagAddChildWithValue
|
|
Proto: Metatag:Metatag,string tag_name,...
|
|
Desc: Add metatag child, returns the newly created metatag.
|
|
#*/
|
|
sq_register(vm, MetatagAddChildWithValue, "MetatagAddChildWithValue", _SC(".xs."));
|
|
|
|
/*#
|
|
Func: MetatagGetTag
|
|
Proto: Metatag:Metatag,string tag_path
|
|
Desc: Find metatag child.
|
|
#*/
|
|
sq_register(vm, MetatagGetTag, "MetatagGetTag", _SC(".xs"));
|
|
/*#
|
|
Func: MetatagGetTypedTag
|
|
Proto: Metatag:Metatag,string tag_path,TagType
|
|
Desc: Find child of a specific value type from a metatag.
|
|
#*/
|
|
sq_register(vm, MetatagGetTypedTag, "MetatagGetTypedTag", _SC(".xsi"));
|
|
/*#
|
|
Func: MetatagGetChildren
|
|
Proto: Array:Metatag
|
|
Desc: Return all children of a metatag in an array.
|
|
#*/
|
|
sq_register(vm, MetatagGetChildren, "MetatagGetChildren", _SC(".x"));
|
|
|
|
// Push defines.
|
|
sq_pushroottable(vm);
|
|
|
|
/*#
|
|
Enum: TagType
|
|
Values: TagTypeBinary,TagTypeString,TagTypeInteger,TagTypeReal,TagTypeNode,TagTypeNone
|
|
#*/
|
|
sq_pushstring(vm, "TagTypeBinary", -1); sq_pushinteger(vm, GS::Variant::VariantBinary); sq_newslot(vm, -3, true);
|
|
sq_pushstring(vm, "TagTypeInteger", -1); sq_pushinteger(vm, GS::Variant::VariantInteger); sq_newslot(vm, -3, true);
|
|
sq_pushstring(vm, "TagTypeNone", -1); sq_pushinteger(vm, GS::Variant::VariantNone); sq_newslot(vm, -3, true);
|
|
sq_pushstring(vm, "TagTypeReal", -1); sq_pushinteger(vm, GS::Variant::VariantFloat); sq_newslot(vm, -3, true);
|
|
sq_pushstring(vm, "TagTypeString", -1); sq_pushinteger(vm, GS::Variant::VariantString); sq_newslot(vm, -3, true);
|
|
#if 1
|
|
sq_pushstring(vm, "TagTypeNode", -1); sq_pushinteger(vm, GS::Variant::VariantNone); sq_newslot(vm, -3, true);
|
|
sq_pushstring(vm, "TagTypeTag", -1); sq_pushinteger(vm, GS::Variant::VariantNone); sq_newslot(vm, -3, true);
|
|
sq_pushstring(vm, "TagTypeShortcut", -1); sq_pushinteger(vm, GS::Variant::VariantNone); sq_newslot(vm, -3, true);
|
|
#endif
|
|
|
|
sq_pop(vm, 1);
|
|
}
|
|
//-----------------------------------------------------------------------------
|