1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-24 15:26:15 +00:00

-WIP Exporter to Godot 3.0, only text scenes (no .scn) and still kind of buggy

This commit is contained in:
Juan Linietsky
2017-02-12 22:52:02 -03:00
parent 6abe141579
commit ebb7d2cdb7
17 changed files with 2398 additions and 69 deletions

2
core/io/export_data.cpp Normal file
View File

@@ -0,0 +1,2 @@
#include "export_data.h"

86
core/io/export_data.h Normal file
View File

@@ -0,0 +1,86 @@
#ifndef EXPORT_DATA_H
#define EXPORT_DATA_H
#include "variant.h"
#include "vector.h"
#include "map.h"
struct ExportData {
struct Dependency {
String path;
String type;
};
Map<int,Dependency> dependencies;
struct PropertyData {
String name;
Variant value;
};
struct ResourceData {
String type;
int index;
List<PropertyData> properties;
};
Vector<ResourceData> resources;
struct NodeData {
bool text_data;
String name;
String type;
String instance;
//int info
int owner_int; //depending type
int parent_int;
bool instance_is_placeholder;
//text info
NodePath parent;
NodePath owner;
String instance_placeholder;
Vector<String> groups;
List<PropertyData> properties;
NodeData() { parent_int=0; owner_int=0; text_data=true; }
};
Vector<NodeData> nodes;
struct Connection {
bool text_data;
int from_int;
int to_int;
NodePath from;
NodePath to;
String signal;
String method;
Array binds;
int flags;
Connection() { text_data=true; }
};
Vector<Connection> connections;
Vector<NodePath> editables;
Array node_paths; //for integer packed data
Variant base_scene;
};
#endif // EXPORT_DATA_H

View File

@@ -118,7 +118,7 @@ void ResourceInteractiveLoaderBinary::_advance_padding(uint32_t p_len) {
}
Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) {
Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v,bool p_for_export_data) {
uint32_t type = f->get_32();
@@ -378,56 +378,42 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) {
} break;
case OBJECT_INTERNAL_RESOURCE: {
uint32_t index=f->get_32();
String path = res_path+"::"+itos(index);
RES res = ResourceLoader::load(path);
if (res.is_null()) {
WARN_PRINT(String("Couldn't load resource: "+path).utf8().get_data());
if (p_for_export_data) {
r_v="@RESLOCAL:"+itos(index);
} else {
String path = res_path+"::"+itos(index);
RES res = ResourceLoader::load(path);
if (res.is_null()) {
WARN_PRINT(String("Couldn't load resource: "+path).utf8().get_data());
}
r_v=res;
}
r_v=res;
} break;
case OBJECT_EXTERNAL_RESOURCE: {
//old file format, still around for compatibility
String type = get_unicode_string();
String path = get_unicode_string();
if (path.find("://")==-1 && path.is_rel_path()) {
// path is relative to file being loaded, so convert to a resource path
path=Globals::get_singleton()->localize_path(res_path.get_base_dir().plus_file(path));
if (p_for_export_data) {
}
if (remaps.find(path)) {
path=remaps[path];
}
RES res=ResourceLoader::load(path,type);
if (res.is_null()) {
WARN_PRINT(String("Couldn't load resource: "+path).utf8().get_data());
}
r_v=res;
} break;
case OBJECT_EXTERNAL_RESOURCE_INDEX: {
//new file format, just refers to an index in the external list
uint32_t erindex = f->get_32();
if (erindex>=external_resources.size()) {
WARN_PRINT("Broken external resource! (index out of size");
r_v=Variant();
r_v="@RESPATH:"+type+":"+path;
} else {
String type = external_resources[erindex].type;
String path = external_resources[erindex].path;
if (path.find("://")==-1 && path.is_rel_path()) {
// path is relative to file being loaded, so convert to a resource path
path=Globals::get_singleton()->localize_path(res_path.get_base_dir().plus_file(path));
}
if (remaps.find(path)) {
path=remaps[path];
}
RES res=ResourceLoader::load(path,type);
if (res.is_null()) {
@@ -436,6 +422,37 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) {
r_v=res;
}
} break;
case OBJECT_EXTERNAL_RESOURCE_INDEX: {
//new file format, just refers to an index in the external list
uint32_t erindex = f->get_32();
if (p_for_export_data) {
r_v="@RESEXTERNAL:"+itos(erindex);
} else {
if (erindex>=external_resources.size()) {
WARN_PRINT("Broken external resource! (index out of size");
r_v=Variant();
} else {
String type = external_resources[erindex].type;
String path = external_resources[erindex].path;
if (path.find("://")==-1 && path.is_rel_path()) {
// path is relative to file being loaded, so convert to a resource path
path=Globals::get_singleton()->localize_path(res_path.get_base_dir().plus_file(path));
}
RES res=ResourceLoader::load(path,type);
if (res.is_null()) {
WARN_PRINT(String("Couldn't load resource: "+path).utf8().get_data());
}
r_v=res;
}
}
} break;
default: {
@@ -455,10 +472,10 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) {
len&=0x7FFFFFFF;
for(uint32_t i=0;i<len;i++) {
Variant key;
Error err = parse_variant(key);
Error err = parse_variant(key,p_for_export_data);
ERR_FAIL_COND_V(err,ERR_FILE_CORRUPT);
Variant value;
err = parse_variant(value);
err = parse_variant(value,p_for_export_data);
ERR_FAIL_COND_V(err,ERR_FILE_CORRUPT);
d[key]=value;
}
@@ -472,7 +489,7 @@ Error ResourceInteractiveLoaderBinary::parse_variant(Variant& r_v) {
a.resize(len);
for(uint32_t i=0;i<len;i++) {
Variant val;
Error err = parse_variant(val);
Error err = parse_variant(val,p_for_export_data);
ERR_FAIL_COND_V(err,ERR_FILE_CORRUPT);
a[i]=val;
}
@@ -862,6 +879,77 @@ String ResourceInteractiveLoaderBinary::get_unicode_string() {
return s;
}
Error ResourceInteractiveLoaderBinary::get_export_data(ExportData& r_export_data) {
for(int i=0;i<external_resources.size();i++) {
ExportData::Dependency dep;
dep.path=external_resources[i].path;
dep.type=external_resources[i].type;
r_export_data.dependencies[i]=dep;
}
for(int i=0;i<internal_resources.size();i++) {
bool main = i==(internal_resources.size()-1);
//maybe it is loaded already
r_export_data.resources.resize( r_export_data.resources.size()+1 );
ExportData::ResourceData &res_data=r_export_data.resources[ r_export_data.resources.size()-1 ];
res_data.index=-1;
if (!main) {
String path=internal_resources[i].path;
if (path.begins_with("local://")) {
path=path.replace_first("local://","");
res_data.index = path.to_int();
}
} else {
}
uint64_t offset = internal_resources[i].offset;
f->seek(offset);
String t = get_unicode_string();
res_data.type=t;
int pc = f->get_32();
//set properties
for(int i=0;i<pc;i++) {
uint32_t name_idx = f->get_32();
if (name_idx>=(uint32_t)string_map.size()) {
error=ERR_FILE_CORRUPT;
ERR_FAIL_V(ERR_FILE_CORRUPT);
}
Variant value;
error = parse_variant(value,true);
if (error)
return error;
ExportData::PropertyData pdata;
pdata.name=string_map[name_idx];
pdata.value=value;
res_data.properties.push_back(pdata);
}
}
return OK;
}
void ResourceInteractiveLoaderBinary::get_dependencies(FileAccess *p_f,List<String> *p_dependencies,bool p_add_types) {
@@ -1175,6 +1263,7 @@ Error ResourceFormatLoaderBinary::load_import_metadata(const String &p_path, Ref
}
ResourceFormatLoaderBinary *ResourceFormatLoaderBinary::singleton=NULL;
void ResourceFormatLoaderBinary::get_dependencies(const String& p_path,List<String> *p_dependencies,bool p_add_types) {
@@ -1188,6 +1277,28 @@ void ResourceFormatLoaderBinary::get_dependencies(const String& p_path,List<Stri
ria->get_dependencies(f,p_dependencies,p_add_types);
}
Error ResourceFormatLoaderBinary::get_export_data(const String& p_path,ExportData& r_export_data) {
Error err;
FileAccess *f = FileAccess::open(p_path,FileAccess::READ,&err);
if (err!=OK) {
ERR_FAIL_COND_V(err!=OK,ERR_CANT_OPEN);
}
Ref<ResourceInteractiveLoaderBinary> ria = memnew( ResourceInteractiveLoaderBinary );
ria->local_path=Globals::get_singleton()->localize_path(p_path);
ria->res_path=ria->local_path;
// ria->set_local_path( Globals::get_singleton()->localize_path(p_path) );
ria->open(f);
return ria->get_export_data(r_export_data);
}
Error ResourceFormatLoaderBinary::rename_dependencies(const String &p_path,const Map<String,String>& p_map) {

View File

@@ -79,7 +79,7 @@ class ResourceInteractiveLoaderBinary : public ResourceInteractiveLoader {
friend class ResourceFormatLoaderBinary;
Error parse_variant(Variant& r_v);
Error parse_variant(Variant& r_v, bool p_for_export_data=false);
public:
@@ -94,6 +94,7 @@ public:
String recognize(FileAccess *p_f);
void get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types);
Error get_export_data(ExportData& r_export_data);
ResourceInteractiveLoaderBinary();
~ResourceInteractiveLoaderBinary();
@@ -111,9 +112,11 @@ public:
virtual void get_dependencies(const String& p_path, List<String> *p_dependencies, bool p_add_types=false);
virtual Error load_import_metadata(const String &p_path, Ref<ResourceImportMetadata>& r_var) const;
virtual Error rename_dependencies(const String &p_path,const Map<String,String>& p_map);
virtual Error get_export_data(const String& p_path,ExportData& r_export_data);
static ResourceFormatLoaderBinary *singleton;
ResourceFormatLoaderBinary() { singleton=this; }
};

View File

@@ -339,7 +339,7 @@ Error ResourceInteractiveLoaderXML::_parse_array_element(Vector<char> &buff,bool
return OK;
}
Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name) {
Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name, bool p_for_export_data) {
bool exit;
Tag *tag = parse_tag(&exit);
@@ -382,7 +382,7 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name)
int dictline = get_current_line();
err=parse_property(key,tagname);
err=parse_property(key,tagname,p_for_export_data);
if (err && err!=ERR_FILE_EOF) {
ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Error parsing dictionary: "+name+" (from line "+itos(dictline)+")");
@@ -392,7 +392,7 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name)
if (err)
break;
Variant value;
err=parse_property(value,tagname);
err=parse_property(value,tagname,p_for_export_data);
if (err) {
ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": Error parsing dictionary: "+name+" (from line "+itos(dictline)+")");
}
@@ -429,7 +429,7 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name)
Variant v;
String tagname;
int idx=0;
while( (err=parse_property(v,tagname))==OK ) {
while( (err=parse_property(v,tagname,p_for_export_data))==OK ) {
ERR_CONTINUE( idx <0 || idx >=len );
@@ -463,7 +463,20 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name)
if (tag->args.has("resource_type"))
hint=tag->args["resource_type"];
if (p_for_export_data) {
String prop;
if (path.begins_with("local://")) {
prop="@RESLOCAL:"+itos(path.replace("local://","").to_int());
}
r_v=prop;
return OK;
}
if (path.begins_with("local://"))
path=path.replace("local://",local_path+"::");
else if (path.find("://")==-1 && path.is_rel_path()) {
// path is relative to file being loaded, so convert to a resource path
@@ -488,6 +501,18 @@ Error ResourceInteractiveLoaderXML::parse_property(Variant& r_v, String &r_name)
} else if (tag->args.has("external")) {
int index = tag->args["external"].to_int();
if (p_for_export_data) {
String prop;
prop="@RESEXTERNAL:"+itos(index);
r_v=prop;
return OK;
}
if (ext_resources.has(index)) {
String path=ext_resources[index].path;
String type=ext_resources[index].type;
@@ -1653,6 +1678,139 @@ void ResourceInteractiveLoaderXML::get_dependencies(FileAccess *f,List<String> *
}
Error ResourceInteractiveLoaderXML::get_export_data(FileAccess *p_f,ExportData& r_export_data) {
open(p_f);
ERR_FAIL_COND_V(error!=OK,error);
while (true) {
bool exit;
Tag *tag = parse_tag(&exit);
if (!tag) {
error=ERR_FILE_CORRUPT;
if (!exit) // shouldn't have exited
ERR_FAIL_V(error);
error=ERR_FILE_EOF;
return error;
}
bool main;
if (tag->name=="ext_resource") {
ExportData::Dependency dep;
error=ERR_FILE_CORRUPT;
ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": <ext_resource> missing 'path' field.");
ERR_FAIL_COND_V(!tag->args.has("path"),ERR_FILE_CORRUPT);
String type="Resource";
if (tag->args.has("type"))
type=tag->args["type"];
String path = tag->args["path"];
dep.path=path;
dep.type=type;
if (tag->args.has("index")) {
ExtResource er;
er.path=path;
er.type=type;
r_export_data.dependencies[tag->args["index"].to_int()]=dep;
} else {
int index = r_export_data.dependencies.size();
r_export_data.dependencies[index]=dep;
}
Error err = close_tag("ext_resource");
if (err)
return error;
continue;
} else if (tag->name=="resource") {
main=false;
} else if (tag->name=="main_resource") {
main=true;
} else {
ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": unexpected main tag: "+tag->name);
error=ERR_FILE_CORRUPT;
ERR_FAIL_V(error);
}
r_export_data.resources.resize( r_export_data.resources.size()+1 );
ExportData::ResourceData &res_data=r_export_data.resources[ r_export_data.resources.size()-1 ];
res_data.index=-1;
if (!main) {
//loading resource
String path=tag->args["path"];
error=OK;
if (path.begins_with("local://")) {
//built-in resource (but really external)
path=path.replace("local://","");
res_data.index=path.to_int();
}
res_data.type= tag->args["type"];
} else {
res_data.type=resource_type;
}
//load properties
while(true) {
String name;
Variant v;
Error err;
err = parse_property(v,name);
if (err==ERR_FILE_EOF) //tag closed
break;
if (err!=OK) {
ERR_EXPLAIN(local_path+":"+itos(get_current_line())+": XML Parsing aborted.");
ERR_FAIL_COND_V(err!=OK,ERR_FILE_CORRUPT);
}
ExportData::PropertyData prop;
prop.name=name;
prop.value=v;
res_data.properties.push_back(prop);
}
if (main) {
return OK;
}
}
return OK;
}
Error ResourceInteractiveLoaderXML::rename_dependencies(FileAccess *p_f, const String &p_path,const Map<String,String>& p_map) {
open(p_f);
@@ -2021,6 +2179,23 @@ void ResourceFormatLoaderXML::get_dependencies(const String& p_path,List<String>
}
Error ResourceFormatLoaderXML::get_export_data(const String& p_path,ExportData& r_export_data) {
FileAccess *f = FileAccess::open(p_path,FileAccess::READ);
if (!f) {
ERR_FAIL_V(ERR_CANT_OPEN);
}
Ref<ResourceInteractiveLoaderXML> ria = memnew( ResourceInteractiveLoaderXML );
ria->local_path=Globals::get_singleton()->localize_path(p_path);
ria->res_path=ria->local_path;
return ria->get_export_data(f,r_export_data);
}
Error ResourceFormatLoaderXML::rename_dependencies(const String &p_path,const Map<String,String>& p_map) {
FileAccess *f = FileAccess::open(p_path,FileAccess::READ);
@@ -2036,6 +2211,7 @@ Error ResourceFormatLoaderXML::rename_dependencies(const String &p_path,const Ma
return ria->rename_dependencies(f,p_path,p_map);
}
ResourceFormatLoaderXML *ResourceFormatLoaderXML::singleton=NULL;
/****************************************************************************************/
/****************************************************************************************/

View File

@@ -79,7 +79,7 @@ friend class ResourceFormatLoaderXML;
_FORCE_INLINE_ void unquote(String& p_str);
Error goto_end_of_tag();
Error parse_property_data(String &r_data);
Error parse_property(Variant& r_v, String &r_name);
Error parse_property(Variant& r_v, String &r_name,bool p_for_export_data=false);
Error error;
@@ -98,6 +98,7 @@ public:
void get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types);
Error rename_dependencies(FileAccess *p_f, const String &p_path,const Map<String,String>& p_map);
Error get_export_data(FileAccess *p_f,ExportData& r_export_data);
~ResourceInteractiveLoaderXML();
@@ -106,6 +107,7 @@ public:
class ResourceFormatLoaderXML : public ResourceFormatLoader {
public:
static ResourceFormatLoaderXML *singleton;
virtual Ref<ResourceInteractiveLoader> load_interactive(const String &p_path,Error *r_error=NULL);
virtual void get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions) const;
virtual void get_recognized_extensions(List<String> *p_extensions) const;
@@ -113,7 +115,9 @@ public:
virtual String get_resource_type(const String &p_path) const;
virtual void get_dependencies(const String& p_path, List<String> *p_dependencies, bool p_add_types=false);
virtual Error rename_dependencies(const String &p_path,const Map<String,String>& p_map);
virtual Error get_export_data(const String& p_path,ExportData& r_export_data);
ResourceFormatLoaderXML() { singleton=this; }
};

View File

@@ -399,6 +399,34 @@ void ResourceLoader::get_dependencies(const String& p_path, List<String> *p_depe
}
}
Error ResourceLoader::get_export_data(const String& p_path,ExportData& r_export_data) {
String local_path;
if (p_path.is_rel_path())
local_path="res://"+p_path;
else
local_path = Globals::get_singleton()->localize_path(p_path);
String remapped_path = PathRemap::get_singleton()->get_remap(local_path);
String extension=remapped_path.extension();
for (int i=0;i<loader_count;i++) {
if (!loader[i]->recognize(extension))
continue;
//if (p_type_hint!="" && !loader[i]->handles_type(p_type_hint))
// continue;
return loader[i]->get_export_data(p_path,r_export_data);
}
return ERR_UNAVAILABLE;
}
Error ResourceLoader::rename_dependencies(const String &p_path,const Map<String,String>& p_map) {

View File

@@ -30,7 +30,7 @@
#define RESOURCE_LOADER_H
#include "resource.h"
#include "export_data.h"
/**
@author Juan Linietsky <reduzio@gmail.com>
*/
@@ -67,6 +67,7 @@ public:
virtual void get_dependencies(const String& p_path,List<String> *p_dependencies,bool p_add_types=false);
virtual Error load_import_metadata(const String &p_path, Ref<ResourceImportMetadata>& r_var) const { return ERR_UNAVAILABLE; }
virtual Error rename_dependencies(const String &p_path,const Map<String,String>& p_map) { return OK; }
virtual Error get_export_data(const String& p_path,ExportData& r_export_data) { return ERR_UNAVAILABLE; }
virtual ~ResourceFormatLoader() {}
};
@@ -107,6 +108,8 @@ public:
static void get_dependencies(const String& p_path,List<String> *p_dependencies,bool p_add_types=false);
static Error rename_dependencies(const String &p_path,const Map<String,String>& p_map);
static Error get_export_data(const String& p_path,ExportData& r_export_data);
static String guess_full_filename(const String &p_path,const String& p_type);
static void set_timestamp_on_load(bool p_timestamp) { timestamp_on_load=p_timestamp; }

View File

@@ -178,9 +178,9 @@ Error DirAccess::make_dir_recursive(String p_dir) {
for(int i=0;i<subdirs.size();i++) {
curpath=curpath.plus_file(subdirs[i]);
Error err = make_dir(curpath);
if (err != OK && err != ERR_ALREADY_EXISTS) {
ERR_FAIL_V(err);
}
}

View File

@@ -907,32 +907,25 @@ Error VariantParser::parse_value(Token& token,Variant &value,Stream *p_stream,in
if (p_res_parser && id=="Resource" && p_res_parser->func){
RES res;
Error err = p_res_parser->func(p_res_parser->userdata,p_stream,res,line,r_err_str);
Error err = p_res_parser->func(p_res_parser->userdata,p_stream,value,line,r_err_str);
if (err)
return err;
value=res;
return OK;
} else if (p_res_parser && id=="ExtResource" && p_res_parser->ext_func){
RES res;
Error err = p_res_parser->ext_func(p_res_parser->userdata,p_stream,res,line,r_err_str);
Error err = p_res_parser->ext_func(p_res_parser->userdata,p_stream,value,line,r_err_str);
if (err)
return err;
value=res;
return OK;
} else if (p_res_parser && id=="SubResource" && p_res_parser->sub_func){
RES res;
Error err = p_res_parser->sub_func(p_res_parser->userdata,p_stream,res,line,r_err_str);
Error err = p_res_parser->sub_func(p_res_parser->userdata,p_stream,value,line,r_err_str);
if (err)
return err;
value=res;
return OK;
} else {

View File

@@ -73,7 +73,7 @@ public:
};
typedef Error (*ParseResourceFunc)(void* p_self, Stream* p_stream,Ref<Resource>& r_res,int &line,String &r_err_str);
typedef Error (*ParseResourceFunc)(void* p_self, Stream* p_stream,Variant& r_res,int &line,String &r_err_str);
struct ResourceParser {

View File

@@ -54,7 +54,7 @@ Ref<Resource> ResourceInteractiveLoaderText::get_resource() {
return resource;
}
Error ResourceInteractiveLoaderText::_parse_sub_resource(VariantParser::Stream* p_stream,Ref<Resource>& r_res,int &line,String &r_err_str) {
Error ResourceInteractiveLoaderText::_parse_sub_resource(VariantParser::Stream* p_stream,Variant& r_value_res,int &line,String &r_err_str) {
VariantParser::Token token;
VariantParser::get_token(p_stream,token,line,r_err_str);
@@ -74,9 +74,9 @@ Error ResourceInteractiveLoaderText::_parse_sub_resource(VariantParser::Stream*
return ERR_PARSE_ERROR;
}
r_res=RES(ResourceCache::get(path));
r_value_res=RES(ResourceCache::get(path));
} else {
r_res=RES();
r_value_res=RES();
}
VariantParser::get_token(p_stream,token,line,r_err_str);
@@ -89,7 +89,7 @@ Error ResourceInteractiveLoaderText::_parse_sub_resource(VariantParser::Stream*
return OK;
}
Error ResourceInteractiveLoaderText::_parse_ext_resource(VariantParser::Stream* p_stream,Ref<Resource>& r_res,int &line,String &r_err_str){
Error ResourceInteractiveLoaderText::_parse_ext_resource(VariantParser::Stream* p_stream,Variant& r_value_res,int &line,String &r_err_str){
VariantParser::Token token;
VariantParser::get_token(p_stream,token,line,r_err_str);
@@ -116,13 +116,15 @@ Error ResourceInteractiveLoaderText::_parse_ext_resource(VariantParser::Stream*
}
r_res=ResourceLoader::load(path,type);
RES res = ResourceLoader::load(path,type);
if (r_res.is_null()) {
if (res.is_null()) {
WARN_PRINT(String("Couldn't load external resource: "+path).utf8().get_data());
}
r_value_res=res;
} else {
r_res=RES();
r_value_res=RES();
}
VariantParser::get_token(p_stream,token,line,r_err_str);
@@ -136,6 +138,60 @@ Error ResourceInteractiveLoaderText::_parse_ext_resource(VariantParser::Stream*
}
Error ResourceInteractiveLoaderText::_parse_sub_resource_export(VariantParser::Stream* p_stream,Variant& r_value_res,int &line,String &r_err_str) {
VariantParser::Token token;
VariantParser::get_token(p_stream,token,line,r_err_str);
if (token.type!=VariantParser::TK_NUMBER) {
r_err_str="Expected number (sub-resource index)";
return ERR_PARSE_ERROR;
}
int index = token.value;
r_value_res="@RESLOCAL:"+itos(index);
VariantParser::get_token(p_stream,token,line,r_err_str);
if (token.type!=VariantParser::TK_PARENTHESIS_CLOSE) {
r_err_str="Expected ')'";
return ERR_PARSE_ERROR;
}
return OK;
}
Error ResourceInteractiveLoaderText::_parse_ext_resource_export(VariantParser::Stream* p_stream,Variant& r_value_res,int &line,String &r_err_str){
VariantParser::Token token;
VariantParser::get_token(p_stream,token,line,r_err_str);
if (token.type!=VariantParser::TK_NUMBER) {
r_err_str="Expected number (sub-resource index)";
return ERR_PARSE_ERROR;
}
int id = token.value;
{
r_value_res="@RESEXTERNAL:"+itos(id);
}
VariantParser::get_token(p_stream,token,line,r_err_str);
if (token.type!=VariantParser::TK_PARENTHESIS_CLOSE) {
r_err_str="Expected ')'";
return ERR_PARSE_ERROR;
}
return OK;
}
Error ResourceInteractiveLoaderText::poll() {
if (error!=OK)
@@ -684,6 +740,384 @@ void ResourceInteractiveLoaderText::get_dependencies(FileAccess *f,List<String>
}
}
Error ResourceInteractiveLoaderText::get_export_data(FileAccess *p_f,ExportData& r_export_data) {
open(p_f);
ERR_FAIL_COND_V(error!=OK,error);
while(true) {
print_line("next tag is: "+next_tag.name);
if (next_tag.name=="ext_resource") {
if (!next_tag.fields.has("path")) {
error=ERR_FILE_CORRUPT;
error_text="Missing 'path' in external resource tag";
_printerr();
return error;
}
if (!next_tag.fields.has("type")) {
error=ERR_FILE_CORRUPT;
error_text="Missing 'type' in external resource tag";
_printerr();
return error;
}
if (!next_tag.fields.has("id")) {
error=ERR_FILE_CORRUPT;
error_text="Missing 'id' in external resource tag";
_printerr();
return error;
}
String path=next_tag.fields["path"];
String type=next_tag.fields["type"];
int index=next_tag.fields["id"];
ExportData::Dependency dep;
dep.path=path;
dep.type=type;
r_export_data.dependencies[index]=dep;
error = VariantParser::parse_tag(&stream,lines,error_text,next_tag,&rp_export);
if (error) {
_printerr();
return error;
}
} else if (next_tag.name=="sub_resource") {
if (!next_tag.fields.has("type")) {
error=ERR_FILE_CORRUPT;
error_text="Missing 'type' in external resource tag";
_printerr();
return error;
}
if (!next_tag.fields.has("id")) {
error=ERR_FILE_CORRUPT;
error_text="Missing 'index' in external resource tag";
_printerr();
return error;
}
String type=next_tag.fields["type"];
int id=next_tag.fields["id"];
r_export_data.resources.resize( r_export_data.resources.size()+1 );
ExportData::ResourceData &res_data=r_export_data.resources[ r_export_data.resources.size()-1 ];
res_data.type=type;
res_data.index=id;
while(true) {
String assign;
Variant value;
error = VariantParser::parse_tag_assign_eof(&stream,lines,error_text,next_tag,assign,value,&rp_export);
print_line("get prop: "+assign);
if (error) {
_printerr();
return error;
}
if (assign!=String()) {
ExportData::PropertyData pdata;
pdata.name=assign;
pdata.value=value;
res_data.properties.push_back(pdata);
//it's assignment
} else if (next_tag.name!=String()) {
error=OK;
break;
} else {
error=ERR_FILE_CORRUPT;
error_text="Premature end of file while parsing [sub_resource]";
_printerr();
return error;
}
}
} else if (next_tag.name=="resource") {
if (is_scene) {
error_text+="found the 'resource' tag on a scene file!";
_printerr();
error=ERR_FILE_CORRUPT;
return error;
}
r_export_data.resources.resize( r_export_data.resources.size()+1 );
ExportData::ResourceData &res_data=r_export_data.resources[ r_export_data.resources.size()-1 ];
res_data.index=-1;
res_data.type=res_type;
while(true) {
String assign;
Variant value;
error = VariantParser::parse_tag_assign_eof(&stream,lines,error_text,next_tag,assign,value,&rp_export);
if (error) {
if (error!=ERR_FILE_EOF) {
_printerr();
} else {
return OK;
}
return error;
}
if (assign!=String()) {
ExportData::PropertyData pdata;
pdata.name=assign;
pdata.value=value;
res_data.properties.push_back(pdata);
//it's assignment
} else if (next_tag.name!=String()) {
error=ERR_FILE_CORRUPT;
error_text="Extra tag found when parsing main resource file";
_printerr();
return error;
} else {
return OK;
}
}
return OK;
} else if (next_tag.name=="node") {
if (!is_scene) {
error_text+="found the 'node' tag on a resource file!";
_printerr();
error=ERR_FILE_CORRUPT;
return error;
}
r_export_data.nodes.resize( r_export_data.nodes.size()+1 );
ExportData::NodeData &node_data=r_export_data.nodes[ r_export_data.nodes.size()-1 ];
if (next_tag.fields.has("name")) {
node_data.name=next_tag.fields["name"];
}
if (next_tag.fields.has("parent")) {
node_data.parent=next_tag.fields["parent"];
}
if (next_tag.fields.has("type")) {
node_data.type=next_tag.fields["type"];
}
if (next_tag.fields.has("instance")) {
node_data.instance = next_tag.fields["instance"];
}
if (next_tag.fields.has("instance_placeholder")) {
node_data.instance_placeholder = next_tag.fields["instance_placeholder"];
}
if (next_tag.fields.has("owner")) {
node_data.owner=next_tag.fields["owner"];
}
if (next_tag.fields.has("groups")) {
Array groups = next_tag.fields["groups"];
for (int i=0;i<groups.size();i++) {
node_data.groups.push_back(groups[i]);
}
}
while(true) {
String assign;
Variant value;
error = VariantParser::parse_tag_assign_eof(&stream,lines,error_text,next_tag,assign,value,&rp_export);
print_line("get prop: "+assign);
if (error) {
if (error!=ERR_FILE_EOF) {
_printerr();
return error;
} else {
return OK;
}
}
if (assign!=String()) {
ExportData::PropertyData pdata;
pdata.name=assign;
pdata.value=value;
node_data.properties.push_back(pdata);
//it's assignment
} else if (next_tag.name!=String()) {
print_line("found something else?");
break; //something else
} else {
print_line("done i guess?");
//all done?
return OK;
}
}
} else if (next_tag.name=="connection") {
if (!is_scene) {
error_text+="found the 'connection' tag on a resource file!";
_printerr();
error=ERR_FILE_CORRUPT;
return error;
}
if (!next_tag.fields.has("from")) {
error=ERR_FILE_CORRUPT;
error_text="missing 'from' field fron connection tag";
return error;
}
if (!next_tag.fields.has("to")) {
error=ERR_FILE_CORRUPT;
error_text="missing 'to' field fron connection tag";
return error;
}
if (!next_tag.fields.has("signal")) {
error=ERR_FILE_CORRUPT;
error_text="missing 'signal' field fron connection tag";
return error;
}
if (!next_tag.fields.has("method")) {
error=ERR_FILE_CORRUPT;
error_text="missing 'method' field fron connection tag";
return error;
}
NodePath from = next_tag.fields["from"];
NodePath to = next_tag.fields["to"];
StringName method = next_tag.fields["method"];
StringName signal = next_tag.fields["signal"];
int flags=CONNECT_PERSIST;
Array binds;
if (next_tag.fields.has("flags")) {
flags=next_tag.fields["flags"];
}
if (next_tag.fields.has("binds")) {
binds=next_tag.fields["binds"];
}
ExportData::Connection conn;
conn.from=from;
conn.to=to;
conn.method=method;
conn.signal=signal;
conn.binds=binds;
conn.flags=flags;
r_export_data.connections.push_back(conn);
error = VariantParser::parse_tag(&stream,lines,error_text,next_tag,&rp_export);
if (error) {
if (error!=ERR_FILE_EOF) {
_printerr();
return error;
} else {
return OK;
}
}
continue;
} else if (next_tag.name=="editable") {
if (!is_scene) {
error_text+="found the 'editable' tag on a resource file!";
_printerr();
error=ERR_FILE_CORRUPT;
return error;
}
if (!next_tag.fields.has("path")) {
error=ERR_FILE_CORRUPT;
error_text="missing 'path' field fron connection tag";
_printerr();
return error;
}
NodePath path = next_tag.fields["path"];
r_export_data.editables.push_back(path);
error = VariantParser::parse_tag(&stream,lines,error_text,next_tag,&rp_export);
if (error) {
if (error!=ERR_FILE_EOF) {
_printerr();
return error;
} else {
return OK;
}
}
continue;
} else {
error_text+="Unknown tag in file: "+next_tag.name;
_printerr();
error=ERR_FILE_CORRUPT;
return error;
}
}
ERR_FAIL_V(ERR_BUG);
}
Error ResourceInteractiveLoaderText::rename_dependencies(FileAccess *p_f, const String &p_path,const Map<String,String>& p_map) {
@@ -878,6 +1312,11 @@ void ResourceInteractiveLoaderText::open(FileAccess *p_f,bool p_skip_first_tag)
rp.func=NULL;
rp.userdata=this;
rp_export.ext_func=_parse_ext_resources_export;
rp_export.sub_func=_parse_sub_resources_export;
rp_export.func=NULL;
rp_export.userdata=this;
}
@@ -1024,6 +1463,30 @@ void ResourceFormatLoaderText::get_dependencies(const String& p_path,List<String
}
ResourceFormatLoaderText* ResourceFormatLoaderText::singleton=NULL;
Error ResourceFormatLoaderText::get_export_data(const String& p_path,ExportData& r_export_data) {
FileAccess *f = FileAccess::open(p_path,FileAccess::READ);
if (!f) {
ERR_FAIL_V(ERR_CANT_OPEN);
}
Ref<ResourceInteractiveLoaderText> ria = memnew( ResourceInteractiveLoaderText );
ria->local_path=Globals::get_singleton()->localize_path(p_path);
ria->res_path=ria->local_path;
// ria->set_local_path( Globals::get_singleton()->localize_path(p_path) );
Error err = ria->get_export_data(f,r_export_data);
if (err!=OK) {
ERR_PRINTS("ERROR: "+ria->error_text);
}
return err;
}
Error ResourceFormatLoaderText::rename_dependencies(const String &p_path,const Map<String,String>& p_map) {
FileAccess *f = FileAccess::open(p_path,FileAccess::READ);

View File

@@ -73,14 +73,22 @@ class ResourceInteractiveLoaderText : public ResourceInteractiveLoader {
Map<String,String> remaps;
//void _printerr();
static Error _parse_sub_resources(void* p_self, VariantParser::Stream* p_stream,Ref<Resource>& r_res,int &line,String &r_err_str) { return reinterpret_cast<ResourceInteractiveLoaderText*>(p_self)->_parse_sub_resource(p_stream,r_res,line,r_err_str); }
static Error _parse_ext_resources(void* p_self, VariantParser::Stream* p_stream,Ref<Resource>& r_res,int &line,String &r_err_str) { return reinterpret_cast<ResourceInteractiveLoaderText*>(p_self)->_parse_ext_resource(p_stream,r_res,line,r_err_str); }
static Error _parse_sub_resources(void* p_self, VariantParser::Stream* p_stream,Variant& r_value_res,int &line,String &r_err_str) { return reinterpret_cast<ResourceInteractiveLoaderText*>(p_self)->_parse_sub_resource(p_stream,r_value_res,line,r_err_str); }
static Error _parse_ext_resources(void* p_self, VariantParser::Stream* p_stream,Variant& r_value_res,int &line,String &r_err_str) { return reinterpret_cast<ResourceInteractiveLoaderText*>(p_self)->_parse_ext_resource(p_stream,r_value_res,line,r_err_str); }
Error _parse_sub_resource(VariantParser::Stream* p_stream,Ref<Resource>& r_res,int &line,String &r_err_str);
Error _parse_ext_resource(VariantParser::Stream* p_stream,Ref<Resource>& r_res,int &line,String &r_err_str);
Error _parse_sub_resource(VariantParser::Stream* p_stream,Variant& r_value_res,int &line,String &r_err_str);
Error _parse_ext_resource(VariantParser::Stream* p_stream,Variant& r_value_res,int &line,String &r_err_str);
VariantParser::ResourceParser rp;
static Error _parse_sub_resources_export(void* p_self, VariantParser::Stream* p_stream,Variant& r_value_res,int &line,String &r_err_str) { return reinterpret_cast<ResourceInteractiveLoaderText*>(p_self)->_parse_sub_resource_export(p_stream,r_value_res,line,r_err_str); }
static Error _parse_ext_resources_export(void* p_self, VariantParser::Stream* p_stream,Variant& r_value_res,int &line,String &r_err_str) { return reinterpret_cast<ResourceInteractiveLoaderText*>(p_self)->_parse_ext_resource_export(p_stream,r_value_res,line,r_err_str); }
Error _parse_sub_resource_export(VariantParser::Stream* p_stream,Variant& r_value_res,int &line,String &r_err_str);
Error _parse_ext_resource_export(VariantParser::Stream* p_stream,Variant& r_value_res,int &line,String &r_err_str);
VariantParser::ResourceParser rp_export;
Ref<PackedScene> packed_scene;
@@ -104,6 +112,7 @@ public:
String recognize(FileAccess *p_f);
void get_dependencies(FileAccess *p_f, List<String> *p_dependencies, bool p_add_types);
Error rename_dependencies(FileAccess *p_f, const String &p_path,const Map<String,String>& p_map);
Error get_export_data(FileAccess *p_f,ExportData& r_export_data);
~ResourceInteractiveLoaderText();
@@ -122,8 +131,10 @@ public:
virtual String get_resource_type(const String &p_path) const;
virtual void get_dependencies(const String& p_path, List<String> *p_dependencies, bool p_add_types=false);
virtual Error rename_dependencies(const String &p_path,const Map<String,String>& p_map);
virtual Error get_export_data(const String& p_path,ExportData& r_export_data);
static ResourceFormatLoaderText* singleton;
ResourceFormatLoaderText() { singleton=this;}
};

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,66 @@
#ifndef EDITOR_EXPORT_GODOT3_H
#define EDITOR_EXPORT_GODOT3_H
#include "scene/main/node.h"
#include "tools/editor/editor_file_system.h"
#include "io/export_data.h"
class EditorExportGodot3 {
Map<String,int> pack_names;
HashMap<Variant,int,VariantHasher> pack_values;
int _pack_name(const String& p_name) {
if (pack_names.has(p_name)) {
return pack_names[p_name];
}
int idx = pack_names.size();
pack_names[p_name]=idx;
return idx;
}
int _pack_value(const Variant& p_value) {
if (pack_values.has(p_value)) {
return pack_values[p_value];
}
int idx = pack_values.size();
pack_values[p_value]=idx;
return idx;
}
Map<String,String> prop_rename_map;
Map<String,String> type_rename_map;
Map<String,String> signal_rename_map;
Map<String,String> resource_replace_map;
String _replace_resource(const String& p_res) {
if (resource_replace_map.has(p_res))
return resource_replace_map[p_res];
else
return p_res;
}
Error _get_property_as_text(const Variant& p_variant,String&p_string);
void _save_text(const String& p_path,ExportData &resource);
void _save_binary(const String& p_path,ExportData &resource);
void _save_config(const String &p_path);
void _rename_properties(const String& p_type,List<ExportData::PropertyData> *p_props);
void _convert_resources(ExportData &resource);
void _unpack_packed_scene(ExportData &resource);
void _pack_packed_scene(ExportData &resource);
void _find_files(EditorFileSystemDirectory *p_dir, List<String> * r_files);
public:
Error export_godot3(const String& p_path);
EditorExportGodot3();
};
#endif // EDITOR_EXPORT_GODOT3_H

View File

@@ -2426,7 +2426,10 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
orphan_resources->show();
} break;
case TOOLS_EXPORT_GODOT3: {
export_godot3_dialog->popup_centered_ratio();
} break;
case EDIT_REVERT: {
Node *scene = get_edited_scene();
@@ -5305,6 +5308,7 @@ void EditorNode::_bind_methods() {
ObjectTypeDB::bind_method("_clear_search_box",&EditorNode::_clear_search_box);
ObjectTypeDB::bind_method("_clear_undo_history",&EditorNode::_clear_undo_history);
ObjectTypeDB::bind_method("_dropped_files",&EditorNode::_dropped_files);
ObjectTypeDB::bind_method("_export_godot3_path",&EditorNode::_export_godot3_path);
@@ -5325,6 +5329,15 @@ void EditorNode::_bind_methods() {
}
void EditorNode::_export_godot3_path(const String& p_path) {
Error err = export_godot3.export_godot3(p_path);
if (err!=OK) {
show_warning("Error exporting to Godot 3.0");
}
}
EditorNode::EditorNode() {
EditorHelp::generate_doc(); //before any editor classes are crated
@@ -5797,6 +5810,7 @@ EditorNode::EditorNode() {
p=tool_menu->get_popup();
p->connect("item_pressed",this,"_menu_option");
p->add_item(TTR("Orphan Resource Explorer"),TOOLS_ORPHAN_RESOURCES);
p->add_item(TTR("Export to Godot 3.0"),TOOLS_EXPORT_GODOT3);
export_button = memnew( ToolButton );
export_button->set_tooltip(TTR("Export the project to many platforms."));
@@ -6623,7 +6637,11 @@ EditorNode::EditorNode() {
}
}
export_godot3_dialog = memnew( FileDialog );
export_godot3_dialog->set_access(FileDialog::ACCESS_FILESYSTEM);
export_godot3_dialog->set_mode(FileDialog::MODE_OPEN_DIR);
gui_base->add_child(export_godot3_dialog);
export_godot3_dialog->connect("dir_selected",this,"_export_godot3_path");
Node::set_human_readable_collision_renaming(true);

View File

@@ -80,6 +80,7 @@
#include "fileserver/editor_file_server.h"
#include "editor_resource_preview.h"
#include "editor_export_godot3.h"
#include "progress_dialog.h"
@@ -146,6 +147,7 @@ private:
EDIT_REDO,
EDIT_REVERT,
TOOLS_ORPHAN_RESOURCES,
TOOLS_EXPORT_GODOT3,
RESOURCE_NEW,
RESOURCE_LOAD,
RESOURCE_SAVE,
@@ -281,6 +283,9 @@ private:
HBoxContainer *search_bar;
LineEdit *search_box;
EditorExportGodot3 export_godot3;
FileDialog *export_godot3_dialog;
CreateDialog *create_dialog;
CallDialog *call_dialog;
@@ -573,6 +578,8 @@ private:
void _update_addon_config();
void _export_godot3_path(const String& p_path);
static void _file_access_close_error_notify(const String& p_str);
protected: