Lot of work in new importer, importing textures now works.

This commit is contained in:
Juan Linietsky 2017-02-01 09:45:45 -03:00
parent 36b6ba8e94
commit 2cd2ca7bbc
32 changed files with 1715 additions and 807 deletions

View file

@ -89,7 +89,7 @@ class PoolVector {
if (!alloc)
return;
ERR_FAIL_COND(alloc->lock>0);
// ERR_FAIL_COND(alloc->lock>0); should not be illegal to lock this for copy on write, as it's a copy on write after all
if (alloc->refcount.get()==1)
return; //nothing to do

View file

@ -2155,7 +2155,7 @@ void Image::fix_alpha_edges() {
return; //not needed
PoolVector<uint8_t> dcopy = data;
PoolVector<uint8_t>::Read rp = data.read();
PoolVector<uint8_t>::Read rp = dcopy.read();
const uint8_t *srcptr=rp.ptr();
PoolVector<uint8_t>::Write wp = data.write();

View file

@ -119,7 +119,10 @@ void ConfigFile::get_section_keys(const String& p_section,List<String> *r_keys)
}
void ConfigFile::erase_section(const String& p_section) {
values.erase(p_section);
}
Error ConfigFile::save(const String& p_path){
@ -215,6 +218,8 @@ void ConfigFile::_bind_methods(){
ClassDB::bind_method(_MD("get_sections"),&ConfigFile::_get_sections);
ClassDB::bind_method(_MD("get_section_keys","section"),&ConfigFile::_get_section_keys);
ClassDB::bind_method(_MD("erase_section","section"),&ConfigFile::erase_section);
ClassDB::bind_method(_MD("load:Error","path"),&ConfigFile::load);
ClassDB::bind_method(_MD("save:Error","path"),&ConfigFile::save);

View file

@ -54,6 +54,8 @@ public:
void get_sections(List<String> *r_sections) const;
void get_section_keys(const String& p_section,List<String> *r_keys) const;
void erase_section(const String& p_section);
Error save(const String& p_path);
Error load(const String& p_path);

View file

@ -30,7 +30,7 @@ Error ResourceFormatImporter::_get_path_and_type(const String& p_path, PathAndTy
return OK;
}
else if (err!=OK) {
ERR_PRINTS("ResourceFormatImporter::load - "+p_path+":"+itos(lines)+" error: "+error_text);
ERR_PRINTS("ResourceFormatImporter::load - "+p_path+".import:"+itos(lines)+" error: "+error_text);
memdelete(f);
return err;
}
@ -71,12 +71,20 @@ RES ResourceFormatImporter::load(const String &p_path,const String& p_original_p
}
return ResourceLoader::load(pat.path,pat.type,false,r_error);
RES res = ResourceLoader::load(pat.path,pat.type,false,r_error);
#ifdef TOOLS_ENABLED
res->set_import_last_modified_time( res->get_last_modified_time() ); //pass this, if used
res->set_import_path(pat.path);
#endif
return res;
}
void ResourceFormatImporter::get_recognized_extensions(List<String> *p_extensions) const{
print_line("getting exts from: "+itos(importers.size()));
Set<String> found;
for (Set< Ref<ResourceImporter> >::Element *E=importers.front();E;E=E->next()) {
@ -84,6 +92,7 @@ void ResourceFormatImporter::get_recognized_extensions(List<String> *p_extension
E->get()->get_recognized_extensions(&local_exts);
for (List<String>::Element *F=local_exts.front();F;F=F->next()) {
if (!found.has(F->get())) {
print_line("adding ext "+String(F->get()));
p_extensions->push_back(F->get());
found.insert(F->get());
}
@ -93,10 +102,14 @@ void ResourceFormatImporter::get_recognized_extensions(List<String> *p_extension
void ResourceFormatImporter::get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions) const{
if (p_type=="") {
return get_recognized_extensions(p_extensions);
}
Set<String> found;
for (Set< Ref<ResourceImporter> >::Element *E=importers.front();E;E=E->next()) {
if (!ClassDB::is_parent_class(p_type,E->get()->get_resource_type()))
if (!ClassDB::is_parent_class(E->get()->get_resource_type(),p_type))
continue;
List<String> local_exts;
@ -112,13 +125,21 @@ void ResourceFormatImporter::get_recognized_extensions_for_type(const String& p_
bool ResourceFormatImporter::recognize_path(const String& p_path,const String& p_for_type) const{
return (p_path.get_extension().to_lower()=="import");
return FileAccess::exists(p_path+".import");
}
bool ResourceFormatImporter::can_be_imported(const String& p_path) const {
return ResourceFormatLoader::recognize_path(p_path);
}
bool ResourceFormatImporter::handles_type(const String& p_type) const {
for (Set< Ref<ResourceImporter> >::Element *E=importers.front();E;E=E->next()) {
if (ClassDB::is_parent_class(p_type,E->get()->get_resource_type()))
print_line("handles "+p_type+" base is "+E->get()->get_resource_type());
if (ClassDB::is_parent_class(E->get()->get_resource_type(),p_type))
return true;
}
@ -152,3 +173,59 @@ void ResourceFormatImporter::get_dependencies(const String& p_path,List<String>
return ResourceLoader::get_dependencies(pat.path,p_dependencies,p_add_types);
}
Ref<ResourceImporter> ResourceFormatImporter::get_importer_by_name(const String& p_name) {
for (Set< Ref<ResourceImporter> >::Element *E=importers.front();E;E=E->next()) {
if (E->get()->get_importer_name()==p_name) {
return E->get();
}
}
return Ref<ResourceImporter>();
}
void ResourceFormatImporter::get_importers_for_extension(const String& p_extension,List<Ref<ResourceImporter> > *r_importers) {
for (Set< Ref<ResourceImporter> >::Element *E=importers.front();E;E=E->next()) {
List<String> local_exts;
E->get()->get_recognized_extensions(&local_exts);
for (List<String>::Element *F=local_exts.front();F;F=F->next()) {
if (p_extension.to_lower()==F->get()) {
r_importers->push_back(E->get());
}
}
}
}
Ref<ResourceImporter> ResourceFormatImporter::get_importer_by_extension(const String& p_extension) {
Ref<ResourceImporter> importer;
float priority=0;
for (Set< Ref<ResourceImporter> >::Element *E=importers.front();E;E=E->next()) {
List<String> local_exts;
E->get()->get_recognized_extensions(&local_exts);
for (List<String>::Element *F=local_exts.front();F;F=F->next()) {
if (p_extension.to_lower()==F->get() && E->get()->get_priority() > priority) {
importer=E->get();
priority=E->get()->get_priority();
}
}
}
return importer;
}
String ResourceFormatImporter::get_import_base_path(const String& p_for_file) const {
return "res://.import/"+p_for_file.get_file()+"-"+p_for_file.md5_text();
}
ResourceFormatImporter *ResourceFormatImporter::singleton=NULL;
ResourceFormatImporter::ResourceFormatImporter() {
singleton=this;
}

View file

@ -15,35 +15,61 @@ class ResourceFormatImporter : public ResourceFormatLoader {
Error _get_path_and_type(const String& p_path,PathAndType & r_path_and_type) const;
static ResourceFormatImporter *singleton;
Set< Ref<ResourceImporter> > importers;
public:
static ResourceFormatImporter *get_singleton() { return singleton; }
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual void get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions) const;
bool recognize_path(const String& p_path,const String& p_for_type=String()) const;
virtual bool handles_type(const String& p_type) const=0;
virtual String get_resource_type(const String &p_path) const=0;
virtual bool recognize_path(const String& p_path,const String& p_for_type=String()) const;
virtual bool handles_type(const String& p_type) const;
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 bool can_be_imported(const String& p_path) const;
void add_importer(const Ref<ResourceImporter>& p_importer) { importers.insert(p_importer); }
Ref<ResourceImporter> get_importer_by_name(const String& p_name);
Ref<ResourceImporter> get_importer_by_extension(const String& p_extension);
void get_importers_for_extension(const String& p_extension,List<Ref<ResourceImporter> > *r_importers);
String get_import_base_path(const String& p_for_file) const;
ResourceFormatImporter();
};
class ResourceImporter {
class ResourceImporter : public Reference {
GDCLASS(ResourceImporter,Reference)
public:
virtual String get_name() const=0;
virtual String get_importer_name() const=0;
virtual String get_visible_name() const=0;
virtual void get_recognized_extensions(List<String> *p_extensions) const=0;
virtual String get_save_extension() const=0;
virtual String get_resource_type() const=0;
virtual float get_priority() const { return 1.0; }
struct ImportOption {
PropertyInfo option;
Variant default_value;
ImportOption(const PropertyInfo& p_info,const Variant& p_default) { option=p_info; default_value=p_default; }
ImportOption() {}
};
virtual void get_import_options(List<ImportOption> *r_options)=0;
virtual RES import(const String& p_path,const Map<StringName,Variant>& p_options)=0;
virtual int get_preset_count() const { return 0; }
virtual String get_preset_name(int p_idx) const { return String(); }
virtual void get_import_options(List<ImportOption> *r_options,int p_preset=0) const=0;
virtual bool get_option_visibility(const String& p_option,const Map<StringName,Variant>& p_options) const=0;
virtual Error import(const String& p_source_file,const String& p_save_path,const Map<StringName,Variant>& p_options,List<String>* r_platform_variants)=0;
};

View file

@ -61,7 +61,7 @@ public:
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
virtual void get_recognized_extensions(List<String> *p_extensions) const=0;
virtual void get_recognized_extensions_for_type(const String& p_type,List<String> *p_extensions) const;
bool recognize_path(const String& p_path,const String& p_for_type=String()) const;
virtual bool recognize_path(const String& p_path,const String& p_for_type=String()) const;
virtual bool handles_type(const String& p_type) const=0;
virtual String get_resource_type(const String &p_path) const=0;
virtual void get_dependencies(const String& p_path,List<String> *p_dependencies,bool p_add_types=false);

View file

@ -103,6 +103,7 @@ enum PropertyUsageFlags {
PROPERTY_USAGE_SCRIPT_VARIABLE=8192,
PROPERTY_USAGE_STORE_IF_NULL=16384,
PROPERTY_USAGE_ANIMATE_AS_TRIGGER=32768,
PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED=65536,
PROPERTY_USAGE_DEFAULT=PROPERTY_USAGE_STORAGE|PROPERTY_USAGE_EDITOR|PROPERTY_USAGE_NETWORK,
PROPERTY_USAGE_DEFAULT_INTL=PROPERTY_USAGE_STORAGE|PROPERTY_USAGE_EDITOR|PROPERTY_USAGE_NETWORK|PROPERTY_USAGE_INTERNATIONALIZED,

View file

@ -39,4 +39,13 @@ struct Pair {
Pair( F p_first, S p_second) { first=p_first; second=p_second; }
};
template<class F,class S>
struct PairSort {
bool operator()(const Pair<F,S>& A, const Pair<F,S>& B) const {
return A.first < B.first;
}
};
#endif // PAIR_H

View file

@ -45,6 +45,7 @@
#include "compressed_translation.h"
#include "io/translation_loader_po.h"
#include "io/resource_format_binary.h"
#include "io/resource_import.h"
#include "io/stream_peer_ssl.h"
#include "os/input.h"
#include "core/io/xml_parser.h"
@ -57,7 +58,7 @@
static ResourceFormatSaverBinary *resource_saver_binary=NULL;
static ResourceFormatLoaderBinary *resource_loader_binary=NULL;
static ResourceFormatImporter *resource_format_importer=NULL;
static _ResourceLoader *_resource_loader=NULL;
static _ResourceSaver *_resource_saver=NULL;
@ -105,6 +106,9 @@ void register_core_types() {
resource_loader_binary = memnew( ResourceFormatLoaderBinary );
ResourceLoader::add_resource_format_loader(resource_loader_binary);
resource_format_importer = memnew( ResourceFormatImporter );
ResourceLoader::add_resource_format_loader(resource_format_importer);
ClassDB::register_class<Object>();
@ -183,7 +187,6 @@ void register_core_singletons() {
GlobalConfig::get_singleton()->add_singleton( GlobalConfig::Singleton("ClassDB",_classdb ) );
GlobalConfig::get_singleton()->add_singleton( GlobalConfig::Singleton("Marshalls",_Marshalls::get_singleton() ) );
GlobalConfig::get_singleton()->add_singleton( GlobalConfig::Singleton("TranslationServer",TranslationServer::get_singleton() ) );
GlobalConfig::get_singleton()->add_singleton( GlobalConfig::Singleton("TS",TranslationServer::get_singleton() ) );
GlobalConfig::get_singleton()->add_singleton( GlobalConfig::Singleton("Input",Input::get_singleton() ) );
GlobalConfig::get_singleton()->add_singleton( GlobalConfig::Singleton("InputMap",InputMap::get_singleton() ) );
@ -207,6 +210,8 @@ void unregister_core_types() {
memdelete(resource_saver_binary);
if (resource_loader_binary)
memdelete(resource_loader_binary);
if (resource_format_importer)
memdelete(resource_format_importer);
memdelete( resource_format_po );

View file

@ -353,6 +353,7 @@ Resource::Resource() {
#ifdef TOOLS_ENABLED
last_modified_time=0;
import_last_modified_time=0;
#endif
subindex=0;

View file

@ -66,6 +66,8 @@ friend class ResourceCache;
#ifdef TOOLS_ENABLED
uint64_t last_modified_time;
uint64_t import_last_modified_time;
String import_path;
#endif
bool local_to_scene;
@ -118,6 +120,12 @@ public:
virtual void set_last_modified_time(uint64_t p_time) { last_modified_time=p_time; }
uint64_t get_last_modified_time() const { return last_modified_time; }
virtual void set_import_last_modified_time(uint64_t p_time) { import_last_modified_time=p_time; }
uint64_t get_import_last_modified_time() const { return import_last_modified_time; }
void set_import_path(const String& p_path) { import_path=p_path; }
String get_import_path() const { return import_path; }
#endif
virtual RID get_rid() const; // some resources may offer conversion to RID

View file

@ -183,8 +183,6 @@ void Main::print_help(const char* p_binary) {
#ifdef TOOLS_ENABLED
OS::get_singleton()->print("\t-doctool FILE: Dump the whole engine api to FILE in XML format. If FILE exists, it will be merged.\n");
OS::get_singleton()->print("\t-nodocbase: Disallow dump the base types (used with -doctool).\n");
OS::get_singleton()->print("\t-optimize FILE Save an optimized copy of scene to FILE.\n");
OS::get_singleton()->print("\t-optimize_preset [preset] Use a given preset for optimization.\n");
OS::get_singleton()->print("\t-export [target] Export the project using given export target.\n");
#endif
}
@ -1074,12 +1072,9 @@ bool Main::start() {
String script;
String test;
String screen;
String optimize;
String optimize_preset;
String _export_platform;
String _import;
String _import_script;
String dumpstrings;
bool noquit=false;
bool export_debug=false;
bool project_manager_request = false;
@ -1108,10 +1103,6 @@ bool Main::start() {
Engine::get_singleton()->_custom_level=args[i+1];
} else if (args[i]=="-test") {
test=args[i+1];
} else if (args[i]=="-optimize") {
optimize=args[i+1];
} else if (args[i]=="-optimize_preset") {
optimize_preset=args[i+1];
} else if (args[i]=="-export") {
editor=true; //needs editor
_export_platform=args[i+1];
@ -1125,9 +1116,6 @@ bool Main::start() {
} else if (args[i]=="-import_script") {
editor=true; //needs editor
_import_script=args[i+1];
} else if (args[i]=="-dumpstrings") {
editor=true; //needs editor
dumpstrings=args[i+1];
} else {
// The parameter does not match anything known, don't skip the next argument
parsed_pair=false;
@ -1162,10 +1150,6 @@ bool Main::start() {
return false;
}
if (optimize!="")
editor=true; //need editor
#endif
@ -1399,22 +1383,7 @@ bool Main::start() {
Error serr = editor_node->load_scene(local_game_path);
if (serr==OK) {
if (optimize!="") {
editor_node->save_optimized_copy(optimize,optimize_preset);
if (!noquit)
sml->quit();
}
if (dumpstrings!="") {
editor_node->save_translatable_strings(dumpstrings);
if (!noquit)
sml->quit();
}
}
}
OS::get_singleton()->set_context(OS::CONTEXT_EDITOR);

View file

@ -27,6 +27,8 @@
/* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
/*************************************************************************/
#include "resource_format_image.h"
#if 0
#include "scene/resources/texture.h"
#include "io/image_loader.h"
#include "globals.h"
@ -260,3 +262,4 @@ ResourceFormatLoaderImage::ResourceFormatLoaderImage() {
GLOBAL_DEF("rendering/image_loader/repeat",false);
}
#endif

View file

@ -29,6 +29,8 @@
#ifndef RESOURCE_FORMAT_IMAGE_H
#define RESOURCE_FORMAT_IMAGE_H
#if 0
#include "io/resource_loader.h"
#include "io/resource_saver.h"
/**
@ -49,3 +51,4 @@ public:
};
#endif
#endif

View file

@ -230,7 +230,6 @@
#include "scene/resources/scene_format_text.h"
static ResourceFormatLoaderImage *resource_loader_image=NULL;
//static ResourceFormatLoaderWAV *resource_loader_wav=NULL;
@ -245,6 +244,8 @@ static ResourceFormatLoaderText *resource_loader_text=NULL;
static ResourceFormatLoaderDynamicFont *resource_loader_dynamic_font=NULL;
static ResourceFormatLoaderStreamTexture *resource_loader_stream_texture=NULL;
//static SceneStringNames *string_names;
void register_scene_types() {
@ -255,14 +256,14 @@ void register_scene_types() {
Node::init_node_hrcr();
resource_loader_image = memnew( ResourceFormatLoaderImage );
ResourceLoader::add_resource_format_loader( resource_loader_image );
//resource_loader_wav = memnew( ResourceFormatLoaderWAV );
//ResourceLoader::add_resource_format_loader( resource_loader_wav );
resource_loader_dynamic_font = memnew( ResourceFormatLoaderDynamicFont );
ResourceLoader::add_resource_format_loader( resource_loader_dynamic_font );
resource_loader_stream_texture = memnew( ResourceFormatLoaderStreamTexture);
ResourceLoader::add_resource_format_loader( resource_loader_stream_texture );
#ifdef TOOLS_ENABLED
//scene first!
@ -570,6 +571,7 @@ void register_scene_types() {
ClassDB::register_virtual_class<Texture>();
ClassDB::register_virtual_class<SkyBox>();
ClassDB::register_class<ImageSkyBox>();
ClassDB::register_class<StreamTexture>();
ClassDB::register_class<ImageTexture>();
ClassDB::register_class<AtlasTexture>();
ClassDB::register_class<LargeTexture>();
@ -643,9 +645,9 @@ void unregister_scene_types() {
clear_default_theme();
memdelete( resource_loader_image );
// memdelete( resource_loader_wav );
memdelete( resource_loader_dynamic_font );
memdelete( resource_loader_stream_texture );
#ifdef TOOLS_ENABLED

View file

@ -453,6 +453,335 @@ ImageTexture::~ImageTexture() {
VisualServer::get_singleton()->free( texture );
}
//////////////////////////////////////////
uint32_t StreamTexture::get_flags() const {
return flags;
}
Image::Format StreamTexture::get_format() const {
return format;
}
Error StreamTexture::_load_data(const String& p_path,int &tw,int &th,int& flags,Image& image,int p_size_limit) {
FileAccess *f = FileAccess::open(p_path,FileAccess::READ);
ERR_FAIL_COND_V(!f,ERR_CANT_OPEN);
uint8_t header[4];
f->get_buffer(header,4);
if (header[0]!='G' || header[1]!='D' || header[2]!='S' || header[3]!='T') {
memdelete(f);
ERR_FAIL_COND_V(header[0]!='G' || header[1]!='D' || header[2]!='S' || header[3]!='T',ERR_FILE_CORRUPT);
}
tw = f->get_32();
th = f->get_32();
flags= f->get_32(); //texture flags!
uint32_t df = f->get_32(); //data format
print_line("width: "+itos(tw));
print_line("height: "+itos(th));
print_line("flags: "+itos(flags));
print_line("df: "+itos(df));
if (!(df&FORMAT_BIT_STREAM)) {
p_size_limit=0;
}
if (df&FORMAT_BIT_LOSSLESS || df&FORMAT_BIT_LOSSY) {
//look for a PNG or WEBP file inside
int sw=tw;
int sh=th;
uint32_t mipmaps = f->get_32();
uint32_t size = f->get_32();
print_line("mipmaps: "+itos(mipmaps));
while(mipmaps>1 && p_size_limit>0 && (sw>p_size_limit || sh>p_size_limit)) {
f->seek(f->get_pos()+size);
mipmaps = f->get_32();
size = f->get_32();
sw=MAX(sw>>1,1);
sh=MAX(sh>>1,1);
mipmaps--;
}
//mipmaps need to be read independently, they will be later combined
Vector<Image> mipmap_images;
int total_size=0;
for(int i=0;i<mipmaps;i++) {
PoolVector<uint8_t> pv;
pv.resize(size);
{
PoolVector<uint8_t>::Write w = pv.write();
f->get_buffer(w.ptr(),size);
}
Image img;
if (df&FORMAT_BIT_LOSSLESS) {
img = Image::lossless_unpacker(pv);
} else {
img = Image::lossy_unpacker(pv);
}
if (img.empty()) {
memdelete(f);
ERR_FAIL_COND_V(img.empty(),ERR_FILE_CORRUPT);
}
total_size+=img.get_data().size();
mipmap_images.push_back(img);
}
print_line("mipmap read total: "+itos(mipmap_images.size()));
memdelete(f); //no longer needed
if (mipmap_images.size()==1) {
image=mipmap_images[0];
return OK;
} else {
PoolVector<uint8_t> img_data;
img_data.resize(total_size);
{
PoolVector<uint8_t>::Write w=img_data.write();
int ofs=0;
for(int i=0;i<mipmap_images.size();i++) {
PoolVector<uint8_t> id = mipmap_images[i].get_data();
int len = id.size();
PoolVector<uint8_t>::Read r = id.read();
copymem(&w[ofs],r.ptr(),len);
ofs+=len;
}
}
image = Image(sw,sh,true,mipmap_images[0].get_format(),img_data);
return OK;
}
} else {
//look for regular format
Image::Format format = (Image::Format)(df&FORMAT_MASK_IMAGE_FORMAT);
bool mipmaps = df&FORMAT_BIT_HAS_MIPMAPS;
if (!mipmaps) {
int size = Image::get_image_data_size(tw,th,format,0);
PoolVector<uint8_t> img_data;
img_data.resize(size);
{
PoolVector<uint8_t>::Write w=img_data.write();
f->get_buffer(w.ptr(),size);
}
memdelete(f);
image = Image(tw,th,false,format,img_data);
return OK;
} else {
int sw=tw;
int sh=th;
int mipmaps = Image::get_image_required_mipmaps(tw,th,format);
int total_size = Image::get_image_data_size(tw,th,format,mipmaps);
int idx=0;
int ofs=0;
while(mipmaps>1 && p_size_limit>0 && (sw>p_size_limit || sh>p_size_limit)) {
sw=MAX(sw>>1,1);
sh=MAX(sh>>1,1);
mipmaps--;
idx++;
}
if (idx>0) {
ofs=Image::get_image_data_size(tw,th,format,idx-1);
}
if (total_size - ofs <=0) {
memdelete(f);
ERR_FAIL_V(ERR_FILE_CORRUPT);
}
f->seek(f->get_pos()+ofs);
PoolVector<uint8_t> img_data;
img_data.resize(total_size - ofs);
{
PoolVector<uint8_t>::Write w=img_data.write();
int bytes = f->get_buffer(w.ptr(),total_size - ofs);
memdelete(f);
if (bytes != total_size - ofs) {
ERR_FAIL_V(ERR_FILE_CORRUPT);
}
}
image = Image(sw,sh,true,format,img_data);
return OK;
}
}
return ERR_BUG; //unreachable
}
Error StreamTexture::load(const String& p_path) {
int lw,lh,lflags;
Image image;
Error err = _load_data(p_path,lw,lh,lflags,image);
if (err)
return err;
VS::get_singleton()->texture_allocate(texture,image.get_width(),image.get_height(),image.get_format(),lflags);
VS::get_singleton()->texture_set_data(texture,image);
w=lw;
h=lh;
flags=lflags;
path_to_file=p_path;
format=image.get_format();
return OK;
}
String StreamTexture::get_load_path() const {
return path_to_file;
}
int StreamTexture::get_width() const {
return w;
}
int StreamTexture::get_height() const {
return h;
}
RID StreamTexture::get_rid() const {
return texture;
}
void StreamTexture::draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate, bool p_transpose) const {
if ((w|h)==0)
return;
VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item,Rect2( p_pos, Size2(w,h)),texture,false,p_modulate,p_transpose);
}
void StreamTexture::draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile,const Color& p_modulate, bool p_transpose) const {
if ((w|h)==0)
return;
VisualServer::get_singleton()->canvas_item_add_texture_rect(p_canvas_item,p_rect,texture,p_tile,p_modulate,p_transpose);
}
void StreamTexture::draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate, bool p_transpose) const{
if ((w|h)==0)
return;
VisualServer::get_singleton()->canvas_item_add_texture_rect_region(p_canvas_item,p_rect,texture,p_src_rect,p_modulate,p_transpose);
}
bool StreamTexture::has_alpha() const {
return false;
}
void StreamTexture::set_flags(uint32_t p_flags){
}
void StreamTexture::reload_from_file() {
load(path_to_file);
}
void StreamTexture::_bind_methods() {
ClassDB::bind_method(_MD("load","path"),&StreamTexture::load);
ClassDB::bind_method(_MD("get_load_path"),&StreamTexture::get_load_path);
ADD_PROPERTY( PropertyInfo(Variant::STRING,"load_path",PROPERTY_HINT_FILE,"*.stex"),_SCS("load"),_SCS("get_load_path"));
}
StreamTexture::StreamTexture() {
format=Image::FORMAT_MAX;
flags=0;
w=0;
h=0;
texture = VS::get_singleton()->texture_create();
}
StreamTexture::~StreamTexture() {
VS::get_singleton()->free(texture);
}
RES ResourceFormatLoaderStreamTexture::load(const String &p_path,const String& p_original_path,Error *r_error) {
Ref<StreamTexture> st;
st.instance();
Error err = st->load(p_path);
if (r_error)
*r_error=err;
if (err!=OK)
return RES();
return st;
}
void ResourceFormatLoaderStreamTexture::get_recognized_extensions(List<String> *p_extensions) const{
p_extensions->push_back("stex");
}
bool ResourceFormatLoaderStreamTexture::handles_type(const String& p_type) const{
return p_type=="StreamTexture";
}
String ResourceFormatLoaderStreamTexture::get_resource_type(const String &p_path) const{
if (p_path.get_extension().to_lower()=="stex")
return "StreamTexture";
return "";
}
//////////////////////////////////////////

View file

@ -31,6 +31,7 @@
#include "resource.h"
#include "servers/visual_server.h"
#include "io/resource_loader.h"
#include "math_2d.h"
/**
@ -160,6 +161,76 @@ public:
};
class StreamTexture : public Texture {
GDCLASS( StreamTexture, Texture );
public:
enum DataFormat {
DATA_FORMAT_IMAGE,
DATA_FORMAT_LOSSLESS,
DATA_FORMAT_LOSSY
};
enum FormatBits {
FORMAT_MASK_IMAGE_FORMAT=(1<<20)-1,
FORMAT_BIT_LOSSLESS=1<<20,
FORMAT_BIT_LOSSY=1<<21,
FORMAT_BIT_STREAM=1<<22,
FORMAT_BIT_HAS_MIPMAPS=1<<23,
};
private:
Error _load_data(const String &p_path, int &tw, int &th, int& flags, Image& image, int p_size_limit=0);
String path_to_file;
RID texture;
Image::Format format;
uint32_t flags;
int w,h;
virtual void reload_from_file();
protected:
static void _bind_methods();
public:
uint32_t get_flags() const;
Image::Format get_format() const;
Error load(const String& p_path);
String get_load_path() const;
int get_width() const;
int get_height() const;
virtual RID get_rid() const;
virtual void draw(RID p_canvas_item, const Point2& p_pos, const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const;
virtual void draw_rect(RID p_canvas_item,const Rect2& p_rect, bool p_tile=false,const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const;
virtual void draw_rect_region(RID p_canvas_item,const Rect2& p_rect, const Rect2& p_src_rect,const Color& p_modulate=Color(1,1,1), bool p_transpose=false) const;
virtual bool has_alpha() const;
virtual void set_flags(uint32_t p_flags);
StreamTexture();
~StreamTexture();
};
class ResourceFormatLoaderStreamTexture : public ResourceFormatLoader {
public:
virtual RES load(const String &p_path,const String& p_original_path="",Error *r_error=NULL);
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual bool handles_type(const String& p_type) const;
virtual String get_resource_type(const String &p_path) const;
};
VARIANT_ENUM_CAST( ImageTexture::Storage );
class AtlasTexture : public Texture {

View file

@ -78,3 +78,4 @@ if (env["tools"] == "yes"):
SConscript('plugins/SCsub')
SConscript('fileserver/SCsub')
SConscript('io_plugins/SCsub')
SConscript('import/SCsub')

View file

@ -34,8 +34,10 @@
#include "os/file_access.h"
#include "editor_node.h"
#include "io/resource_saver.h"
#include "io/resource_import.h"
#include "editor_settings.h"
#include "editor_resource_preview.h"
#include "variant_parser.h"
EditorFileSystem *EditorFileSystem::singleton=NULL;
@ -115,75 +117,13 @@ String EditorFileSystemDirectory::get_file_path(int p_idx) const {
return "res://"+file;
}
bool EditorFileSystemDirectory::get_file_meta(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx,files.size(),"");
return files[p_idx]->meta.enabled;
}
Vector<String> EditorFileSystemDirectory::get_file_deps(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx,files.size(),Vector<String>());
return files[p_idx]->meta.deps;
return files[p_idx]->deps;
}
Vector<String> EditorFileSystemDirectory::get_missing_sources(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx,files.size(),Vector<String>());
Vector<String> missing;
for(int i=0;i<files[p_idx]->meta.sources.size();i++) {
if (files[p_idx]->meta.sources[i].missing)
missing.push_back(files[p_idx]->meta.sources[i].path);
}
return missing;
}
bool EditorFileSystemDirectory::is_missing_sources(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx,files.size(),false);
for(int i=0;i<files[p_idx]->meta.sources.size();i++) {
if (files[p_idx]->meta.sources[i].missing)
return true;
}
return false;
}
bool EditorFileSystemDirectory::have_sources_changed(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx,files.size(),false);
return files[p_idx]->meta.sources_changed;
}
int EditorFileSystemDirectory::get_source_count(int p_idx) const {
ERR_FAIL_INDEX_V(p_idx,files.size(),0);
if (!files[p_idx]->meta.enabled)
return 0;
return files[p_idx]->meta.sources.size();
}
String EditorFileSystemDirectory::get_source_file(int p_idx,int p_source) const {
ERR_FAIL_INDEX_V(p_idx,files.size(),String());
ERR_FAIL_INDEX_V(p_source,files[p_idx]->meta.sources.size(),String());
if (!files[p_idx]->meta.enabled)
return String();
return files[p_idx]->meta.sources[p_source].path;
}
bool EditorFileSystemDirectory::is_source_file_missing(int p_idx,int p_source) const {
ERR_FAIL_INDEX_V(p_idx,files.size(),false);
ERR_FAIL_INDEX_V(p_source,files[p_idx]->meta.sources.size(),false);
if (!files[p_idx]->meta.enabled)
return false;
return files[p_idx]->meta.sources[p_source].missing;
}
StringName EditorFileSystemDirectory::get_file_type(int p_idx) const {
@ -210,7 +150,6 @@ void EditorFileSystemDirectory::_bind_methods() {
ClassDB::bind_method(_MD("get_file","idx"),&EditorFileSystemDirectory::get_file);
ClassDB::bind_method(_MD("get_file_path","idx"),&EditorFileSystemDirectory::get_file_path);
ClassDB::bind_method(_MD("get_file_type","idx"),&EditorFileSystemDirectory::get_file_type);
ClassDB::bind_method(_MD("is_missing_sources","idx"),&EditorFileSystemDirectory::is_missing_sources);
ClassDB::bind_method(_MD("get_name"),&EditorFileSystemDirectory::get_name);
ClassDB::bind_method(_MD("get_path"),&EditorFileSystemDirectory::get_path);
ClassDB::bind_method(_MD("get_parent:EditorFileSystemDirectory"),&EditorFileSystemDirectory::get_parent);
@ -244,42 +183,6 @@ EditorFileSystemDirectory::~EditorFileSystemDirectory() {
EditorFileSystemDirectory::ImportMeta EditorFileSystem::_get_meta(const String& p_path) {
return EditorFileSystemDirectory::ImportMeta();
#if 0
Ref<ResourceImportMetadata> imd = ResourceLoader::load_import_metadata(p_path);
EditorFileSystemDirectory::ImportMeta m;
if (imd.is_null()) {
m.enabled=false;
m.sources_changed=false;
} else {
m.enabled=true;
m.sources_changed=false;
for(int i=0;i<imd->get_source_count();i++) {
EditorFileSystemDirectory::ImportMeta::Source s;
s.path=imd->get_source_path(i);
s.md5=imd->get_source_md5(i);
s.modified_time=0;
s.missing=false;
m.sources.push_back(s);
}
m.import_editor=imd->get_editor();
}
List<String> deps;
ResourceLoader::get_dependencies(p_path,&deps);
for(List<String>::Element *E=deps.front();E;E=E->next()) {
m.deps.push_back(E->get());
}
return m;
#endif
}
void EditorFileSystem::_scan_filesystem() {
ERR_FAIL_COND(!scanning || new_filesystem);
@ -292,7 +195,7 @@ void EditorFileSystem::_scan_filesystem() {
String project=GlobalConfig::get_singleton()->get_resource_path();
String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_cache");
String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_cache2");
FileAccess *f =FileAccess::open(fscache,FileAccess::READ);
if (f) {
@ -322,30 +225,14 @@ void EditorFileSystem::_scan_filesystem() {
FileCache fc;
fc.type=split[1];
fc.modification_time=split[2].to_int64();
String meta = split[3].strip_edges();
fc.meta.enabled=false;
if (meta.find("<>")!=-1){
Vector<String> spl = meta.split("<>");
int sc = spl.size()-1;
if (sc%3==0){
fc.meta.enabled=true;
fc.meta.import_editor=spl[0];
fc.meta.sources.resize(sc/3);
for(int i=0;i<fc.meta.sources.size();i++) {
fc.meta.sources[i].path=spl[1+i*3+0];
fc.meta.sources[i].md5=spl[1+i*3+1];
fc.meta.sources[i].modified_time=spl[1+i*3+2].to_int64();
}
fc.import_modification_time = split[3].to_int64();
}
}
String deps = split[4].strip_edges();
if (deps.length()) {
Vector<String> dp = deps.split("<>");
for(int i=0;i<dp.size();i++) {
String path=dp[i];
fc.meta.deps.push_back(path);
fc.deps.push_back(path);
}
}
@ -393,7 +280,14 @@ void EditorFileSystem::_scan_filesystem() {
}
void EditorFileSystem::_save_filesystem_cache() {
String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_cache2");
FileAccess *f=FileAccess::open(fscache,FileAccess::WRITE);
_save_filesystem_cache(filesystem,f);
f->close();
memdelete(f);
}
void EditorFileSystem::_thread_func(void *_userdata) {
@ -408,6 +302,8 @@ bool EditorFileSystem::_update_scan_actions() {
bool fs_changed=false;
Vector<String> reimports;
for (List<ItemAction>::Element *E=scan_actions.front();E;E=E->next()) {
ItemAction&ia = E->get();
@ -472,18 +368,25 @@ bool EditorFileSystem::_update_scan_actions() {
//print_line("*ACTION REMOVE FILE: "+ia.file);
} break;
case ItemAction::ACTION_FILE_SOURCES_CHANGED: {
case ItemAction::ACTION_FILE_REIMPORT: {
int idx = ia.dir->find_file_index(ia.file);
ERR_CONTINUE(idx==-1);
String full_path = ia.dir->get_file_path(idx);
sources_changed.push_back(full_path);
reimports.push_back(full_path);
fs_changed=true;
} break;
}
}
if (reimports.size()) {
reimport_files(reimports);
}
scan_actions.clear();
return fs_changed;
@ -495,9 +398,10 @@ void EditorFileSystem::scan() {
if (false /*&& bool(Globals::get_singleton()->get("debug/disable_scan"))*/)
return;
if (scanning || scanning_sources|| thread)
if (scanning || scanning_changes|| thread)
return;
_update_extensions();
abort_scan=false;
if (!use_threads) {
@ -532,43 +436,6 @@ void EditorFileSystem::scan() {
}
bool EditorFileSystem::_check_meta_sources(EditorFileSystemDirectory::ImportMeta & p_meta) {
if (p_meta.enabled) {
for(int j=0;j<p_meta.sources.size();j++) {
#if 0
String src = EditorImportPlugin::expand_source_path(p_meta.sources[j].path);
if (!FileAccess::exists(src)) {
p_meta.sources[j].missing=true;
continue;
}
p_meta.sources[j].missing=false;
uint64_t mt = FileAccess::get_modified_time(src);
if (mt!=p_meta.sources[j].modified_time) {
//scan
String md5 = FileAccess::get_md5(src);
//print_line("checking: "+src);
//print_line("md5: "+md5);
//print_line("vs: "+p_meta.sources[j].md5);
if (md5!=p_meta.sources[j].md5) {
//really changed
return true;
}
p_meta.sources[j].modified_time=mt;
}
#endif
}
}
return false;
}
void EditorFileSystem::ScanProgress::update(int p_current,int p_total) const {
float ratio = low + ((hi-low)/p_total)*p_current;
@ -586,8 +453,6 @@ EditorFileSystem::ScanProgress EditorFileSystem::ScanProgress::get_sub(int p_cur
}
void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir,DirAccess *da,const ScanProgress& p_progress) {
List<String> dirs;
@ -675,9 +540,11 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir,DirAccess
for (List<String>::Element*E=files.front();E;E=E->next(),idx++) {
String ext = E->get().get_extension().to_lower();
if (!valid_extensions.has(ext))
if (!valid_extensions.has(ext)) {
continue; //invalid
}
EditorFileSystemDirectory::FileInfo *fi = memnew( EditorFileSystemDirectory::FileInfo );
fi->file=E->get();
@ -687,32 +554,45 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir,DirAccess
FileCache *fc = file_cache.getptr(path);
uint64_t mt = FileAccess::get_modified_time(path);
if (fc && fc->modification_time == mt) {
if (import_extensions.has(ext)) {
fi->meta=fc->meta;
fi->type=fc->type;
fi->modified_time=fc->modification_time;
} else {
fi->meta=_get_meta(path);
fi->type=ResourceLoader::get_resource_type(path);
fi->modified_time=mt;
//is imported
uint64_t import_mt=0;
if (FileAccess::exists(path+".import")) {
import_mt=FileAccess::get_modified_time(path+".import");
}
}
if (fc && fc->modification_time==mt && fc->import_modification_time==import_mt) {
fi->type=fc->type;
fi->modified_time=fc->modification_time;
fi->import_modified_time=fc->import_modification_time;
} else {
print_line("REIMPORT BECAUSE: time changed");
fi->type=ResourceFormatImporter::get_singleton()->get_resource_type(path);
fi->modified_time=0;
fi->import_modified_time=0;
if (fi->meta.enabled) {
if (_check_meta_sources(fi->meta)) {
ItemAction ia;
ia.action=ItemAction::ACTION_FILE_SOURCES_CHANGED;
ia.action=ItemAction::ACTION_FILE_REIMPORT;
ia.dir=p_dir;
ia.file=E->get();
scan_actions.push_back(ia);
fi->meta.sources_changed=true;
} else {
fi->meta.sources_changed=false;
}
} else {
fi->meta.sources_changed=true;
//not imported, so just update type if changed
if (fc && fc->modification_time == mt) {
fi->type=fc->type;
fi->modified_time=fc->modification_time;
fi->import_modified_time=0;
} else {
fi->type=ResourceLoader::get_resource_type(path);
fi->modified_time=mt;
fi->import_modified_time=0;
}
}
p_dir->files.push_back(fi);
@ -722,11 +602,13 @@ void EditorFileSystem::_scan_new_dir(EditorFileSystemDirectory *p_dir,DirAccess
}
void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir,const ScanProgress& p_progress) {
uint64_t current_mtime = FileAccess::get_modified_time(p_dir->get_path());
bool updated_dir=false;
String cd = p_dir->get_path();
//print_line("dir: "+p_dir->get_path()+" MODTIME: "+itos(p_dir->modified_time)+" CTIME: "+itos(current_mtime));
@ -751,7 +633,7 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir,const S
//then scan files and directories and check what's different
DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
String cd = p_dir->get_path();
da->change_dir(cd);
da->list_dir_begin();
while (true) {
@ -807,7 +689,7 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir,const S
String path = cd.plus_file(fi->file);
fi->modified_time=FileAccess::get_modified_time(path);
fi->meta=_get_meta(path);
fi->import_modified_time=0;
fi->type=ResourceLoader::get_resource_type(path);
{
@ -817,19 +699,18 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir,const S
ia.file=f;
ia.new_file=fi;
scan_actions.push_back(ia);
}
//take the chance and scan sources
if (_check_meta_sources(fi->meta)) {
if (import_extensions.has(ext)) {
//if it can be imported, and it was added, it needs to be reimported
print_line("REIMPORT: file was not found before, reimport");
ItemAction ia;
ia.action=ItemAction::ACTION_FILE_SOURCES_CHANGED;
ia.action=ItemAction::ACTION_FILE_REIMPORT;
ia.dir=p_dir;
ia.file=f;
scan_actions.push_back(ia);
fi->meta.sources_changed=true;
} else {
fi->meta.sources_changed=false;
}
} else {
@ -859,15 +740,39 @@ void EditorFileSystem::_scan_fs_changes(EditorFileSystemDirectory *p_dir,const S
}
if (_check_meta_sources(p_dir->files[i]->meta)) {
ItemAction ia;
ia.action=ItemAction::ACTION_FILE_SOURCES_CHANGED;
ia.dir=p_dir;
ia.file=p_dir->files[i]->file;
scan_actions.push_back(ia);
p_dir->files[i]->meta.sources_changed=true;
} else {
p_dir->files[i]->meta.sources_changed=false;
if (import_extensions.has(p_dir->files[i]->file.get_extension().to_lower())) {
//check here if file must be imported or not
String path = cd.plus_file(p_dir->files[i]->file);
uint64_t mt = FileAccess::get_modified_time(path);
bool reimport=false;
if (mt!=p_dir->files[i]->modified_time) {
print_line("REIMPORT: modified time changed, reimport");
reimport=true; //it was modified, must be reimported.
} else if (!FileAccess::exists(path+".import")) {
print_line("REIMPORT: no .import exists, reimport");
reimport=true; //no .import file, obviously reimport
} else {
uint64_t import_mt=FileAccess::get_modified_time(path+".import");
if (import_mt!=p_dir->files[i]->import_modified_time) {
print_line("REIMPORT: import modified changed, reimport");
reimport=true;
}
}
if (reimport) {
ItemAction ia;
ia.action=ItemAction::ACTION_FILE_REIMPORT;
ia.dir=p_dir;
ia.file=p_dir->files[i]->file;
scan_actions.push_back(ia);
}
}
EditorResourcePreview::get_singleton()->check_for_invalidation(p_dir->get_file_path(i));
@ -900,7 +805,7 @@ void EditorFileSystem::_thread_func_sources(void *_userdata) {
sp.low=0;
efs->_scan_fs_changes(efs->filesystem,sp);
}
efs->scanning_sources_done=true;
efs->scanning_changes_done=true;
}
void EditorFileSystem::get_changed_sources(List<String> *r_changed) {
@ -908,14 +813,15 @@ void EditorFileSystem::get_changed_sources(List<String> *r_changed) {
*r_changed=sources_changed;
}
void EditorFileSystem::scan_sources() {
void EditorFileSystem::scan_changes() {
if (scanning || scanning_sources|| thread)
if (scanning || scanning_changes|| thread)
return;
_update_extensions();
sources_changed.clear();
scanning_sources=true;
scanning_sources_done=false;
scanning_changes=true;
scanning_changes_done=false;
abort_scan=false;
@ -931,8 +837,8 @@ void EditorFileSystem::scan_sources() {
if (_update_scan_actions())
emit_signal("filesystem_changed");
}
scanning_sources=false;
scanning_sources_done=true;
scanning_changes=false;
scanning_changes_done=true;
emit_signal("sources_changed",sources_changed.size()>0);
} else {
@ -987,11 +893,11 @@ void EditorFileSystem::_notification(int p_what) {
if (use_threads) {
if (scanning_sources) {
if (scanning_changes) {
if (scanning_sources_done) {
if (scanning_changes_done) {
scanning_sources=false;
scanning_changes=false;
set_process(false);
@ -1053,22 +959,13 @@ void EditorFileSystem::_save_filesystem_cache(EditorFileSystemDirectory*p_dir,Fi
for(int i=0;i<p_dir->files.size();i++) {
String s=p_dir->files[i]->file+"::"+p_dir->files[i]->type+"::"+String::num(p_dir->files[i]->modified_time)+"::";
if (p_dir->files[i]->meta.enabled) {
s+=p_dir->files[i]->meta.import_editor;
for(int j=0;j<p_dir->files[i]->meta.sources.size();j++){
s+="<>"+p_dir->files[i]->meta.sources[j].path;
s+="<>"+p_dir->files[i]->meta.sources[j].md5;
s+="<>"+String::num(p_dir->files[i]->meta.sources[j].modified_time);
}
}
String s=p_dir->files[i]->file+"::"+p_dir->files[i]->type+"::"+itos(p_dir->files[i]->modified_time)+"::"+itos(p_dir->files[i]->import_modified_time);
s+="::";
for(int j=0;j<p_dir->files[i]->meta.deps.size();j++) {
for(int j=0;j<p_dir->files[i]->deps.size();j++) {
if (j>0)
s+="<>";
s+=p_dir->files[i]->meta.deps[j];
s+=p_dir->files[i]->deps[j];
}
p_file->store_line(s);
@ -1261,34 +1158,8 @@ void EditorFileSystem::_resource_saved(const String& p_path){
}
String EditorFileSystem::_find_first_from_source(EditorFileSystemDirectory* p_dir,const String &p_src) const {
for(int i=0;i<p_dir->files.size();i++) {
for(int j=0;j<p_dir->files[i]->meta.sources.size();j++) {
if (p_dir->files[i]->meta.sources[j].path==p_src)
return p_dir->get_file_path(i);
}
}
for(int i=0;i<p_dir->subdirs.size();i++) {
String ret = _find_first_from_source(p_dir->subdirs[i],p_src);
if (ret.length()>0)
return ret;
}
return String();
}
String EditorFileSystem::find_resource_from_source(const String& p_path) const {
if (filesystem)
return _find_first_from_source(filesystem,p_path);
return String();
}
void EditorFileSystem::update_file(const String& p_file) {
@ -1339,7 +1210,7 @@ void EditorFileSystem::update_file(const String& p_file) {
//print_line("UPDATING: "+p_file);
fs->files[cpos]->type=type;
fs->files[cpos]->modified_time=FileAccess::get_modified_time(p_file);
fs->files[cpos]->meta=_get_meta(p_file);
fs->files[cpos]->import_modified_time=0;
EditorResourcePreview::get_singleton()->call_deferred("check_for_invalidation",p_file);
call_deferred("emit_signal","filesystem_changed"); //update later
@ -1347,6 +1218,128 @@ void EditorFileSystem::update_file(const String& p_file) {
}
void EditorFileSystem::_reimport_file(const String& p_file) {
print_line("REIMPORTING: "+p_file);
EditorFileSystemDirectory *fs=NULL;
int cpos=-1;
bool found = _find_file(p_file,&fs,cpos);
ERR_FAIL_COND(!found);
//try to obtain existing params
Map<StringName,Variant> params;
String importer_name;
if (FileAccess::exists(p_file+".import")) {
Ref<ConfigFile> cf;
cf.instance();
Error err = cf->load(p_file+".import");
if (err==OK) {
List<String> sk;
cf->get_section_keys("params",&sk);
for(List<String>::Element *E=sk.front();E;E=E->next()) {
params[E->get()]=cf->get_value("params",E->get());
}
importer_name = cf->get_value("remap","importer");
}
}
Ref<ResourceImporter> importer;
//find the importer
if (importer_name!="") {
importer = ResourceFormatImporter::get_singleton()->get_importer_by_name(importer_name);
}
if (importer.is_null()) {
//not found by name, find by extension
importer = ResourceFormatImporter::get_singleton()->get_importer_by_extension(p_file.get_extension());
if (importer.is_null()) {
ERR_PRINT("BUG: File queued for import, but can't be imported!");
ERR_FAIL();
}
}
//mix with default params, in case a parameter is missing
List<ResourceImporter::ImportOption> opts;
importer->get_import_options(&opts);
for (List<ResourceImporter::ImportOption>::Element *E=opts.front();E;E=E->next()) {
if (!params.has(E->get().option.name)) { //this one is not present
params[E->get().option.name]=E->get().default_value;
}
}
//finally, perform import!!
String base_path = ResourceFormatImporter::get_singleton()->get_import_base_path(p_file);
List<String> import_variants;
Error err = importer->import(p_file,base_path,params,&import_variants);
ERR_EXPLAIN("Error importing: "+p_file);
ERR_FAIL_COND(err!=OK);
//as import is complete, save the .import file
FileAccess *f = FileAccess::open(p_file+".import",FileAccess::WRITE);
ERR_FAIL_COND(!f);
//write manually, as order matters ([remap] has to go first for performance).
f->store_line("[remap]");
f->store_line("");
f->store_line("importer=\""+importer->get_importer_name()+"\"");
f->store_line("type=\""+importer->get_resource_type()+"\"");
if (import_variants.size()) {
//import with variants
for(List<String>::Element *E=import_variants.front();E;E=E->next()) {
f->store_line("path."+E->get()+"=\""+base_path.c_escape()+"."+E->get()+"."+importer->get_save_extension()+"\"");
}
} else {
f->store_line("path=\""+base_path+"."+importer->get_save_extension()+"\"");
}
f->store_line("");
f->store_line("[params]");
f->store_line("");
//store options in provided order, to avoid file changing
for (List<ResourceImporter::ImportOption>::Element *E=opts.front();E;E=E->next()) {
String base = E->get().option.name;
String value;
VariantWriter::write_to_string(params[base],value);
f->store_line(base+"="+value);
}
memdelete(f);
//update modified times, to avoid reimport
fs->files[cpos]->modified_time = FileAccess::get_modified_time(p_file);
fs->files[cpos]->import_modified_time = FileAccess::get_modified_time(p_file+".import");
}
void EditorFileSystem::reimport_files(const Vector<String>& p_files) {
EditorProgress pr("reimport",TTR("(Re)Importing Assets"),p_files.size());
for(int i=0;i<p_files.size();i++) {
pr.step(p_files[i].get_file(),i);
_reimport_file(p_files[i]);
}
_save_filesystem_cache();
}
void EditorFileSystem::_bind_methods() {
@ -1355,7 +1348,7 @@ void EditorFileSystem::_bind_methods() {
ClassDB::bind_method(_MD("is_scanning"),&EditorFileSystem::is_scanning);
ClassDB::bind_method(_MD("get_scanning_progress"),&EditorFileSystem::get_scanning_progress);
ClassDB::bind_method(_MD("scan"),&EditorFileSystem::scan);
ClassDB::bind_method(_MD("scan_sources"),&EditorFileSystem::scan_sources);
ClassDB::bind_method(_MD("scan_sources"),&EditorFileSystem::scan_changes);
ClassDB::bind_method(_MD("update_file","path"),&EditorFileSystem::update_file);
ClassDB::bind_method(_MD("get_filesystem_path:EditorFileSystemDirectory","path"),&EditorFileSystem::get_filesystem_path);
ClassDB::bind_method(_MD("get_file_type","path"),&EditorFileSystem::get_file_type);
@ -1365,7 +1358,25 @@ void EditorFileSystem::_bind_methods() {
}
void EditorFileSystem::_update_extensions() {
valid_extensions.clear();
import_extensions.clear();
List<String> extensionsl;
ResourceLoader::get_recognized_extensions_for_type("",&extensionsl);
for(List<String>::Element *E = extensionsl.front();E;E=E->next()) {
valid_extensions.insert(E->get());
}
extensionsl.clear();
ResourceFormatImporter::get_singleton()->get_recognized_extensions(&extensionsl);
for(List<String>::Element *E = extensionsl.front();E;E=E->next()) {
import_extensions.insert(E->get());
}
}
EditorFileSystem::EditorFileSystem() {
@ -1379,16 +1390,14 @@ EditorFileSystem::EditorFileSystem() {
thread_sources=NULL;
new_filesystem=NULL;
scanning_sources=false;
scanning_changes=false;
ResourceSaver::set_save_callback(_resource_saved);
List<String> extensionsl;
ResourceLoader::get_recognized_extensions_for_type("",&extensionsl);
for(List<String>::Element *E = extensionsl.front();E;E=E->next()) {
valid_extensions.insert(E->get());
DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES);
if (da->change_dir("res://.import")!=OK) {
da->make_dir("res://.import");
}
memdelete(da);
scan_total=0;
}

View file

@ -48,30 +48,13 @@ class EditorFileSystemDirectory : public Object {
EditorFileSystemDirectory *parent;
Vector<EditorFileSystemDirectory*> subdirs;
struct ImportMeta {
struct Source {
String path;
String md5;
uint64_t modified_time;
bool missing;
};
Vector<Source> sources;
String import_editor;
Vector<String> deps;
bool enabled;
bool sources_changed;
};
struct FileInfo {
String file;
StringName type;
uint64_t modified_time;
ImportMeta meta;
uint64_t import_modified_time;
Vector<String> deps;
bool verified; //used for checking changes
};
@ -101,14 +84,7 @@ public:
String get_file(int p_idx) const;
String get_file_path(int p_idx) const;
StringName get_file_type(int p_idx) const;
bool get_file_meta(int p_idx) const;
bool is_missing_sources(int p_idx) const;
bool have_sources_changed(int p_idx) const;
Vector<String> get_missing_sources(int p_idx) const;
Vector<String> get_file_deps(int p_idx) const;
int get_source_count(int p_idx) const;
String get_source_file(int p_idx,int p_source) const;
bool is_source_file_missing(int p_idx,int p_source) const;
EditorFileSystemDirectory *get_parent();
@ -136,7 +112,7 @@ class EditorFileSystem : public Node {
ACTION_DIR_REMOVE,
ACTION_FILE_ADD,
ACTION_FILE_REMOVE,
ACTION_FILE_SOURCES_CHANGED
ACTION_FILE_REIMPORT
};
Action action;
@ -171,7 +147,7 @@ class EditorFileSystem : public Node {
String type;
uint64_t modification_time;
EditorFileSystemDirectory::ImportMeta meta;
uint64_t import_modification_time;
Vector<String> deps;
};
@ -186,25 +162,25 @@ class EditorFileSystem : public Node {
ScanProgress get_sub(int p_current,int p_total) const;
};
static EditorFileSystemDirectory::ImportMeta _get_meta(const String& p_path);
bool _check_meta_sources(EditorFileSystemDirectory::ImportMeta & p_meta);
void _save_filesystem_cache();
void _save_filesystem_cache(EditorFileSystemDirectory *p_dir,FileAccess *p_file);
bool _find_file(const String& p_file,EditorFileSystemDirectory ** r_d, int &r_file_pos) const;
void _scan_fs_changes(EditorFileSystemDirectory *p_dir, const ScanProgress &p_progress);
int md_count;
Set<String> valid_extensions;
Set<String> import_extensions;
void _scan_new_dir(EditorFileSystemDirectory *p_dir,DirAccess *da,const ScanProgress& p_progress);
Thread *thread_sources;
bool scanning_sources;
bool scanning_sources_done;
bool scanning_changes;
bool scanning_changes_done;
static void _thread_func_sources(void *_userdata);
@ -214,7 +190,10 @@ class EditorFileSystem : public Node {
bool _update_scan_actions();
static void _resource_saved(const String& p_path);
String _find_first_from_source(EditorFileSystemDirectory* p_dir,const String &p_src) const;
void _update_extensions();
void _reimport_file(const String &p_file);
protected:
@ -229,14 +208,16 @@ public:
bool is_scanning() const;
float get_scanning_progress() const;
void scan();
void scan_sources();
void scan_changes();
void get_changed_sources(List<String> *r_changed);
void update_file(const String& p_file);
String find_resource_from_source(const String& p_path) const;
EditorFileSystemDirectory *get_filesystem_path(const String& p_path);
String get_file_type(const String& p_file) const;
EditorFileSystemDirectory* find_file(const String& p_file,int* r_index) const;
void reimport_files(const Vector<String>& p_files);
EditorFileSystem();
~EditorFileSystem();
};

View file

@ -99,7 +99,7 @@
#include "plugins/color_ramp_editor_plugin.h"
#include "plugins/collision_shape_2d_editor_plugin.h"
#include "plugins/gi_probe_editor_plugin.h"
#include "import/resource_import_texture.h"
// end
#include "editor_settings.h"
#include "io_plugins/editor_texture_import_plugin.h"
@ -333,21 +333,6 @@ void EditorNode::_notification(int p_what) {
_editor_select(EDITOR_3D);
if (defer_load_scene!="") {
load_scene(defer_load_scene);
defer_load_scene="";
}
if (defer_translatable!="") {
Error ok = save_translatable_strings(defer_translatable);
if (ok!=OK)
OS::get_singleton()->set_exit_code(255);
defer_translatable="";
get_tree()->quit();
}
/*
if (defer_optimize!="") {
Error ok = save_optimized_copy(defer_optimize,defer_optimize_preset);
@ -370,40 +355,7 @@ void EditorNode::_notification(int p_what) {
if (p_what == MainLoop::NOTIFICATION_WM_FOCUS_IN) {
/*
List<Ref<Resource> > cached;
ResourceCache::get_cached_resources(&cached);
bool changes=false;
for(List<Ref<Resource> >::Element *E=cached.front();E;E=E->next()) {
if (!E->get()->can_reload_from_file())
continue;
if (E->get()->get_path().find("::")!=-1)
continue;
uint64_t mt = FileAccess::get_modified_time(E->get()->get_path());
if (mt!=E->get()->get_last_modified_time()) {
changes=true;
break;
}
}
sources_button->get_popup()->set_item_disabled(sources_button->get_popup()->get_item_index(DEPENDENCY_UPDATE_LOCAL),!changes);
if (changes && sources_button->get_popup()->is_item_disabled(sources_button->get_popup()->get_item_index(DEPENDENCY_UPDATE_IMPORTED))) {
sources_button->set_icon(gui_base->get_icon("DependencyLocalChanged","EditorIcons"));
}
*/
if (bool(EDITOR_DEF("filesystem/resources/auto_reload_modified_images",true))) {
_menu_option_confirm(DEPENDENCY_LOAD_CHANGED_IMAGES,true);
}
waiting_for_sources_changed=true;
EditorFileSystem::get_singleton()->scan_sources();
EditorFileSystem::get_singleton()->scan_changes();
}
if (p_what == MainLoop::NOTIFICATION_WM_QUIT_REQUEST) {
@ -435,60 +387,70 @@ void EditorNode::_fs_changed() {
export_defer.platform="";
}
{
//reload changed resources
List<Ref<Resource> > changed;
List<Ref<Resource> > cached;
ResourceCache::get_cached_resources(&cached);
//this should probably be done in a thread..
for(List<Ref<Resource> >::Element *E=cached.front();E;E=E->next()) {
if (!E->get()->editor_can_reload_from_file())
continue;
if (!E->get()->get_path().is_resource_file() && !E->get()->get_path().is_abs_path())
continue;
if (!FileAccess::exists(E->get()->get_path()))
continue;
if (E->get()->get_import_path()!=String()) {
//imported resource
uint64_t mt = FileAccess::get_modified_time(E->get()->get_import_path());
if (mt!=E->get()->get_import_last_modified_time()) {
changed.push_back(E->get());
}
} else {
uint64_t mt = FileAccess::get_modified_time(E->get()->get_path());
if (mt!=E->get()->get_last_modified_time()) {
changed.push_back(E->get());
}
}
}
if (changed.size()) {
EditorProgress ep("reload_res","Reload Modified Resources",changed.size());
int idx=0;
for(List<Ref<Resource> >::Element *E=changed.front();E;E=E->next()) {
ep.step(E->get()->get_path(),idx++);
E->get()->reload_from_file();
}
}
}
}
void EditorNode::_sources_changed(bool p_exist) {
if (p_exist && bool(EditorSettings::get_singleton()->get("filesystem/import/automatic_reimport_on_sources_changed"))) {
p_exist=false;
if (waiting_for_first_scan) {
List<String> changed_sources;
EditorFileSystem::get_singleton()->get_changed_sources(&changed_sources);
EditorProgress ep("reimport",TTR("Re-Importing"),changed_sources.size());
int step_idx=0;
#if 0
for(List<String>::Element *E=changed_sources.front();E;E=E->next()) {
ep.step(TTR("Importing:")+" "+E->get(),step_idx++);
Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(E->get());
ERR_CONTINUE(rimd.is_null());
String editor = rimd->get_editor();
if (editor.begins_with("texture_")) {
editor="texture"; //compatibility fix for old versions
}
Ref<EditorImportPlugin> eip = EditorImportExport::get_singleton()->get_import_plugin_by_name(editor);
ERR_CONTINUE(eip.is_null());
Error err = eip->import(E->get(),rimd);
if (err!=OK) {
EditorNode::add_io_error("Error Re Importing:\n "+E->get());
}
if (defer_load_scene!="") {
print_line("loading scene DEFERED");
load_scene(defer_load_scene);
defer_load_scene="";
}
#endif
EditorFileSystem::get_singleton()->scan_sources();
waiting_for_sources_changed=false;
return;
waiting_for_first_scan=false;
}
if (p_exist) {
sources_button->set_icon(gui_base->get_icon("DependencyChanged","EditorIcons"));
sources_button->set_disabled(false);
} else {
sources_button->set_icon(gui_base->get_icon("DependencyOk","EditorIcons"));
sources_button->set_disabled(true);
}
waiting_for_sources_changed=false;
}
void EditorNode::_vp_resized() {
@ -1206,12 +1168,6 @@ void EditorNode::_dialog_action(String p_file) {
get_undo_redo()->clear_history();
} break;
case FILE_DUMP_STRINGS: {
save_translatable_strings(p_file);
} break;
case FILE_SAVE_SCENE:
case FILE_SAVE_AS_SCENE: {
@ -2203,46 +2159,6 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
_menu_option_confirm(FILE_SAVE_AND_RUN, true);
} break;
case FILE_DUMP_STRINGS: {
Node *scene = editor_data.get_edited_scene_root();
if (!scene) {
current_option=-1;
//confirmation->get_cancel()->hide();
accept->get_ok()->set_text(TTR("I see.."));
accept->set_text("This operation can't be done without a tree root.");
accept->popup_centered_minsize();
break;
}
String cpath;
if (scene->get_filename()!="") {
cpath = scene->get_filename();
String fn = cpath.substr(0,cpath.length() - cpath.get_extension().size());
String ext=cpath.get_extension();
cpath=fn+".pot";
} else {
current_option=-1;
//confirmation->get_cancel()->hide();
accept->get_ok()->set_text(TTR("I see.."));
accept->set_text(TTR("Please save the scene first."));
accept->popup_centered_minsize();
break;
}
file->set_mode(EditorFileDialog::MODE_SAVE_FILE);
file->set_current_path(cpath);
file->set_title(TTR("Save Translatable Strings"));
file->popup_centered_ratio();
} break;
case FILE_SAVE_OPTIMIZED: {
#if 0
Node *scene = editor_data.get_edited_scene_root();
@ -2867,24 +2783,6 @@ void EditorNode::_menu_option_confirm(int p_option,bool p_confirmed) {
case DEPENDENCY_LOAD_CHANGED_IMAGES: {
List<Ref<Resource> > cached;
ResourceCache::get_cached_resources(&cached);
//this should probably be done in a thread..
for(List<Ref<Resource> >::Element *E=cached.front();E;E=E->next()) {
if (!E->get()->editor_can_reload_from_file())
continue;
if (!E->get()->get_path().is_resource_file() && !E->get()->get_path().is_abs_path())
continue;
if (!FileAccess::exists(E->get()->get_path()))
continue;
uint64_t mt = FileAccess::get_modified_time(E->get()->get_path());
if (mt!=E->get()->get_last_modified_time()) {
E->get()->reload_from_file();
}
}
} break;
case DEPENDENCY_UPDATE_IMPORTED: {
@ -3211,232 +3109,6 @@ void EditorNode::set_edited_scene(Node *p_scene) {
}
void EditorNode::_fetch_translatable_strings(const Object *p_object,Set<StringName>& strings) {
List<String> tstrings;
p_object->get_translatable_strings(&tstrings);
for(List<String>::Element *E=tstrings.front();E;E=E->next())
strings.insert(E->get());
const Node * node = p_object->cast_to<Node>();
if (!node)
return;
Ref<Script> script = node->get_script();
if (script.is_valid())
_fetch_translatable_strings(script.ptr(),strings);
for(int i=0;i<node->get_child_count();i++) {
Node *c=node->get_child(i);
if (c->get_owner()!=get_edited_scene())
continue;
_fetch_translatable_strings(c,strings);
}
}
Error EditorNode::save_translatable_strings(const String& p_to_file) {
if (!is_inside_tree()) {
defer_translatable=p_to_file;
return OK;
}
ERR_FAIL_COND_V(!get_edited_scene(),ERR_INVALID_DATA);
Set<StringName> strings;
_fetch_translatable_strings(get_edited_scene(),strings);
Error err;
FileAccess *f = FileAccess::open(p_to_file,FileAccess::WRITE,&err);
ERR_FAIL_COND_V(err,err);
OS::Date date = OS::get_singleton()->get_date();
OS::Time time = OS::get_singleton()->get_time();
f->store_line("# Translation Strings Dump.");
f->store_line("# Created By.");
f->store_line("# \t" VERSION_FULL_NAME " (c) 2008-2017 Juan Linietsky, Ariel Manzur.");
f->store_line("# From Scene: ");
f->store_line("# \t"+get_edited_scene()->get_filename());
f->store_line("");
f->store_line("msgid \"\"");
f->store_line("msgstr \"\"");
f->store_line("\"Report-Msgid-Bugs-To: <define>\\n\"");
f->store_line("\"POT-Creation-Date: "+itos(date.year)+"-"+itos(date.month)+"-"+itos(date.day)+" "+itos(time.hour)+":"+itos(time.min)+"0000\\n\"");
//f->store_line("\"PO-Revision-Date: 2006-08-30 13:56-0700\\n\"");
//f->store_line("\"Last-Translator: Rubén C. Díaz Alonso <outime@gmail.com>\\n\"");
f->store_line("\"Language-Team: <define>\\n\"");
f->store_line("\"MIME-Version: 1.0\\n\"");
f->store_line("\"Content-Type: text/plain; charset=UTF-8\\n\"");
f->store_line("\"Content-Transfer-Encoding: 8bit\\n\"");
f->store_line("");
for(Set<StringName>::Element *E=strings.front();E;E=E->next()) {
String s = E->get();
if (s=="" || s.strip_edges()=="")
continue;
Vector<String> substr = s.split("\n");
ERR_CONTINUE(substr.size()==0);
f->store_line("");
if (substr.size()==1) {
f->store_line("msgid \""+substr[0].c_escape()+"\"");
} else {
f->store_line("msgid \"\"");
for(int i=0;i<substr.size();i++) {
String s = substr[i];
if (i!=substr.size()-1)
s+="\n";
f->store_line("\""+s.c_escape()+"\"");
}
}
f->store_line("msgstr \"\"");
}
f->close();
memdelete(f);
return OK;
}
Error EditorNode::save_optimized_copy(const String& p_scene,const String& p_preset) {
#if 0
if (!is_inside_scene()) {
defer_optimize=p_scene;
defer_optimize_preset=p_preset;
return OK;
}
if (!get_edited_scene()) {
get_scene()->quit();
ERR_EXPLAIN("No scene to optimize (loading failed?)");
ERR_FAIL_V(ERR_FILE_NOT_FOUND);
}
String src_scene=GlobalConfig::get_singleton()->localize_path(get_edited_scene()->get_filename());
String path=p_scene;
print_line("p_path: "+p_scene);
print_line("src_scene: "+p_scene);
if (path.is_rel_path()) {
print_line("rel path!?");
path=src_scene.get_base_dir()+"/"+path;
}
path = GlobalConfig::get_singleton()->localize_path(path);
print_line("path: "+path);
String preset = "optimizer_presets/"+p_preset;
if (!GlobalConfig::get_singleton()->has(preset)) {
//accept->"()->hide();
accept->get_ok()->set_text("I see..");
accept->set_text("Optimizer preset not found: "+p_preset);
accept->popup_centered(Size2(300,70));
ERR_EXPLAIN("Optimizer preset not found: "+p_preset);
ERR_FAIL_V(ERR_INVALID_PARAMETER);
}
Dictionary d = GlobalConfig::get_singleton()->get(preset);
ERR_FAIL_COND_V(!d.has("__type__"),ERR_INVALID_DATA);
String type=d["__type__"];
Ref<EditorOptimizedSaver> saver;
for(int i=0;i<editor_data.get_optimized_saver_count();i++) {
print_line(type+" vs "+editor_data.get_optimized_saver(i)->get_target_name());
if (editor_data.get_optimized_saver(i)->get_target_name()==type) {
saver=editor_data.get_optimized_saver(i);
}
}
ERR_EXPLAIN("Preset '"+p_preset+"' references nonexistent saver: "+type);
ERR_FAIL_COND_V(saver.is_null(),ERR_INVALID_DATA);
List<Variant> keys;
d.get_key_list(&keys);
saver->clear();
for(List<Variant>::Element *E=keys.front();E;E=E->next()) {
saver->set(E->get(),d[E->get()]);
}
uint32_t flags=0;
/*
if (saver->is_bundle_scenes_enabled())
flags|=ResourceSaver::FLAG_BUNDLE_INSTANCED_SCENES;
*/
if (saver->is_bundle_resources_enabled())
flags|=ResourceSaver::FLAG_BUNDLE_RESOURCES;
if (saver->is_remove_editor_data_enabled())
flags|=ResourceSaver::FLAG_OMIT_EDITOR_PROPERTIES;
if (saver->is_big_endian_data_enabled())
flags|=ResourceSaver::FLAG_SAVE_BIG_ENDIAN;
String platform=saver->get_target_platform();
if (platform=="")
platform="all";
Ref<PackedScene> sdata = memnew( PackedScene );
Error err = sdata->pack(get_edited_scene());
if (err) {
current_option=-1;
//accept->get_cancel()->hide();
accept->get_ok()->set_text("I see..");
accept->set_text("Couldn't save scene. Likely dependencies (instances) couldn't be satisfied.");
accept->popup_centered(Size2(300,70));
return ERR_INVALID_DATA;
}
err = ResourceSaver::save(path,sdata,flags); //todo, saverSceneSaver::save(path,get_edited_scene(),flags,saver);
if (err) {
//accept->"()->hide();
accept->get_ok()->set_text("I see..");
accept->set_text("Error saving optimized scene: "+path);
accept->popup_centered(Size2(300,70));
ERR_FAIL_COND_V(err,err);
}
project_settings->add_remapped_path(src_scene,path,platform);
#endif
return OK;
}
int EditorNode::_get_current_main_editor() {
@ -3834,6 +3506,10 @@ void EditorNode::request_instance_scenes(const Vector<String>& p_files) {
scene_tree_dock->instance_scenes(p_files);
}
ImportDock *EditorNode::get_import_dock() {
return import_dock;
}
FileSystemDock *EditorNode::get_filesystem_dock() {
return filesystem_dock;
@ -5063,7 +4739,6 @@ Variant EditorNode::drag_resource(const Ref<Resource>& p_res,Control* p_from) {
TextureRect *drag_preview = memnew( TextureRect );
Label* label=memnew( Label );
waiting_for_sources_changed=true; //
Ref<Texture> preview;
{
@ -5440,6 +5115,13 @@ EditorNode::EditorNode() {
ResourceLoader::set_timestamp_on_load(true);
ResourceSaver::set_timestamp_on_save(true);
{ //register importers at the begining, so dialogs are created with the right extensions
Ref<ResourceImporterTexture> import_texture;
import_texture.instance();
ResourceFormatImporter::get_singleton()->add_importer(import_texture);
}
_pvrtc_register_compressors();
editor_selection = memnew( EditorSelection );
@ -5765,7 +5447,6 @@ EditorNode::EditorNode() {
pm_export->set_name("Export");
p->add_child(pm_export);
p->add_submenu_item(TTR("Convert To.."),"Export");
pm_export->add_item(TTR("Translatable Strings.."),FILE_DUMP_STRINGS);
pm_export->add_separator();
pm_export->add_shortcut(ED_SHORTCUT("editor/convert_to_MeshLibrary", TTR("MeshLibrary..")), FILE_EXPORT_MESH_LIBRARY);
pm_export->add_shortcut(ED_SHORTCUT("editor/convert_to_TileSet", TTR("TileSet..")), FILE_EXPORT_TILESET);
@ -6248,6 +5929,11 @@ EditorNode::EditorNode() {
property_editor->set_undo_redo(&editor_data.get_undo_redo());
import_dock = memnew( ImportDock );
dock_slot[DOCK_SLOT_RIGHT_UL]->add_child(import_dock);
import_dock->set_name(TTR("Import"));
node_dock = memnew( NodeDock );
//node_dock->set_undoredo(&editor_data.get_undo_redo());
if (use_single_dock_column) {
@ -6584,6 +6270,9 @@ EditorNode::EditorNode() {
plugin_init_callbacks[i]();
}
/*resource_preview->add_preview_generator( Ref<EditorTexturePreviewPlugin>( memnew(EditorTexturePreviewPlugin )));
resource_preview->add_preview_generator( Ref<EditorPackedScenePreviewPlugin>( memnew(EditorPackedScenePreviewPlugin )));
resource_preview->add_preview_generator( Ref<EditorMaterialPreviewPlugin>( memnew(EditorMaterialPreviewPlugin )));
@ -6730,6 +6419,7 @@ EditorNode::EditorNode() {
FileAccess::set_file_close_fail_notify_callback(_file_access_close_error_notify);
waiting_for_first_scan=true;
}

View file

@ -50,6 +50,7 @@
#include "tools/editor/reparent_dialog.h"
#include "tools/editor/connections_dialog.h"
#include "tools/editor/node_dock.h"
#include "tools/editor/import_dock.h"
#include "tools/editor/settings_config_dialog.h"
#include "tools/editor/groups_editor.h"
#include "tools/editor/editor_data.h"
@ -134,7 +135,6 @@ private:
FILE_EXPORT_MESH_LIBRARY,
FILE_EXPORT_TILESET,
FILE_SAVE_OPTIMIZED,
FILE_DUMP_STRINGS,
FILE_OPEN_RECENT,
FILE_OPEN_OLD_SCENE,
FILE_QUICK_OPEN_SCENE,
@ -278,6 +278,7 @@ private:
//ResourcesDock *resources_dock;
PropertyEditor *property_editor;
NodeDock *node_dock;
ImportDock *import_dock;
VBoxContainer *prop_editor_vb;
FileSystemDock *filesystem_dock;
EditorRunNative *run_native;
@ -318,9 +319,6 @@ private:
//TabContainer *prop_pallete;
//TabContainer *top_pallete;
String defer_load_scene;
String defer_translatable;
String defer_optimize;
String defer_optimize_preset;
String defer_export;
String defer_export_platform;
bool defer_export_debug;
@ -376,6 +374,7 @@ private:
bool unsaved_cache;
String open_navigate;
bool changing_scene;
bool waiting_for_first_scan;
bool waiting_for_sources_changed;
@ -488,7 +487,6 @@ private:
static void _load_error_notify(void* p_ud,const String& p_text);
bool has_main_screen() const { return true; }
void _fetch_translatable_strings(const Object *p_object,Set<StringName>& strings);
bool _find_editing_changed_scene(Node *p_from);
@ -683,7 +681,6 @@ public:
Node *get_edited_scene() { return editor_data.get_edited_scene_root(); }
Viewport *get_scene_root() { return scene_root; } //root of the scene being edited
Error save_optimized_copy(const String& p_scene,const String& p_preset);
void fix_dependencies(const String& p_for_file);
void clear_scene() { _cleanup_scene(); }
@ -703,13 +700,12 @@ public:
void request_instance_scene(const String &p_path);
void request_instance_scenes(const Vector<String>& p_files);
FileSystemDock *get_filesystem_dock();
ImportDock *get_import_dock();
SceneTreeDock *get_scene_tree_dock();
static UndoRedo* get_undo_redo() { return &singleton->editor_data.get_undo_redo(); }
EditorSelection *get_editor_selection() { return editor_selection; }
Error save_translatable_strings(const String& p_to_file);
void set_convert_old_scene(bool p_old) { convert_old=p_old; }
void notify_child_process_exited();
@ -784,7 +780,6 @@ public:
};
struct EditorProgress {
String task;

View file

@ -350,25 +350,9 @@ void FileSystemDock::_search(EditorFileSystemDirectory *p_path,List<FileInfo>* m
FileInfo fi;
fi.name=file;
fi.type=p_path->get_file_type(i);
fi.path=p_path->get_file_path(i);
if (p_path->get_file_meta(i)) {
if (p_path->is_missing_sources(i)) {
fi.import_status=3;
} else if (p_path->have_sources_changed(i)) {
fi.import_status=2;
} else {
fi.import_status=1;
}
} else {
fi.import_status=0;
}
for(int j=0;j<p_path->get_source_count(i);j++) {
/*String s = EditorImportPlugin::expand_source_path(p_path->get_source_file(i,j));
if (p_path->is_source_file_missing(i,j)) {
s+=" (Missing)";
}
fi.sources.push_back(s);*/
}
fi.path=p_path->get_file_path(i);
fi.import_status=0;
matches->push_back(fi);
if (matches->size()>p_max_items)
@ -500,25 +484,7 @@ void FileSystemDock::_update_files(bool p_keep_selection) {
fi.name=efd->get_file(i);
fi.path=path.plus_file(fi.name);
fi.type=efd->get_file_type(i);
if (efd->get_file_meta(i)) {
if (efd->is_missing_sources(i)) {
fi.import_status=3;
} else if (efd->have_sources_changed(i)) {
fi.import_status=2;
} else {
fi.import_status=1;
}
for(int j=0;j<efd->get_source_count(i);j++) {
/*String s = EditorImportPlugin::expand_source_path(efd->get_source_file(i,j));
if (efd->is_source_file_missing(i,j)) {
s+=" (Missing)";
}
fi.sources.push_back(s);*/
}
} else {
fi.import_status=0;
}
fi.import_status=0;
@ -1538,26 +1504,6 @@ void FileSystemDock::_files_list_rmb_select(int p_item,const Vector2& p_pos) {
if (efsd) {
if (!efsd->get_file_meta(pos)) {
all_can_reimport=false;
} else {
/*
Ref<ResourceImportMetadata> rimd = ResourceLoader::load_import_metadata(path);
if (rimd.is_valid()) {
String editor=rimd->get_editor();
if (editor.begins_with("texture_")) { //compatibility fix for old texture format
editor="texture";
}
types.insert(editor);
} else {
all_can_reimport=false;
}*/
}
} else {
all_can_reimport=false;
@ -1642,6 +1588,57 @@ void FileSystemDock::select_file(const String& p_file) {
}
void FileSystemDock::_file_multi_selected(int p_index,bool p_selected) {
_file_selected();
}
void FileSystemDock::_file_selected() {
//check import
Vector<String> imports;
String import_type;
for(int i=0;i<files->get_item_count();i++) {
if (!files->is_selected(i))
continue;
String p = files->get_item_metadata(i);
if (!FileAccess::exists(p+".import")) {
imports.clear();
break;
}
Ref<ConfigFile> cf;
cf.instance();
Error err = cf->load(p+".import");
if (err!=OK) {
imports.clear();
break;
}
String type = cf->get_value("remap","type");
if (import_type=="") {
import_type=type;
} else if (import_type!=type) {
//all should be the same type
imports.clear();
break;
}
imports.push_back(p);
}
if (imports.size()==0) {
EditorNode::get_singleton()->get_import_dock()->clear();
} else if (imports.size()==1) {
EditorNode::get_singleton()->get_import_dock()->set_edit_path(imports[0]);
} else {
EditorNode::get_singleton()->get_import_dock()->set_edit_multiple_paths(imports);
}
}
void FileSystemDock::_bind_methods() {
ClassDB::bind_method(_MD("_update_tree"),&FileSystemDock::_update_tree);
@ -1673,6 +1670,8 @@ void FileSystemDock::_bind_methods() {
ClassDB::bind_method(_MD("_files_list_rmb_select"),&FileSystemDock::_files_list_rmb_select);
ClassDB::bind_method(_MD("_preview_invalidated"),&FileSystemDock::_preview_invalidated);
ClassDB::bind_method(_MD("_file_selected"),&FileSystemDock::_file_selected);
ClassDB::bind_method(_MD("_file_multi_selected"),&FileSystemDock::_file_multi_selected);
ADD_SIGNAL(MethodInfo("instance", PropertyInfo(Variant::POOL_STRING_ARRAY, "files")));
@ -1777,6 +1776,8 @@ FileSystemDock::FileSystemDock(EditorNode *p_editor) {
files->set_select_mode(ItemList::SELECT_MULTI);
files->set_drag_forwarding(this);
files->connect("item_rmb_selected",this,"_files_list_rmb_select");
files->connect("item_selected",this,"_file_selected");
files->connect("multi_selected",this,"_file_multi_selected");
files->set_allow_rmb_select(true);
file_list_vb = memnew( VBoxContainer );

View file

@ -126,6 +126,11 @@ private:
Tree * tree; //directories
ItemList *files;
void _file_multi_selected(int p_index, bool p_selected);
void _file_selected();
void _go_to_tree();
void _go_to_dir(const String& p_dir);
void _select_file(int p_idx);

View file

@ -0,0 +1,274 @@
#include "resource_import_texture.h"
#include "io/image_loader.h"
#include "scene/resources/texture.h"
String ResourceImporterTexture::get_importer_name() const {
return "texture";
}
String ResourceImporterTexture::get_visible_name() const{
return "Texture";
}
void ResourceImporterTexture::get_recognized_extensions(List<String> *p_extensions) const{
ImageLoader::get_recognized_extensions(p_extensions);
}
String ResourceImporterTexture::get_save_extension() const {
return "stex";
}
String ResourceImporterTexture::get_resource_type() const{
return "StreamTexture";
}
bool ResourceImporterTexture::get_option_visibility(const String& p_option,const Map<StringName,Variant>& p_options) const {
if (p_option=="compress/lossy_quality" && int(p_options["compress/mode"])!=COMPRESS_LOSSY)
return false;
return true;
}
int ResourceImporterTexture::get_preset_count() const {
return 4;
}
String ResourceImporterTexture::get_preset_name(int p_idx) const {
static const char* preset_names[]={
"2D, Detect 3D",
"2D",
"2D Pixel",
"3D"
};
return preset_names[p_idx];
}
void ResourceImporterTexture::get_import_options(List<ImportOption> *r_options,int p_preset) const {
r_options->push_back(ImportOption(PropertyInfo(Variant::INT,"compress/mode",PROPERTY_HINT_ENUM,"Lossless,Lossy,Video RAM,Uncompressed",PROPERTY_USAGE_DEFAULT|PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED),p_preset==PRESET_3D?2:0));
r_options->push_back(ImportOption(PropertyInfo(Variant::REAL,"compress/lossy_quality",PROPERTY_HINT_RANGE,"0,1,0.01"),0.7));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT,"flags/repeat",PROPERTY_HINT_ENUM,"Disabled,Enabled,Mirrored"),p_preset==PRESET_3D?1:0));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"flags/filter"),p_preset==PRESET_2D_PIXEL?false:true));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"flags/mipmaps"),p_preset==PRESET_3D?true:false));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"flags/anisotropic"),false));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"flags/srgb",PROPERTY_HINT_ENUM,"Disable,Enable,Detect"),2));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"process/fix_alpha_border"),p_preset!=PRESET_3D?true:false));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"process/premult_alpha"),true));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT,"stream"),false));
r_options->push_back(ImportOption(PropertyInfo(Variant::INT,"size_limit",PROPERTY_HINT_RANGE,"0,4096,1"),0));
r_options->push_back(ImportOption(PropertyInfo(Variant::BOOL,"detect_3d"),p_preset==PRESET_DETECT));
}
void ResourceImporterTexture::_save_stex(const Image& p_image,const String& p_to_path,int p_compress_mode,float p_lossy_quality,Image::CompressMode p_vram_compression,bool p_mipmaps,int p_texture_flags,bool p_streamable) {
FileAccess *f = FileAccess::open(p_to_path,FileAccess::WRITE);
f->store_8('G');
f->store_8('D');
f->store_8('S');
f->store_8('T'); //godot streamable texture
f->store_32(p_image.get_width());
f->store_32(p_image.get_height());
f->store_32(p_texture_flags);
uint32_t format=0;
if (p_streamable)
format|=StreamTexture::FORMAT_BIT_STREAM;
if (p_mipmaps || p_compress_mode==COMPRESS_VIDEO_RAM) //VRAM always uses mipmaps
format|=StreamTexture::FORMAT_BIT_HAS_MIPMAPS; //mipmaps bit
switch (p_compress_mode) {
case COMPRESS_LOSSLESS: {
Image image = p_image;
if (p_mipmaps) {
image.generate_mipmaps();
} else {
image.clear_mipmaps();
}
int mmc = image.get_mipmap_count() + 1;
format=StreamTexture::FORMAT_BIT_LOSSLESS;
f->store_32(format);
f->store_32(mmc);
for(int i=0;i<mmc;i++) {
if (i>0) {
image.shrink_x2();
}
PoolVector<uint8_t> data = Image::lossless_packer(image);
int data_len = data.size();
f->store_32(data_len);
PoolVector<uint8_t>::Read r= data.read();
f->store_buffer(r.ptr(),data_len);
}
} break;
case COMPRESS_LOSSY: {
Image image = p_image;
if (p_mipmaps) {
image.generate_mipmaps();
} else {
image.clear_mipmaps();
}
int mmc = image.get_mipmap_count() + 1;
format=StreamTexture::FORMAT_BIT_LOSSY;
f->store_32(format);
f->store_32(mmc);
for(int i=0;i<mmc;i++) {
if (i>0) {
image.shrink_x2();
}
PoolVector<uint8_t> data = Image::lossy_packer(image,p_lossy_quality);
int data_len = data.size();
f->store_32(data_len);
PoolVector<uint8_t>::Read r = data.read();
f->store_buffer(r.ptr(),data_len);
}
} break;
case COMPRESS_VIDEO_RAM: {
Image image = p_image;
image.generate_mipmaps();
image.compress(p_vram_compression);
format |= image.get_format();
f->store_32(format);
PoolVector<uint8_t> data=image.get_data();
int dl = data.size();
PoolVector<uint8_t>::Read r = data.read();
f->store_buffer(r.ptr(),dl);
} break;
case COMPRESS_UNCOMPRESSED: {
Image image = p_image;
if (p_mipmaps) {
image.generate_mipmaps();
} else {
image.clear_mipmaps();
}
format |= image.get_format();
f->store_32(format);
PoolVector<uint8_t> data=image.get_data();
int dl = data.size();
PoolVector<uint8_t>::Read r = data.read();
f->store_buffer(r.ptr(),dl);
} break;
}
memdelete(f);
}
Error ResourceImporterTexture::import(const String& p_source_file,const String& p_save_path,const Map<StringName,Variant>& p_options,List<String>* r_platform_variants) {
int compress_mode = p_options["compress/mode"];
float lossy= p_options["compress/lossy_quality"];
int repeat= p_options["flags/repeat"];
bool filter= p_options["flags/filter"];
bool mipmaps= p_options["flags/mipmaps"];
bool anisotropic= p_options["flags/anisotropic"];
bool srgb= p_options["flags/srgb"];
bool fix_alpha_border= p_options["process/fix_alpha_border"];
bool premult_alpha= p_options["process/premult_alpha"];
bool stream = p_options["stream"];
int size_limit = p_options["size_limit"];
Image image;
Error err = ImageLoader::load_image(p_source_file,&image);
if (err!=OK)
return err;
int tex_flags=0;
if (repeat>0)
tex_flags|=Texture::FLAG_REPEAT;
if (repeat==2)
tex_flags|=Texture::FLAG_MIRRORED_REPEAT;
if (filter)
tex_flags|=Texture::FLAG_FILTER;
if (mipmaps || compress_mode==COMPRESS_VIDEO_RAM)
tex_flags|=Texture::FLAG_MIPMAPS;
if (anisotropic)
tex_flags|=Texture::FLAG_ANISOTROPIC_FILTER;
if (srgb)
tex_flags|=Texture::FLAG_CONVERT_TO_LINEAR;
if (size_limit >0 && (image.get_width()>size_limit || image.get_height()>size_limit )) {
//limit size
if (image.get_width() >= image.get_height()) {
int new_width = size_limit;
int new_height = image.get_height() * new_width / image.get_width();
image.resize(new_width,new_height,Image::INTERPOLATE_CUBIC);
} else {
int new_height = size_limit;
int new_width = image.get_width() * new_height / image.get_height();
image.resize(new_width,new_height,Image::INTERPOLATE_CUBIC);
}
}
if (fix_alpha_border) {
image.fix_alpha_edges();
}
if (premult_alpha) {
image.premultiply_alpha();
}
if (compress_mode==COMPRESS_VIDEO_RAM) {
//must import in all formats
//Android, GLES 2.x
_save_stex(image,p_save_path+".etc.stex",compress_mode,lossy,Image::COMPRESS_ETC,mipmaps,tex_flags,stream);
r_platform_variants->push_back("etc");
//_save_stex(image,p_save_path+".etc2.stex",compress_mode,lossy,Image::COMPRESS_ETC2,mipmaps,tex_flags,stream);
//r_platform_variants->push_back("etc2");
_save_stex(image,p_save_path+".s3tc.stex",compress_mode,lossy,Image::COMPRESS_S3TC,mipmaps,tex_flags,stream);
r_platform_variants->push_back("s3tc");
} else {
//import normally
_save_stex(image,p_save_path+".stex",compress_mode,lossy,Image::COMPRESS_16BIT /*this is ignored */,mipmaps,tex_flags,stream);
}
return OK;
}
ResourceImporterTexture::ResourceImporterTexture()
{
}

View file

@ -0,0 +1,43 @@
#ifndef RESOURCEIMPORTTEXTURE_H
#define RESOURCEIMPORTTEXTURE_H
#include "io/resource_import.h"
class ResourceImporterTexture : public ResourceImporter {
GDCLASS(ResourceImporterTexture,ResourceImporter)
public:
virtual String get_importer_name() const;
virtual String get_visible_name() const;
virtual void get_recognized_extensions(List<String> *p_extensions) const;
virtual String get_save_extension() const;
virtual String get_resource_type() const;
enum Preset {
PRESET_DETECT,
PRESET_2D,
PRESET_2D_PIXEL,
PRESET_3D,
};
enum CompressMode {
COMPRESS_LOSSLESS,
COMPRESS_LOSSY,
COMPRESS_VIDEO_RAM,
COMPRESS_UNCOMPRESSED
};
virtual int get_preset_count() const;
virtual String get_preset_name(int p_idx) const;
virtual void get_import_options(List<ImportOption> *r_options,int p_preset=0) const;
virtual bool get_option_visibility(const String& p_option,const Map<StringName,Variant>& p_options) const;
void _save_stex(const Image& p_image, const String& p_to_path, int p_compress_mode, float p_lossy_quality, Image::CompressMode p_vram_compression, bool p_mipmaps, int p_texture_flags, bool p_streamable);
virtual Error import(const String& p_source_file,const String& p_save_path,const Map<StringName,Variant>& p_options,List<String>* r_platform_variants);
ResourceImporterTexture();
};
#endif // RESOURCEIMPORTTEXTURE_H

View file

@ -0,0 +1,331 @@
#include "import_dock.h"
class ImportDockParameters : public Object {
GDCLASS(ImportDockParameters,Object)
public:
Map<StringName,Variant> values;
List<PropertyInfo> properties;
Ref<ResourceImporter> importer;
Vector<String> paths;
bool _set(const StringName& p_name, const Variant& p_value) {
if (values.has(p_name)) {
values[p_name]=p_value;
return true;
}
return false;
}
bool _get(const StringName& p_name,Variant &r_ret) const {
if (values.has(p_name)) {
r_ret=values[p_name];
return true;
}
return false;
}
void _get_property_list( List<PropertyInfo> *p_list) const {
for (const List<PropertyInfo>::Element *E=properties.front();E;E=E->next()) {
if (!importer->get_option_visibility(E->get().name,values))
continue;
p_list->push_back(E->get());
}
}
void update() {
_change_notify();
}
};
void ImportDock::set_edit_path(const String& p_path) {
Ref<ConfigFile> config;
config.instance();
Error err = config->load(p_path+".import");
if (err!=OK) {
clear();
return;
}
params->importer = ResourceFormatImporter::get_singleton()->get_importer_by_name(config->get_value("remap","importer"));
if (params->importer.is_null()) {
clear();
return;
}
List<ResourceImporter::ImportOption> options;
params->importer->get_import_options(&options);
params->properties.clear();
params->values.clear();
for (List<ResourceImporter::ImportOption>::Element *E=options.front();E;E=E->next()) {
params->properties.push_back(E->get().option);
if (config->has_section_key("params",E->get().option.name)) {
params->values[E->get().option.name]=config->get_value("params",E->get().option.name);
} else {
params->values[E->get().option.name]=E->get().default_value;
}
}
params->update();
List<Ref<ResourceImporter> > importers;
ResourceFormatImporter::get_singleton()->get_importers_for_extension(p_path.get_extension(),&importers);
List<Pair<String,String> > importer_names;
for (List<Ref<ResourceImporter> > ::Element *E=importers.front();E;E=E->next()) {
importer_names.push_back(Pair<String,String>(E->get()->get_visible_name(),E->get()->get_importer_name()));
}
importer_names.sort_custom<PairSort<String,String> >();
import_as->clear();
for (List<Pair<String,String> >::Element *E=importer_names.front();E;E=E->next()) {
import_as->add_item(E->get().first);
import_as->set_item_metadata(import_as->get_item_count()-1,E->get().second);
if (E->get().second==params->importer->get_importer_name()) {
import_as->select(import_as->get_item_count()-1);
}
}
preset->get_popup()->clear();
if (params->importer->get_preset_count()==0) {
preset->get_popup()->add_item(TTR("Default"));
} else {
for (int i=0;i<params->importer->get_preset_count();i++) {
preset->get_popup()->add_item(params->importer->get_preset_name(i));
}
}
params->paths.clear();
params->paths.push_back(p_path);
import->set_disabled(false);
import_as->set_disabled(false);
imported->set_text(p_path.get_file());
}
void ImportDock::set_edit_multiple_paths(const Vector<String>& p_paths) {
clear();
//use the value that is repeated the mot
Map<String,Dictionary> value_frequency;
for(int i=0;i<p_paths.size();i++) {
Ref<ConfigFile> config;
config.instance();
Error err = config->load(p_paths[i]+".import");
ERR_CONTINUE(err!=OK);
if (i==0) {
params->importer = ResourceFormatImporter::get_singleton()->get_importer_by_name(config->get_value("remap","importer"));
if (params->importer.is_null()) {
clear();
return;
}
}
List<String> keys;
config->get_section_keys("params",&keys);
for (List<String>::Element *E=keys.front();E;E=E->next()) {
if (!value_frequency.has(E->get())) {
value_frequency[E->get()]=Dictionary();
}
Variant value = config->get_value("params",E->get());
if (value_frequency[E->get()].has(value)) {
value_frequency[E->get()][value]=int(value_frequency[E->get()][value])+1;
} else {
value_frequency[E->get()][value]=1;
}
}
}
ERR_FAIL_COND(params->importer.is_null());
List<ResourceImporter::ImportOption> options;
params->importer->get_import_options(&options);
params->properties.clear();
params->values.clear();
for (List<ResourceImporter::ImportOption>::Element *E=options.front();E;E=E->next()) {
params->properties.push_back(E->get().option);
if (value_frequency.has(E->get().option.name)) {
Dictionary d = value_frequency[E->get().option.name];
int freq=0;
List<Variant> v;
d.get_key_list(&v);
Variant value;
for (List<Variant>::Element *F=v.front();F;F=F->next()) {
int f = d[F->get()];
if (f>freq) {
value=F->get();
}
}
params->values[E->get().option.name]=value;
} else {
params->values[E->get().option.name]=E->get().default_value;
}
}
params->update();
List<Ref<ResourceImporter> > importers;
ResourceFormatImporter::get_singleton()->get_importers_for_extension(p_paths[0].get_extension(),&importers);
List<Pair<String,String> > importer_names;
for (List<Ref<ResourceImporter> > ::Element *E=importers.front();E;E=E->next()) {
importer_names.push_back(Pair<String,String>(E->get()->get_visible_name(),E->get()->get_importer_name()));
}
importer_names.sort_custom<PairSort<String,String> >();
import_as->clear();
for (List<Pair<String,String> >::Element *E=importer_names.front();E;E=E->next()) {
import_as->add_item(E->get().first);
import_as->set_item_metadata(import_as->get_item_count()-1,E->get().second);
if (E->get().second==params->importer->get_importer_name()) {
import_as->select(import_as->get_item_count()-1);
}
}
preset->get_popup()->clear();
if (params->importer->get_preset_count()==0) {
preset->get_popup()->add_item(TTR("Default"));
} else {
for (int i=0;i<params->importer->get_preset_count();i++) {
preset->get_popup()->add_item(params->importer->get_preset_name(i));
}
}
params->paths=p_paths;
import->set_disabled(false);
import_as->set_disabled(false);
imported->set_text(itos(p_paths.size())+TTR(" Files"));
}
void ImportDock::_preset_selected(int p_idx) {
print_line("preset selected? "+p_idx);
List<ResourceImporter::ImportOption> options;
params->importer->get_import_options(&options,p_idx);
for (List<ResourceImporter::ImportOption>::Element *E=options.front();E;E=E->next()) {
params->values[E->get().option.name]=E->get().default_value;
}
params->update();
}
void ImportDock::clear() {
imported->set_text("");
import->set_disabled(true);
import_as->clear();
import_as->set_disabled(true);
params->values.clear();
params->properties.clear();
params->update();
preset->get_popup()->clear();
}
void ImportDock::_reimport() {
for(int i=0;i<params->paths.size();i++) {
Ref<ConfigFile> config;
config.instance();
Error err = config->load(params->paths[i]+".import");
ERR_CONTINUE(err!=OK);
config->erase_section("params");
for (List<PropertyInfo>::Element *E=params->properties.front();E;E=E->next()) {
config->set_value("params",E->get().name,params->values[E->get().name]);
}
config->save(params->paths[i]+".import");
}
EditorFileSystem::get_singleton()->reimport_files(params->paths);
EditorFileSystem::get_singleton()->emit_signal("filesystem_changed"); //it changed, so force emitting the signal
}
void ImportDock::_bind_methods() {
ClassDB::bind_method(_MD("_reimport"),&ImportDock::_reimport);
ClassDB::bind_method(_MD("_preset_selected"),&ImportDock::_preset_selected);
}
ImportDock::ImportDock() {
imported = memnew( LineEdit );
imported->set_editable(false);
add_child(imported);
HBoxContainer *hb = memnew(HBoxContainer);
add_margin_child(TTR("Import As:"),hb);
import_as = memnew( OptionButton );
hb->add_child(import_as);
import_as->set_h_size_flags(SIZE_EXPAND_FILL);
preset = memnew( MenuButton );
preset->set_text(TTR("Preset.."));
preset->get_popup()->connect("index_pressed",this,"_preset_selected");
hb->add_child(preset);
import_opts = memnew( PropertyEditor );
add_child(import_opts);
import_opts->set_v_size_flags(SIZE_EXPAND_FILL);
import_opts->hide_top_label();
import_opts->set_hide_script(true);
hb = memnew( HBoxContainer );
add_child(hb);
import = memnew( Button );
import->set_text(TTR("Reimport"));
import->connect("pressed",this,"_reimport");
hb->add_spacer();
hb->add_child(import);
hb->add_spacer();
params = memnew( ImportDockParameters );
import_opts->edit(params);
}
ImportDock::~ImportDock() {
memdelete(params);
}

View file

@ -0,0 +1,42 @@
#ifndef IMPORTDOCK_H
#define IMPORTDOCK_H
#include "io/resource_import.h"
#include "editor_file_system.h"
#include "scene/gui/box_container.h"
#include "scene/gui/option_button.h"
#include "scene/gui/popup_menu.h"
#include "property_editor.h"
class ImportDockParameters;
class ImportDock : public VBoxContainer {
GDCLASS(ImportDock,VBoxContainer)
LineEdit *imported;
OptionButton *import_as;
MenuButton *preset;
PropertyEditor *import_opts;
List<PropertyInfo> properties;
Map<StringName,Variant> property_values;
Button *import;
ImportDockParameters *params;
void _preset_selected(int p_idx);
void _reimport();
protected:
static void _bind_methods();
public:
void set_edit_path(const String& p_path);
void set_edit_multiple_paths(const Vector<String>& p_paths);
void clear();
ImportDock();
~ImportDock();
};
#endif // IMPORTDOCK_H

View file

@ -29,6 +29,11 @@
#ifndef EDITOR_TEXTURE_IMPORT_PLUGIN_H
#define EDITOR_TEXTURE_IMPORT_PLUGIN_H
#if 0
#include "tools/editor/editor_import_export.h"
#include "scene/gui/dialogs.h"

View file

@ -118,7 +118,7 @@ void CustomPropertyEditor::_menu_option(int p_which) {
Set<String> valid_extensions;
for (List<String>::Element *E=extensions.front();E;E=E->next()) {
print_line("found: "+E->get());
valid_extensions.insert(E->get());
}
@ -3140,6 +3140,10 @@ void PropertyEditor::update_tree() {
} else if ( ! (p.usage&PROPERTY_USAGE_EDITOR ) )
continue;
if (hide_script && p.name=="script/script")
continue;
String basename=p.name;
if (group!="") {
if (group_base!="") {
@ -3886,7 +3890,7 @@ void PropertyEditor::_item_selected() {
}
void PropertyEditor::_edit_set(const String& p_name, const Variant& p_value) {
void PropertyEditor::_edit_set(const String& p_name, const Variant& p_value, bool p_refresh_all) {
if (autoclear) {
TreeItem *item = tree->get_selected();
@ -3899,7 +3903,11 @@ void PropertyEditor::_edit_set(const String& p_name, const Variant& p_value) {
if (!undo_redo || obj->cast_to<MultiNodeEdit>() || obj->cast_to<ArrayPropertyEdit>()) { //kind of hacky
obj->set(p_name,p_value);
_changed_callbacks(obj,p_name);
if (p_refresh_all)
_changed_callbacks(obj,"");
else
_changed_callbacks(obj,p_name);
emit_signal(_prop_edited,p_name);
@ -3909,9 +3917,14 @@ void PropertyEditor::_edit_set(const String& p_name, const Variant& p_value) {
undo_redo->add_do_property(obj,p_name,p_value);
undo_redo->add_undo_property(obj,p_name,obj->get(p_name));
if (p_refresh_all) {
undo_redo->add_do_method(this,"_changed_callback",obj,"");
undo_redo->add_undo_method(this,"_changed_callback",obj,"");
} else {
undo_redo->add_do_method(this,"_changed_callback",obj,p_name);
undo_redo->add_undo_method(this,"_changed_callback",obj,p_name);
undo_redo->add_do_method(this,"_changed_callback",obj,p_name);
undo_redo->add_undo_method(this,"_changed_callback",obj,p_name);
}
Resource *r = obj->cast_to<Resource>();
if (r) {
@ -3973,6 +3986,9 @@ void PropertyEditor::_item_edited() {
int type=d["type"];
int hint= d["hint"];
int usage = d["usage"];
bool refresh_all = usage&PROPERTY_USAGE_UPDATE_ALL_IF_MODIFIED;
String hint_text=d["hint_text"];
switch(type) {
@ -3981,7 +3997,7 @@ void PropertyEditor::_item_edited() {
} break;
case Variant::BOOL: {
_edit_set(name,item->is_checked(1));
_edit_set(name,item->is_checked(1),refresh_all);
item->set_tooltip(1, item->is_checked(1) ? "True" : "False");
} break;
case Variant::INT:
@ -3995,9 +4011,9 @@ void PropertyEditor::_item_edited() {
break;
if (type==Variant::INT)
_edit_set(name,int(item->get_range(1)));
_edit_set(name,int(item->get_range(1)),refresh_all);
else
_edit_set(name,item->get_range(1));
_edit_set(name,item->get_range(1),refresh_all);
} break;
case Variant::STRING: {
@ -4012,9 +4028,9 @@ void PropertyEditor::_item_edited() {
txt=strings[idx];
}
_edit_set(name,txt);
_edit_set(name,txt,refresh_all);
} else {
_edit_set(name,item->get_text(1));
_edit_set(name,item->get_text(1),refresh_all);
}
} break;
// math types
@ -4045,7 +4061,7 @@ void PropertyEditor::_item_edited() {
} break;
case Variant::NODE_PATH: {
_edit_set(name, NodePath(item->get_text(1)));
_edit_set(name, NodePath(item->get_text(1)),refresh_all);
} break;
@ -4476,6 +4492,8 @@ PropertyEditor::PropertyEditor() {
_prop_edited="property_edited";
hide_script=false;
undo_redo=NULL;
obj=NULL;
search_box=NULL;

View file

@ -192,6 +192,7 @@ class PropertyEditor : public Control {
bool use_doc_hints;
bool use_filter;
bool subsection_selectable;
bool hide_script;
HashMap<String,String> pending;
String selected_property;
@ -224,7 +225,7 @@ class PropertyEditor : public Control {
void _node_removed(Node *p_node);
friend class ProjectExportDialog;
void _edit_set(const String& p_name, const Variant& p_value);
void _edit_set(const String& p_name, const Variant& p_value,bool p_refresh_all=false);
void _draw_flags(Object *ti,const Rect2& p_rect);
bool _might_be_in_instance();
@ -276,6 +277,7 @@ public:
void set_show_categories(bool p_show);
void set_use_doc_hints(bool p_enable) { use_doc_hints=p_enable; }
void set_hide_script(bool p_hide) { hide_script=p_hide; }
void set_use_filter(bool p_use);
void register_text_enter(Node *p_line_edit);