/* ----------------------------------------------------------------------------- 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); } //-----------------------------------------------------------------------------