FileDialog::~FileDialog() { if (unregister_func) unregister_func(this); memdelete(dir_access); }
~EditorFontImportDialog() { memdelete(options); }
void ScriptCreateDialog::_path_changed(const String& p_path) { path_valid=false; String p =p_path; if (p=="") { path_error_label->set_text(TTR("Path is empty")); path_error_label->add_color_override("font_color",Color(1,0.4,0.0,0.8)); return; } p = Globals::get_singleton()->localize_path(p); if (!p.begins_with("res://")) { path_error_label->set_text(TTR("Path is not local")); path_error_label->add_color_override("font_color",Color(1,0.4,0.0,0.8)); return; } if (p.find("/") || p.find("\\")) { DirAccess *d = DirAccess::create(DirAccess::ACCESS_RESOURCES); if (d->change_dir(p.get_base_dir())!=OK) { path_error_label->set_text(TTR("Invalid base path")); path_error_label->add_color_override("font_color",Color(1,0.4,0.0,0.8)); memdelete(d); return; } memdelete(d); } FileAccess *f = FileAccess::create(FileAccess::ACCESS_RESOURCES); if (f->file_exists(p)) { path_error_label->set_text(TTR("File exists")); path_error_label->add_color_override("font_color",Color(1,0.4,0.0,0.8)); memdelete(f); return; } memdelete(f); String extension=p.extension(); List<String> extensions; int l=language_menu->get_selected(); ScriptServer::get_language( l )->get_recognized_extensions(&extensions); bool found=false; for(List<String>::Element *E=extensions.front();E;E=E->next()) { if (E->get().nocasecmp_to(extension)==0) { found=true; break; } } if (!found) { path_error_label->set_text(TTR("Invalid extension")); path_error_label->add_color_override("font_color",Color(1,0.4,0.0,0.8)); return; } path_error_label->set_text(TTR("Valid path")); path_error_label->add_color_override("font_color",Color(0,1.0,0.8,0.8)); path_valid=true; }
void godot_icall_RID_Dtor(RID *p_ptr) { ERR_FAIL_NULL(p_ptr); memdelete(p_ptr); }
void Label::regenerate_word_cache() { while (word_cache) { WordCache *current=word_cache; word_cache=current->next; memdelete( current ); } int width=autowrap?get_size().width:get_longest_line_width(); Ref<Font> font = get_font("font"); int current_word_size=0; int word_pos=0; int line_width=0; int space_count=0; int space_width=font->get_char_size(' ').width; int line_spacing = get_constant("line_spacing"); line_count=1; total_char_cache=0; WordCache *last=NULL; for (int i=0;i<text.size()+1;i++) { CharType current=i<text.length()?text[i]:' '; //always a space at the end, so the algo works if (uppercase) current=String::char_uppercase(current); // ranges taken from http://www.unicodemap.org/ // if your language is not well supported, consider helping improve // the unicode support in Godot. bool separatable = (current>=0x2E08 && current<=0xFAFF) || (current>=0xFE30 && current<=0xFE4F); //current>=33 && (current < 65||current >90) && (current<97||current>122) && (current<48||current>57); bool insert_newline=false; int char_width; if (current<33) { if (current_word_size>0) { WordCache *wc = memnew( WordCache ); if (word_cache) { last->next=wc; } else { word_cache=wc; } last=wc; wc->pixel_width=current_word_size; wc->char_pos=word_pos; wc->word_len=i-word_pos; wc->space_count = space_count; current_word_size=0; space_count=0; } if (current=='\n') { insert_newline=true; } else { total_char_cache++; } if (i<text.length() && text[i] == ' ') { total_char_cache--; // do not count spaces if (line_width > 0 || last==NULL || last->char_pos!=WordCache::CHAR_WRAPLINE) { space_count++; line_width+=space_width; }else { space_count=0; } } } else { // latin characters if (current_word_size==0) { word_pos=i; } char_width=font->get_char_size(current).width; current_word_size+=char_width; line_width+=char_width; total_char_cache++; } if ((autowrap && (line_width >= width) && ((last && last->char_pos >= 0) || separatable)) || insert_newline) { if (separatable) { if (current_word_size>0) { WordCache *wc = memnew( WordCache ); if (word_cache) { last->next=wc; } else { word_cache=wc; } last=wc; wc->pixel_width=current_word_size-char_width; wc->char_pos=word_pos; wc->word_len=i-word_pos; wc->space_count = space_count; current_word_size=char_width; space_count=0; word_pos=i; } } WordCache *wc = memnew( WordCache ); if (word_cache) { last->next=wc; } else { word_cache=wc; } last=wc; wc->pixel_width=0; wc->char_pos=insert_newline?WordCache::CHAR_NEWLINE:WordCache::CHAR_WRAPLINE; line_width=current_word_size; line_count++; space_count=0; } } if (!autowrap) { minsize.width=width; if (max_lines_visible > 0 && line_count > max_lines_visible) { minsize.height=(font->get_height() * max_lines_visible) + (line_spacing * (max_lines_visible - 1)); } else { minsize.height=(font->get_height() * line_count)+(line_spacing * (line_count - 1)); } } word_cache_dirty=false; }
void ExportTemplateManager::_install_from_file(const String &p_file, bool p_use_progress) { FileAccess *fa = NULL; zlib_filefunc_def io = zipio_create_io_from_file(&fa); unzFile pkg = unzOpen2(p_file.utf8().get_data(), &io); if (!pkg) { EditorNode::get_singleton()->show_warning(TTR("Can't open export templates zip.")); return; } int ret = unzGoToFirstFile(pkg); int fc = 0; //count them and find version String version; while (ret == UNZ_OK) { unz_file_info info; char fname[16384]; ret = unzGetCurrentFileInfo(pkg, &info, fname, 16384, NULL, 0, NULL, 0); String file = fname; if (file.ends_with("version.txt")) { Vector<uint8_t> data; data.resize(info.uncompressed_size); //read unzOpenCurrentFile(pkg); ret = unzReadCurrentFile(pkg, data.ptrw(), data.size()); unzCloseCurrentFile(pkg); String data_str; data_str.parse_utf8((const char *)data.ptr(), data.size()); data_str = data_str.strip_edges(); // Version number should be of the form major.minor[.patch].status[.module_config] // so it can in theory have 3 or more slices. if (data_str.get_slice_count(".") < 3) { EditorNode::get_singleton()->show_warning(vformat(TTR("Invalid version.txt format inside templates: %s."), data_str)); unzClose(pkg); return; } version = data_str; } fc++; ret = unzGoToNextFile(pkg); } if (version == String()) { EditorNode::get_singleton()->show_warning(TTR("No version.txt found inside templates.")); unzClose(pkg); return; } String template_path = EditorSettings::get_singleton()->get_templates_dir().plus_file(version); DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); Error err = d->make_dir_recursive(template_path); if (err != OK) { EditorNode::get_singleton()->show_warning(TTR("Error creating path for templates:") + "\n" + template_path); unzClose(pkg); return; } memdelete(d); ret = unzGoToFirstFile(pkg); EditorProgress *p = NULL; if (p_use_progress) { p = memnew(EditorProgress("ltask", TTR("Extracting Export Templates"), fc)); } fc = 0; while (ret == UNZ_OK) { //get filename unz_file_info info; char fname[16384]; unzGetCurrentFileInfo(pkg, &info, fname, 16384, NULL, 0, NULL, 0); String file = String(fname).get_file(); Vector<uint8_t> data; data.resize(info.uncompressed_size); //read unzOpenCurrentFile(pkg); unzReadCurrentFile(pkg, data.ptrw(), data.size()); unzCloseCurrentFile(pkg); if (p) { p->step(TTR("Importing:") + " " + file, fc); } FileAccess *f = FileAccess::open(template_path.plus_file(file), FileAccess::WRITE); if (!f) { ret = unzGoToNextFile(pkg); fc++; ERR_CONTINUE(!f); } f->store_buffer(data.ptr(), data.size()); memdelete(f); ret = unzGoToNextFile(pkg); fc++; } if (p) { memdelete(p); } unzClose(pkg); _update_template_list(); }
virtual Vector<uint8_t> custom_export(String& p_path,const Ref<EditorExportPlatform> &p_platform) { //compile gdscript to bytecode if (EditorImportExport::get_singleton()->script_get_action()!=EditorImportExport::SCRIPT_ACTION_NONE) { if (p_path.ends_with(".gd")) { Vector<uint8_t> file = FileAccess::get_file_as_array(p_path); if (file.empty()) return file; String txt; txt.parse_utf8((const char*)file.ptr(),file.size()); file = GDTokenizerBuffer::parse_code_string(txt); if (!file.empty()) { if (EditorImportExport::get_singleton()->script_get_action()==EditorImportExport::SCRIPT_ACTION_ENCRYPT) { String tmp_path=EditorSettings::get_singleton()->get_settings_path().plus_file("tmp/script.gde"); FileAccess *fa = FileAccess::open(tmp_path,FileAccess::WRITE); String skey=EditorImportExport::get_singleton()->script_get_encryption_key().to_lower(); Vector<uint8_t> key; key.resize(32); for(int i=0;i<32;i++) { int v=0; if (i*2<skey.length()) { CharType ct = skey[i*2]; if (ct>='0' && ct<='9') ct=ct-'0'; else if (ct>='a' && ct<='f') ct=10+ct-'a'; v|=ct<<4; } if (i*2+1<skey.length()) { CharType ct = skey[i*2+1]; if (ct>='0' && ct<='9') ct=ct-'0'; else if (ct>='a' && ct<='f') ct=10+ct-'a'; v|=ct; } key[i]=v; } FileAccessEncrypted *fae=memnew(FileAccessEncrypted); Error err = fae->open_and_parse(fa,key,FileAccessEncrypted::MODE_WRITE_AES256); if (err==OK) { fae->store_buffer(file.ptr(),file.size()); p_path=p_path.basename()+".gde"; } memdelete(fae); file=FileAccess::get_file_as_array(tmp_path); return file; } else { p_path=p_path.basename()+".gdc"; return file; } } } } return Vector<uint8_t>(); }
void ResourceImporterTexture::_save_stex(const Ref<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, bool p_detect_3d, bool p_detect_srgb, bool p_force_rgbe, bool p_detect_normal, bool p_force_normal) { 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 if (p_detect_3d) format |= StreamTexture::FORMAT_BIT_DETECT_3D; if (p_detect_srgb) format |= StreamTexture::FORMAT_BIT_DETECT_SRGB; if (p_detect_normal) format |= StreamTexture::FORMAT_BIT_DETECT_NORMAL; if ((p_compress_mode == COMPRESS_LOSSLESS || p_compress_mode == COMPRESS_LOSSY) && p_image->get_format() > Image::FORMAT_RGBA8) { p_compress_mode = COMPRESS_UNCOMPRESSED; //these can't go as lossy } switch (p_compress_mode) { case COMPRESS_LOSSLESS: { Ref<Image> image = p_image->duplicate(); 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: { Ref<Image> image = p_image->duplicate(); 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: { Ref<Image> image = p_image->duplicate(); image->generate_mipmaps(); if (p_force_rgbe && image->get_format() >= Image::FORMAT_R8 && image->get_format() <= Image::FORMAT_RGBE9995) { image->convert(Image::FORMAT_RGBE9995); } else { Image::CompressSource csource = Image::COMPRESS_SOURCE_GENERIC; if (p_force_normal) { csource = Image::COMPRESS_SOURCE_NORMAL; } else if (p_texture_flags & VS::TEXTURE_FLAG_CONVERT_TO_LINEAR) { csource = Image::COMPRESS_SOURCE_SRGB; } image->compress(p_vram_compression, csource, p_lossy_quality); } 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: { Ref<Image> image = p_image->duplicate(); 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); }
ResourceImporterTexture::~ResourceImporterTexture() { memdelete(mutex); }
void OS_Android::delete_main_loop() { memdelete( main_loop ); }
void OS_Android::finalize() { memdelete(input); }
bool OrphanResourcesDialog::_fill_owners(EditorFileSystemDirectory *efsd, HashMap<String, int> &refs, TreeItem *p_parent) { if (!efsd) return false; bool has_children = false; for (int i = 0; i < efsd->get_subdir_count(); i++) { TreeItem *dir_item = NULL; if (p_parent) { dir_item = files->create_item(p_parent); dir_item->set_text(0, efsd->get_subdir(i)->get_name()); dir_item->set_icon(0, get_icon("folder", "FileDialog")); } bool children = _fill_owners(efsd->get_subdir(i), refs, dir_item); if (p_parent) { if (!children) { memdelete(dir_item); } else { has_children = true; } } } for (int i = 0; i < efsd->get_file_count(); i++) { if (!p_parent) { Vector<String> deps = efsd->get_file_deps(i); for (int j = 0; j < deps.size(); j++) { if (!refs.has(deps[j])) { refs[deps[j]] = 1; } } } else { String path = efsd->get_file_path(i); if (!refs.has(path)) { TreeItem *ti = files->create_item(p_parent); ti->set_cell_mode(0, TreeItem::CELL_MODE_CHECK); ti->set_text(0, efsd->get_file(i)); ti->set_editable(0, true); String type = efsd->get_file_type(i); Ref<Texture> icon = EditorNode::get_singleton()->get_class_icon(type); ti->set_icon(0, icon); int ds = efsd->get_file_deps(i).size(); ti->set_text(1, itos(ds)); if (ds) { ti->add_button(1, get_icon("GuiVisibilityVisible", "EditorIcons")); } ti->set_metadata(0, path); has_children = true; } } } return has_children; }
void unregister_core_types() { memdelete( _resource_loader ); memdelete( _resource_saver ); memdelete( _os); memdelete( _marshalls ); memdelete( _geometry ); #ifdef XML_ENABLED if (resource_saver_xml) memdelete(resource_saver_xml); if (resource_loader_xml) memdelete(resource_loader_xml); #endif if (resource_saver_binary) memdelete(resource_saver_binary); if (resource_loader_binary) memdelete(resource_loader_binary); memdelete( resource_format_po ); if (ip) memdelete(ip); ObjectDB::cleanup(); unregister_variant_methods(); ObjectTypeDB::cleanup(); ResourceCache::clear(); CoreStringNames::free(); StringName::cleanup(); if (_global_mutex) { memdelete(_global_mutex); _global_mutex=NULL; //still needed at a few places }; }
ThreadSafe::~ThreadSafe() { if (mutex) memdelete( mutex ); }
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(); if (current_mtime != p_dir->modified_time) { updated_dir = true; p_dir->modified_time = current_mtime; //ooooops, dir changed, see what's going on //first mark everything as veryfied for (int i = 0; i < p_dir->files.size(); i++) { p_dir->files[i]->verified = false; } for (int i = 0; i < p_dir->subdirs.size(); i++) { p_dir->get_subdir(i)->verified = false; } //then scan files and directories and check what's different DirAccess *da = DirAccess::create(DirAccess::ACCESS_RESOURCES); da->change_dir(cd); da->list_dir_begin(); while (true) { bool isdir; String f = da->get_next(&isdir); if (f == "") break; if (isdir) { if (f.begins_with(".")) //ignore hidden and . / .. continue; int idx = p_dir->find_dir_index(f); if (idx == -1) { if (FileAccess::exists(cd.plus_file(f).plus_file("project.godot"))) // skip if another project inside this continue; if (FileAccess::exists(cd.plus_file(f).plus_file(".gdignore"))) // skip if another project inside this continue; EditorFileSystemDirectory *efd = memnew(EditorFileSystemDirectory); efd->parent = p_dir; efd->name = f; DirAccess *d = DirAccess::create(DirAccess::ACCESS_RESOURCES); d->change_dir(cd.plus_file(f)); _scan_new_dir(efd, d, p_progress.get_sub(1, 1)); memdelete(d); ItemAction ia; ia.action = ItemAction::ACTION_DIR_ADD; ia.dir = p_dir; ia.file = f; ia.new_dir = efd; scan_actions.push_back(ia); } else { p_dir->subdirs[idx]->verified = true; } } else { String ext = f.get_extension().to_lower(); if (!valid_extensions.has(ext)) continue; //invalid int idx = p_dir->find_file_index(f); if (idx == -1) { //never seen this file, add actition to add it EditorFileSystemDirectory::FileInfo *fi = memnew(EditorFileSystemDirectory::FileInfo); fi->file = f; String path = cd.plus_file(fi->file); fi->modified_time = FileAccess::get_modified_time(path); fi->import_modified_time = 0; fi->type = ResourceLoader::get_resource_type(path); fi->import_valid = ResourceLoader::is_import_valid(path); { ItemAction ia; ia.action = ItemAction::ACTION_FILE_ADD; ia.dir = p_dir; ia.file = f; ia.new_file = fi; scan_actions.push_back(ia); } if (import_extensions.has(ext)) { //if it can be imported, and it was added, it needs to be reimported ItemAction ia; ia.action = ItemAction::ACTION_FILE_REIMPORT; ia.dir = p_dir; ia.file = f; scan_actions.push_back(ia); } } else { p_dir->files[idx]->verified = true; } } } da->list_dir_end(); memdelete(da); } for (int i = 0; i < p_dir->files.size(); i++) { if (updated_dir && !p_dir->files[i]->verified) { //this file was removed, add action to remove it ItemAction ia; ia.action = ItemAction::ACTION_FILE_REMOVE; ia.dir = p_dir; ia.file = p_dir->files[i]->file; scan_actions.push_back(ia); continue; } 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) { reimport = true; //it was modified, must be reimported. } else if (!FileAccess::exists(path + ".import")) { 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) { reimport = true; } else if (!_check_missing_imported_files(path)) { 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); } } } for (int i = 0; i < p_dir->subdirs.size(); i++) { if (updated_dir && !p_dir->subdirs[i]->verified) { //this directory was removed, add action to remove it ItemAction ia; ia.action = ItemAction::ACTION_DIR_REMOVE; ia.dir = p_dir->subdirs[i]; scan_actions.push_back(ia); continue; } _scan_fs_changes(p_dir->get_subdir(i), p_progress); } }
void unregister_theora_types() { memdelete( theora_stream_loader ); }
void EditorFileSystem::_notification(int p_what) { switch (p_what) { case NOTIFICATION_ENTER_TREE: { call_deferred("scan"); //this should happen after every editor node entered the tree } break; case NOTIFICATION_EXIT_TREE: { if (use_threads && thread) { //abort thread if in progress abort_scan = true; while (scanning) { OS::get_singleton()->delay_usec(1000); } Thread::wait_to_finish(thread); memdelete(thread); thread = NULL; WARN_PRINTS("Scan thread aborted..."); set_process(false); } if (filesystem) memdelete(filesystem); if (new_filesystem) memdelete(new_filesystem); filesystem = NULL; new_filesystem = NULL; } break; case NOTIFICATION_PROCESS: { if (use_threads) { if (scanning_changes) { if (scanning_changes_done) { scanning_changes = false; set_process(false); Thread::wait_to_finish(thread_sources); memdelete(thread_sources); thread_sources = NULL; if (_update_scan_actions()) emit_signal("filesystem_changed"); emit_signal("sources_changed", sources_changed.size() > 0); } } else if (!scanning) { set_process(false); if (filesystem) memdelete(filesystem); filesystem = new_filesystem; new_filesystem = NULL; Thread::wait_to_finish(thread); memdelete(thread); thread = NULL; _update_scan_actions(); emit_signal("filesystem_changed"); emit_signal("sources_changed", sources_changed.size() > 0); } } } break; } }
HTTPRequest::~HTTPRequest() { if (file) memdelete(file); }
void ExportTemplateManager::_update_template_list() { while (current_hb->get_child_count()) { memdelete(current_hb->get_child(0)); } while (installed_vb->get_child_count()) { memdelete(installed_vb->get_child(0)); } DirAccess *d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); Error err = d->change_dir(EditorSettings::get_singleton()->get_templates_dir()); d->list_dir_begin(); Set<String> templates; if (err == OK) { bool isdir; String c = d->get_next(&isdir); while (c != String()) { if (isdir && !c.begins_with(".")) { templates.insert(c); } c = d->get_next(&isdir); } } d->list_dir_end(); memdelete(d); String current_version = VERSION_FULL_CONFIG; Label *current = memnew(Label); current->set_h_size_flags(SIZE_EXPAND_FILL); current_hb->add_child(current); if (templates.has(current_version)) { current->add_color_override("font_color", get_color("success_color", "Editor")); Button *redownload = memnew(Button); redownload->set_text(TTR("Re-Download")); current_hb->add_child(redownload); redownload->connect("pressed", this, "_download_template", varray(current_version)); Button *uninstall = memnew(Button); uninstall->set_text(TTR("Uninstall")); current_hb->add_child(uninstall); current->set_text(current_version + " " + TTR("(Installed)")); uninstall->connect("pressed", this, "_uninstall_template", varray(current_version)); } else { current->add_color_override("font_color", get_color("error_color", "Editor")); Button *redownload = memnew(Button); redownload->set_text(TTR("Download")); redownload->connect("pressed", this, "_download_template", varray(current_version)); current_hb->add_child(redownload); current->set_text(current_version + " " + TTR("(Missing)")); } for (Set<String>::Element *E = templates.back(); E; E = E->prev()) { HBoxContainer *hbc = memnew(HBoxContainer); Label *version = memnew(Label); version->set_modulate(get_color("disabled_font_color", "Editor")); String text = E->get(); if (text == current_version) { text += " " + TTR("(Current)"); } version->set_text(text); version->set_h_size_flags(SIZE_EXPAND_FILL); hbc->add_child(version); Button *uninstall = memnew(Button); uninstall->set_text(TTR("Uninstall")); hbc->add_child(uninstall); uninstall->connect("pressed", this, "_uninstall_template", varray(E->get())); installed_vb->add_child(hbc); } }
void EditorFileSystem::update_file(const String &p_file) { EditorFileSystemDirectory *fs = NULL; int cpos = -1; if (!_find_file(p_file, &fs, cpos)) { if (!fs) return; } if (!FileAccess::exists(p_file)) { //was removed _delete_internal_files(p_file); memdelete(fs->files[cpos]); fs->files.remove(cpos); call_deferred("emit_signal", "filesystem_changed"); //update later return; } String type = ResourceLoader::get_resource_type(p_file); if (cpos == -1) { //the file did not exist, it was added late_added_files.insert(p_file); //remember that it was added. This mean it will be scanned and imported on editor restart int idx = 0; for (int i = 0; i < fs->files.size(); i++) { if (p_file < fs->files[i]->file) break; idx++; } EditorFileSystemDirectory::FileInfo *fi = memnew(EditorFileSystemDirectory::FileInfo); fi->file = p_file.get_file(); fi->import_modified_time = 0; fi->import_valid = ResourceLoader::is_import_valid(p_file); if (idx == fs->files.size()) { fs->files.push_back(fi); } else { fs->files.insert(idx, fi); } cpos = idx; } else { //the file exists and it was updated, and was not added in this step. //this means we must force upon next restart to scan it again, to get proper type and dependencies late_update_files.insert(p_file); _save_late_updated_files(); //files need to be updated in the re-scan } fs->files[cpos]->type = type; fs->files[cpos]->modified_time = FileAccess::get_modified_time(p_file); fs->files[cpos]->deps = _get_dependencies(p_file); fs->files[cpos]->import_valid = ResourceLoader::is_import_valid(p_file); call_deferred("emit_signal", "filesystem_changed"); //update later }
ScriptDebuggerRemote::~ScriptDebuggerRemote() { remove_print_handler(&phl); remove_error_handler(&eh); memdelete(mutex); }
void EditorFileSystem::_reimport_file(const String &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")) { //use existing 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"); } } else { late_added_files.insert(p_file); //imported files do not call update_file(), but just in case.. } Ref<ResourceImporter> importer; bool load_default = false; //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()); load_default = true; 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; } } if (load_default && ProjectSettings::get_singleton()->has_setting("importer_defaults/" + importer->get_importer_name())) { //use defaults if exist Dictionary d = ProjectSettings::get_singleton()->get("importer_defaults/" + importer->get_importer_name()); List<Variant> v; d.get_key_list(&v); for (List<Variant>::Element *E = v.front(); E; E = E->next()) { params[E->get()] = d[E->get()]; } } //finally, perform import!! String base_path = ResourceFormatImporter::get_singleton()->get_import_base_path(p_file); List<String> import_variants; List<String> gen_files; Error err = importer->import(p_file, base_path, params, &import_variants, &gen_files); if (err != OK) { ERR_PRINTS("Error importing: " + p_file); } //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() + "\""); if (importer->get_resource_type() != "") { f->store_line("type=\"" + importer->get_resource_type() + "\""); } if (err == OK) { if (importer->get_save_extension() == "") { //no path } else if (import_variants.size()) { //import with variants for (List<String>::Element *E = import_variants.front(); E; E = E->next()) { String path = base_path.c_escape() + "." + E->get() + "." + importer->get_save_extension(); f->store_line("path." + E->get() + "=\"" + path + "\""); } } else { f->store_line("path=\"" + base_path + "." + importer->get_save_extension() + "\""); } } else { f->store_line("valid=false"); } f->store_line(""); if (gen_files.size()) { f->store_line("[gen]"); Array genf; for (List<String>::Element *E = gen_files.front(); E; E = E->next()) { genf.push_back(E->get()); } String value; VariantWriter::write_to_string(genf, value); f->store_line("files=" + value); f->store_line(""); } f->store_line("[params]"); f->store_line(""); //store options in provided order, to avoid file changing. Order is also important because first match is accepted first. 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); } f->close(); 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"); fs->files[cpos]->deps = _get_dependencies(p_file); fs->files[cpos]->type = importer->get_resource_type(); fs->files[cpos]->import_valid = ResourceLoader::is_import_valid(p_file); //if file is currently up, maybe the source it was loaded from changed, so import math must be updated for it //to reload properly if (ResourceCache::has(p_file)) { Resource *r = ResourceCache::get(p_file); if (r->get_import_path() != String()) { String dst_path = ResourceFormatImporter::get_singleton()->get_internal_resource_path(p_file); r->set_import_path(dst_path); r->set_import_last_modified_time(0); } } EditorResourcePreview::get_singleton()->check_for_invalidation(p_file); }
void VisualShaderEditor::_update_graph() { if (updating) return; if (visual_shader.is_null()) return; graph->set_scroll_ofs(visual_shader->get_graph_offset() * EDSCALE); VisualShader::Type type = VisualShader::Type(edit_type->get_selected()); graph->clear_connections(); //erase all nodes for (int i = 0; i < graph->get_child_count(); i++) { if (Object::cast_to<GraphNode>(graph->get_child(i))) { memdelete(graph->get_child(i)); i--; } } static const Color type_color[3] = { Color::html("#61daf4"), Color::html("#d67dee"), Color::html("#f6a86e") }; List<VisualShader::Connection> connections; visual_shader->get_node_connections(type, &connections); Ref<StyleBoxEmpty> label_style = make_empty_stylebox(2, 1, 2, 1); Vector<int> nodes = visual_shader->get_node_list(type); for (int n_i = 0; n_i < nodes.size(); n_i++) { Vector2 position = visual_shader->get_node_position(type, nodes[n_i]); Ref<VisualShaderNode> vsnode = visual_shader->get_node(type, nodes[n_i]); GraphNode *node = memnew(GraphNode); graph->add_child(node); /*if (!vsnode->is_connected("changed", this, "_node_changed")) { vsnode->connect("changed", this, "_node_changed", varray(vsnode->get_instance_id()), CONNECT_DEFERRED); }*/ node->set_offset(position); node->set_title(vsnode->get_caption()); node->set_name(itos(nodes[n_i])); if (nodes[n_i] >= 2) { node->set_show_close_button(true); node->connect("close_request", this, "_delete_request", varray(nodes[n_i]), CONNECT_DEFERRED); } node->connect("dragged", this, "_node_dragged", varray(nodes[n_i])); Control *custom_editor = NULL; int port_offset = 0; Ref<VisualShaderNodeUniform> uniform = vsnode; if (uniform.is_valid()) { LineEdit *uniform_name = memnew(LineEdit); uniform_name->set_text(uniform->get_uniform_name()); node->add_child(uniform_name); uniform_name->connect("text_entered", this, "_line_edit_changed", varray(uniform_name, nodes[n_i])); uniform_name->connect("focus_exited", this, "_line_edit_focus_out", varray(uniform_name, nodes[n_i])); if (vsnode->get_input_port_count() == 0 && vsnode->get_output_port_count() == 1 && vsnode->get_output_port_name(0) == "") { //shortcut VisualShaderNode::PortType port_right = vsnode->get_output_port_type(0); node->set_slot(0, false, VisualShaderNode::PORT_TYPE_SCALAR, Color(), true, port_right, type_color[port_right]); continue; } port_offset++; } for (int i = 0; i < plugins.size(); i++) { custom_editor = plugins.write[i]->create_editor(vsnode); if (custom_editor) { break; } } if (custom_editor && vsnode->get_output_port_count() > 0 && vsnode->get_output_port_name(0) == "" && (vsnode->get_input_port_count() == 0 || vsnode->get_input_port_name(0) == "")) { //will be embedded in first port } else if (custom_editor) { port_offset++; node->add_child(custom_editor); custom_editor = NULL; } for (int i = 0; i < MAX(vsnode->get_input_port_count(), vsnode->get_output_port_count()); i++) { if (vsnode->is_port_separator(i)) { node->add_child(memnew(HSeparator)); port_offset++; } bool valid_left = i < vsnode->get_input_port_count(); VisualShaderNode::PortType port_left = VisualShaderNode::PORT_TYPE_SCALAR; bool port_left_used = false; String name_left; if (valid_left) { name_left = vsnode->get_input_port_name(i); port_left = vsnode->get_input_port_type(i); for (List<VisualShader::Connection>::Element *E = connections.front(); E; E = E->next()) { if (E->get().to_node == nodes[n_i] && E->get().to_port == i) { port_left_used = true; } } } bool valid_right = i < vsnode->get_output_port_count(); VisualShaderNode::PortType port_right = VisualShaderNode::PORT_TYPE_SCALAR; String name_right; if (valid_right) { name_right = vsnode->get_output_port_name(i); port_right = vsnode->get_output_port_type(i); } HBoxContainer *hb = memnew(HBoxContainer); Variant default_value; if (valid_left && !port_left_used) { default_value = vsnode->get_input_port_default_value(i); } if (default_value.get_type() != Variant::NIL) { // only a label Button *button = memnew(Button); hb->add_child(button); button->connect("pressed", this, "_edit_port_default_input", varray(button, nodes[n_i], i)); switch (default_value.get_type()) { case Variant::COLOR: { button->set_custom_minimum_size(Size2(30, 0) * EDSCALE); button->connect("draw", this, "_draw_color_over_button", varray(button, default_value)); } break; case Variant::INT: case Variant::REAL: { button->set_text(String::num(default_value, 4)); } break; case Variant::VECTOR3: { Vector3 v = default_value; button->set_text(String::num(v.x, 3) + "," + String::num(v.y, 3) + "," + String::num(v.z, 3)); } break; default: {} } } if (i == 0 && custom_editor) { hb->add_child(custom_editor); custom_editor->set_h_size_flags(SIZE_EXPAND_FILL); } else { if (valid_left) { Label *label = memnew(Label); label->set_text(name_left); label->add_style_override("normal", label_style); //more compact hb->add_child(label); } hb->add_spacer(); if (valid_right) { Label *label = memnew(Label); label->set_text(name_right); label->set_align(Label::ALIGN_RIGHT); label->add_style_override("normal", label_style); //more compact hb->add_child(label); } } if (valid_right && edit_type->get_selected() == VisualShader::TYPE_FRAGMENT) { TextureButton *preview = memnew(TextureButton); preview->set_toggle_mode(true); preview->set_normal_texture(get_icon("GuiVisibilityHidden", "EditorIcons")); preview->set_pressed_texture(get_icon("GuiVisibilityVisible", "EditorIcons")); preview->set_v_size_flags(SIZE_SHRINK_CENTER); if (vsnode->get_output_port_for_preview() == i) { preview->set_pressed(true); } preview->connect("pressed", this, "_preview_select_port", varray(nodes[n_i], i), CONNECT_DEFERRED); hb->add_child(preview); } node->add_child(hb); node->set_slot(i + port_offset, valid_left, port_left, type_color[port_left], valid_right, port_right, type_color[port_right]); } if (vsnode->get_output_port_for_preview() >= 0) { VisualShaderNodePortPreview *port_preview = memnew(VisualShaderNodePortPreview); port_preview->setup(visual_shader, type, nodes[n_i], vsnode->get_output_port_for_preview()); port_preview->set_h_size_flags(SIZE_SHRINK_CENTER); node->add_child(port_preview); } String error = vsnode->get_warning(visual_shader->get_mode(), type); if (error != String()) { Label *error_label = memnew(Label); error_label->add_color_override("font_color", get_color("error_color", "Editor")); error_label->set_text(error); node->add_child(error_label); } } for (List<VisualShader::Connection>::Element *E = connections.front(); E; E = E->next()) { int from = E->get().from_node; int from_idx = E->get().from_port; int to = E->get().to_node; int to_idx = E->get().to_port; graph->connect_node(itos(from), from_idx, itos(to), to_idx); } }
void EditorFileSystem::_scan_filesystem() { ERR_FAIL_COND(!scanning || new_filesystem); //read .fscache String cpath; sources_changed.clear(); file_cache.clear(); String project = ProjectSettings::get_singleton()->get_resource_path(); String fscache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_cache3"); FileAccess *f = FileAccess::open(fscache, FileAccess::READ); if (f) { //read the disk cache while (!f->eof_reached()) { String l = f->get_line().strip_edges(); if (l == String()) continue; if (l.begins_with("::")) { Vector<String> split = l.split("::"); ERR_CONTINUE(split.size() != 3); String name = split[1]; cpath = name; } else { Vector<String> split = l.split("::"); ERR_CONTINUE(split.size() != 6); String name = split[0]; String file; file = name; name = cpath.plus_file(name); FileCache fc; fc.type = split[1]; fc.modification_time = split[2].to_int64(); fc.import_modification_time = split[3].to_int64(); fc.import_valid = split[4].to_int64() != 0; String deps = split[5].strip_edges(); if (deps.length()) { Vector<String> dp = deps.split("<>"); for (int i = 0; i < dp.size(); i++) { String path = dp[i]; fc.deps.push_back(path); } } file_cache[name] = fc; } } f->close(); memdelete(f); } String update_cache = EditorSettings::get_singleton()->get_project_settings_path().plus_file("filesystem_update3"); if (FileAccess::exists(update_cache)) { { FileAccessRef f = FileAccess::open(update_cache, FileAccess::READ); String l = f->get_line().strip_edges(); while (l != String()) { file_cache.erase(l); //erase cache for this, so it gets updated l = f->get_line().strip_edges(); } } DirAccessRef d = DirAccess::create(DirAccess::ACCESS_FILESYSTEM); d->remove(update_cache); //bye bye update cache } EditorProgressBG scan_progress("efs", "ScanFS", 1000); ScanProgress sp; sp.low = 0; sp.hi = 1; sp.progress = &scan_progress; new_filesystem = memnew(EditorFileSystemDirectory); new_filesystem->parent = NULL; DirAccess *d = DirAccess::create(DirAccess::ACCESS_RESOURCES); d->change_dir("res://"); _scan_new_dir(new_filesystem, d, sp); file_cache.clear(); //clear caches, no longer needed memdelete(d); f = FileAccess::open(fscache, FileAccess::WRITE); _save_filesystem_cache(new_filesystem, f); f->close(); memdelete(f); scanning = false; }
void DocDump::dump(const String &p_file) { List<StringName> class_list; ClassDB::get_class_list(&class_list); class_list.sort_custom<StringName::AlphCompare>(); FileAccess *f = FileAccess::open(p_file, FileAccess::WRITE); _write_string(f, 0, "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"); _write_string(f, 0, "<doc version=\"" + String(VERSION_MKSTRING) + "\" name=\"Engine Types\">"); while (class_list.size()) { String name = class_list.front()->get(); String header = "<class name=\"" + name + "\""; String inherits = ClassDB::get_parent_class(name); if (inherits != "") header += " inherits=\"" + inherits + "\""; String category = ClassDB::get_category(name); if (category == "") category = "Core"; header += " category=\"" + category + "\""; header += ">"; _write_string(f, 0, header); _write_string(f, 1, "<brief_description>"); _write_string(f, 1, "</brief_description>"); _write_string(f, 1, "<description>"); _write_string(f, 1, "</description>"); _write_string(f, 1, "<methods>"); List<MethodInfo> method_list; ClassDB::get_method_list(name, &method_list, true); method_list.sort(); for (List<MethodInfo>::Element *E = method_list.front(); E; E = E->next()) { if (E->get().name == "" || E->get().name[0] == '_') continue; //hiden MethodBind *m = ClassDB::get_method(name, E->get().name); String qualifiers; if (E->get().flags & METHOD_FLAG_CONST) qualifiers += "qualifiers=\"const\""; _write_string(f, 2, "<method name=\"" + _escape_string(E->get().name) + "\" " + qualifiers + " >"); for (int i = -1; i < E->get().arguments.size(); i++) { PropertyInfo arginfo; if (i == -1) { arginfo = E->get().return_val; String type_name = (arginfo.hint == PROPERTY_HINT_RESOURCE_TYPE) ? arginfo.hint_string : Variant::get_type_name(arginfo.type); if (arginfo.type == Variant::NIL) continue; _write_string(f, 3, "<return type=\"" + type_name + "\">"); } else { arginfo = E->get().arguments[i]; String type_name; if (arginfo.hint == PROPERTY_HINT_RESOURCE_TYPE) type_name = arginfo.hint_string; else if (arginfo.type == Variant::NIL) type_name = "var"; else type_name = Variant::get_type_name(arginfo.type); if (m && m->has_default_argument(i)) { Variant default_arg = m->get_default_argument(i); String default_arg_text = String(_escape_string(m->get_default_argument(i))); switch (default_arg.get_type()) { case Variant::NIL: default_arg_text = "NULL"; break; // atomic types case Variant::BOOL: if (bool(default_arg)) default_arg_text = "true"; else default_arg_text = "false"; break; case Variant::INT: case Variant::REAL: //keep it break; case Variant::STRING: case Variant::NODE_PATH: default_arg_text = "\"" + default_arg_text + "\""; break; case Variant::TRANSFORM: if (default_arg.operator Transform() == Transform()) { default_arg_text = ""; } default_arg_text = Variant::get_type_name(default_arg.get_type()) + "(" + default_arg_text + ")"; break; case Variant::VECTOR2: case Variant::RECT2: case Variant::VECTOR3: case Variant::PLANE: case Variant::QUAT: case Variant::RECT3: case Variant::BASIS: case Variant::COLOR: case Variant::POOL_BYTE_ARRAY: case Variant::POOL_INT_ARRAY: case Variant::POOL_REAL_ARRAY: case Variant::POOL_STRING_ARRAY: case Variant::POOL_VECTOR3_ARRAY: case Variant::POOL_COLOR_ARRAY: default_arg_text = Variant::get_type_name(default_arg.get_type()) + "(" + default_arg_text + ")"; break; case Variant::OBJECT: case Variant::DICTIONARY: // 20 case Variant::ARRAY: case Variant::_RID: default: {} } _write_string(f, 3, "<argument index=\"" + itos(i) + "\" name=\"" + _escape_string(arginfo.name) + "\" type=\"" + type_name + "\" default=\"" + _escape_string(default_arg_text) + "\">"); } else _write_string(f, 3, "<argument index=\"" + itos(i) + "\" name=\"" + arginfo.name + "\" type=\"" + type_name + "\">"); } String hint; switch (arginfo.hint) { case PROPERTY_HINT_DIR: hint = "A directory."; break; case PROPERTY_HINT_RANGE: hint = "Range - min: " + arginfo.hint_string.get_slice(",", 0) + " max: " + arginfo.hint_string.get_slice(",", 1) + " step: " + arginfo.hint_string.get_slice(",", 2); break; case PROPERTY_HINT_ENUM: hint = "Values: "; for (int j = 0; j < arginfo.hint_string.get_slice_count(","); j++) { if (j > 0) hint += ", "; hint += arginfo.hint_string.get_slice(",", j) + "=" + itos(j); } break; case PROPERTY_HINT_LENGTH: hint = "Length: " + arginfo.hint_string; break; case PROPERTY_HINT_FLAGS: hint = "Values: "; for (int j = 0; j < arginfo.hint_string.get_slice_count(","); j++) { if (j > 0) hint += ", "; hint += arginfo.hint_string.get_slice(",", j) + "=" + itos(1 << j); } break; case PROPERTY_HINT_FILE: hint = "A file:"; break; default: {} //case PROPERTY_HINT_RESOURCE_TYPE: hint="Type: "+arginfo.hint_string; break; }; if (hint != "") _write_string(f, 4, hint); _write_string(f, 3, (i == -1) ? "</return>" : "</argument>"); } _write_string(f, 3, "<description>"); _write_string(f, 3, "</description>"); _write_string(f, 2, "</method>"); } _write_string(f, 1, "</methods>"); List<MethodInfo> signal_list; ClassDB::get_signal_list(name, &signal_list, true); if (signal_list.size()) { _write_string(f, 1, "<signals>"); for (List<MethodInfo>::Element *EV = signal_list.front(); EV; EV = EV->next()) { _write_string(f, 2, "<signal name=\"" + EV->get().name + "\">"); for (int i = 0; i < EV->get().arguments.size(); i++) { PropertyInfo arginfo = EV->get().arguments[i]; _write_string(f, 3, "<argument index=\"" + itos(i) + "\" name=\"" + arginfo.name + "\" type=\"" + Variant::get_type_name(arginfo.type) + "\">"); _write_string(f, 3, "</argument>"); } _write_string(f, 3, "<description>"); _write_string(f, 3, "</description>"); _write_string(f, 2, "</signal>"); } _write_string(f, 1, "</signals>"); } _write_string(f, 1, "<constants>"); List<String> constant_list; ClassDB::get_integer_constant_list(name, &constant_list, true); /* constants are sorted in a special way */ List<_ConstantSort> constant_sort; for (List<String>::Element *E = constant_list.front(); E; E = E->next()) { _ConstantSort cs; cs.name = E->get(); cs.value = ClassDB::get_integer_constant(name, E->get()); constant_sort.push_back(cs); } constant_sort.sort(); for (List<_ConstantSort>::Element *E = constant_sort.front(); E; E = E->next()) { _write_string(f, 2, "<constant name=\"" + E->get().name + "\" value=\"" + itos(E->get().value) + "\">"); _write_string(f, 2, "</constant>"); } _write_string(f, 1, "</constants>"); _write_string(f, 0, "</class>"); class_list.erase(name); } _write_string(f, 0, "</doc>"); f->close(); memdelete(f); }
bool EditorFileSystem::_update_scan_actions() { sources_changed.clear(); bool fs_changed = false; Vector<String> reimports; for (List<ItemAction>::Element *E = scan_actions.front(); E; E = E->next()) { ItemAction &ia = E->get(); switch (ia.action) { case ItemAction::ACTION_NONE: { } break; case ItemAction::ACTION_DIR_ADD: { int idx = 0; for (int i = 0; i < ia.dir->subdirs.size(); i++) { if (ia.new_dir->name < ia.dir->subdirs[i]->name) break; idx++; } if (idx == ia.dir->subdirs.size()) { ia.dir->subdirs.push_back(ia.new_dir); } else { ia.dir->subdirs.insert(idx, ia.new_dir); } fs_changed = true; } break; case ItemAction::ACTION_DIR_REMOVE: { ERR_CONTINUE(!ia.dir->parent); ia.dir->parent->subdirs.erase(ia.dir); memdelete(ia.dir); fs_changed = true; } break; case ItemAction::ACTION_FILE_ADD: { int idx = 0; for (int i = 0; i < ia.dir->files.size(); i++) { if (ia.new_file->file < ia.dir->files[i]->file) break; idx++; } if (idx == ia.dir->files.size()) { ia.dir->files.push_back(ia.new_file); } else { ia.dir->files.insert(idx, ia.new_file); } fs_changed = true; } break; case ItemAction::ACTION_FILE_REMOVE: { int idx = ia.dir->find_file_index(ia.file); ERR_CONTINUE(idx == -1); _delete_internal_files(ia.dir->files[idx]->file); memdelete(ia.dir->files[idx]); ia.dir->files.remove(idx); fs_changed = true; } break; 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); reimports.push_back(full_path); fs_changed = true; } break; } } if (reimports.size()) { reimport_files(reimports); } scan_actions.clear(); return fs_changed; }
MethodBind* ObjectTypeDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind , const MethodDefinition &method_name, const Variant **p_defs, int p_defcount) { StringName mdname=method_name.name; #else MethodBind* ObjectTypeDB::bind_methodfi(uint32_t p_flags, MethodBind *p_bind , const char *method_name, const Variant **p_defs, int p_defcount) { StringName mdname=StaticCString::create(method_name); #endif StringName rettype; if (mdname.operator String().find(":")!=-1) { rettype = mdname.operator String().get_slice(":",1); mdname = mdname.operator String().get_slice(":",0); } OBJTYPE_LOCK; ERR_FAIL_COND_V(!p_bind,NULL); p_bind->set_name(mdname); String instance_type=p_bind->get_instance_type(); TypeInfo *type=types.getptr(instance_type); if (!type) { print_line("couldn't bind method "+mdname+" for instance: "+instance_type); memdelete(p_bind); ERR_FAIL_COND_V(!type,NULL); } if (type->method_map.has(mdname)) { memdelete(p_bind); // overloading not supported ERR_EXPLAIN("Method already bound: "+instance_type+"::"+mdname); ERR_FAIL_V(NULL); } #ifdef DEBUG_METHODS_ENABLED p_bind->set_argument_names(method_name.args); p_bind->set_return_type(rettype); type->method_order.push_back(mdname); #endif type->method_map[mdname]=p_bind; Vector<Variant> defvals; #define PARSE_DEFVAL(m_defval)\ if (d##m_defval.used) defvals.insert(0,d##m_defval.val);\ else goto set_defvals; defvals.resize(p_defcount); for(int i=0;i<p_defcount;i++) { defvals[i]=*p_defs[p_defcount-i-1]; } set_defvals: p_bind->set_default_arguments(defvals); p_bind->set_hint_flags(p_flags); #undef PARSE_DEFVAL return p_bind; }
bool EditorFileSystem::_check_missing_imported_files(const String &p_path) { if (!reimport_on_missing_imported_files) return true; Error err; FileAccess *f = FileAccess::open(p_path + ".import", FileAccess::READ, &err); if (!f) { print_line("could not open import for " + p_path); return false; } VariantParser::StreamFile stream; stream.f = f; String assign; Variant value; VariantParser::Tag next_tag; int lines = 0; String error_text; List<String> to_check; while (true) { assign = Variant(); next_tag.fields.clear(); next_tag.name = String(); err = VariantParser::parse_tag_assign_eof(&stream, lines, error_text, next_tag, assign, value, NULL, true); if (err == ERR_FILE_EOF) { memdelete(f); return OK; } else if (err != OK) { ERR_PRINTS("ResourceFormatImporter::load - " + p_path + ".import:" + itos(lines) + " error: " + error_text); memdelete(f); return false; } if (assign != String()) { if (assign.begins_with("path")) { to_check.push_back(value); } else if (assign == "files") { Array fa = value; for (int i = 0; i < fa.size(); i++) { to_check.push_back(fa[i]); } } } else if (next_tag.name != "remap" && next_tag.name != "deps") { break; } } memdelete(f); for (List<String>::Element *E = to_check.front(); E; E = E->next()) { if (!FileAccess::exists(E->get())) { return false; } } return true; }
RES ResourceFormatLoaderTheme::load(const String &p_path,const String& p_original_path) { Error err; FileAccess *f = FileAccess::open(p_path,FileAccess::READ,&err); ERR_EXPLAIN("Unable to open theme file: "+p_path); ERR_FAIL_COND_V(err,RES()); String base_path = p_path.get_base_dir(); Ref<Theme> theme( memnew( Theme ) ); Map<StringName,Variant> library; bool reading_library=false; int line=0; while(!f->eof_reached()) { String l = f->get_line().strip_edges(); line++; int comment = l.find(";"); if (comment!=-1) l=l.substr(0,comment); if (l=="") continue; if (l.begins_with("[")) { if (l=="[library]") { reading_library=true; } else if (l=="[theme]") { reading_library=false; } else { memdelete(f); ERR_EXPLAIN(p_path+":"+itos(line)+": Unknown section type: '"+l+"'."); ERR_FAIL_V(RES()); } continue; } int eqpos = l.find("="); if (eqpos==-1) { memdelete(f); ERR_EXPLAIN(p_path+":"+itos(line)+": Expected '='."); ERR_FAIL_V(RES()); } String right=l.substr(eqpos+1,l.length()).strip_edges(); if (right=="") { memdelete(f); ERR_EXPLAIN(p_path+":"+itos(line)+": Expected value after '='."); ERR_FAIL_V(RES()); } Variant value; if (right.is_valid_integer()) { //is number value = right.to_int(); } else if (right.is_valid_html_color()) { //is html color value = Color::html(right); } else if (right.begins_with("@")) { //reference String reference = right.substr(1,right.length()); if (!library.has(reference)) { memdelete(f); ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid reference to '"+reference+"'."); ERR_FAIL_V(RES()); } value=library[reference]; } else if (right.begins_with("default")) { //use default //do none } else { //attempt to parse a constructor int popenpos = right.find("("); if (popenpos==-1) { memdelete(f); ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid constructor syntax: "+right); ERR_FAIL_V(RES()); } int pclosepos = right.find_last(")"); if (pclosepos==-1) { ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid constructor parameter syntax: "+right); ERR_FAIL_V(RES()); } String type = right.substr(0,popenpos); String param = right.substr(popenpos+1,pclosepos-popenpos-1); if (type=="icon") { String path; if (param.is_abs_path()) path=param; else path=base_path+"/"+param; Ref<Texture> texture = ResourceLoader::load(path); if (!texture.is_valid()) { memdelete(f); ERR_EXPLAIN(p_path+":"+itos(line)+": Couldn't find icon at path: "+path); ERR_FAIL_V(RES()); } value=texture; } else if (type=="sbox") { String path; if (param.is_abs_path()) path=param; else path=base_path+"/"+param; Ref<StyleBox> stylebox = ResourceLoader::load(path); if (!stylebox.is_valid()) { memdelete(f); ERR_EXPLAIN(p_path+":"+itos(line)+": Couldn't find stylebox at path: "+path); ERR_FAIL_V(RES()); } value=stylebox; } else if (type=="sboxt") { Vector<String> params = param.split(","); if (params.size()!=5 && params.size()!=9) { memdelete(f); ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid param count for sboxt(): '"+right+"'."); ERR_FAIL_V(RES()); } String path=params[0]; if (!param.is_abs_path()) path=base_path+"/"+path; Ref<Texture> tex = ResourceLoader::load(path); if (tex.is_null()) { memdelete(f); ERR_EXPLAIN(p_path+":"+itos(line)+": Could not open texture for sboxt at path: '"+params[0]+"'."); ERR_FAIL_V(RES()); } Ref<StyleBoxTexture> sbtex( memnew(StyleBoxTexture) ); sbtex->set_texture(tex); for(int i=0;i<4;i++) { if (!params[i+1].is_valid_integer()) { memdelete(f); ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid expand margin parameter for sboxt #"+itos(i+1) +", expected integer constant, got: '"+params[i+1]+"'."); ERR_FAIL_V(RES()); } int margin = params[i+1].to_int(); sbtex->set_expand_margin_size(Margin(i),margin); } if (params.size()==9) { for(int i=0;i<4;i++) { if (!params[i+5].is_valid_integer()) { memdelete(f); ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid expand margin parameter for sboxt #"+itos(i+5) +", expected integer constant, got: '"+params[i+5]+"'."); ERR_FAIL_V(RES()); } int margin = params[i+5].to_int(); sbtex->set_margin_size(Margin(i),margin); } } value = sbtex; } else if (type=="sboxf") { Vector<String> params = param.split(","); if (params.size()<2) { memdelete(f); ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid param count for sboxf(): '"+right+"'."); ERR_FAIL_V(RES()); } Ref<StyleBoxFlat> sbflat( memnew(StyleBoxFlat) ); if (!params[0].is_valid_integer()) { memdelete(f); ERR_EXPLAIN(p_path+":"+itos(line)+": Expected integer numeric constant for parameter 0 (border size)."); ERR_FAIL_V(RES()); } sbflat->set_border_size(params[0].to_int()); if (!params[0].is_valid_integer()) { memdelete(f); ERR_EXPLAIN(p_path+":"+itos(line)+": Expected integer numeric constant for parameter 0 (border size)."); ERR_FAIL_V(RES()); } int left = MIN( params.size()-1, 3 ); int ccodes=0; for(int i=0;i<left;i++) { if (params[i+1].is_valid_html_color()) ccodes++; else break; } Color normal; Color bright; Color dark; if (ccodes<1) { memdelete(f); ERR_EXPLAIN(p_path+":"+itos(line)+": Expected at least 1, 2 or 3 html color codes."); ERR_FAIL_V(RES()); } else if (ccodes==1) { normal=Color::html(params[1]); bright=Color::html(params[1]); dark=Color::html(params[1]); } else if (ccodes==2) { normal=Color::html(params[1]); bright=Color::html(params[2]); dark=Color::html(params[2]); } else { normal=Color::html(params[1]); bright=Color::html(params[2]); dark=Color::html(params[3]); } sbflat->set_dark_color(dark); sbflat->set_light_color(bright); sbflat->set_bg_color(normal); if (params.size()==ccodes+5) { //margins for(int i=0;i<4;i++) { if (!params[i+ccodes+1].is_valid_integer()) { memdelete(f); ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid expand margin parameter for sboxf #"+itos(i+ccodes+1) +", expected integer constant, got: '"+params[i+ccodes+1]+"'."); ERR_FAIL_V(RES()); } // int margin = params[i+ccodes+1].to_int(); //sbflat->set_margin_size(Margin(i),margin); } } else if (params.size()!=ccodes+1) { memdelete(f); ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid amount of margin parameters for sboxt."); ERR_FAIL_V(RES()); } value=sbflat; } else { memdelete(f); ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid constructor type: '"+type+"'."); ERR_FAIL_V(RES()); } } //parse left and do something with it String left= l.substr(0,eqpos); if (reading_library) { left=left.strip_edges(); if (!left.is_valid_identifier()) { memdelete(f); ERR_EXPLAIN(p_path+":"+itos(line)+": <LibraryItem> is not a valid identifier."); ERR_FAIL_V(RES()); } if (library.has(left)) { memdelete(f); ERR_EXPLAIN(p_path+":"+itos(line)+": Already in library: '"+left+"'."); ERR_FAIL_V(RES()); } library[left]=value; } else { int pointpos = left.find("."); if (pointpos==-1) { memdelete(f); ERR_EXPLAIN(p_path+":"+itos(line)+": Expected 'control.item=..' assign syntax."); ERR_FAIL_V(RES()); } String control=left.substr(0,pointpos).strip_edges(); if (!control.is_valid_identifier()) { memdelete(f); ERR_EXPLAIN(p_path+":"+itos(line)+": <Control> is not a valid identifier."); ERR_FAIL_V(RES()); } String item=left.substr(pointpos+1,left.size()).strip_edges(); if (!item.is_valid_identifier()) { memdelete(f); ERR_EXPLAIN(p_path+":"+itos(line)+": <Item> is not a valid identifier."); ERR_FAIL_V(RES()); } if (value.get_type()==Variant::NIL) { //try to use exiting if (Theme::get_default()->has_stylebox(item,control)) value=Theme::get_default()->get_stylebox(item,control); else if (Theme::get_default()->has_font(item,control)) value=Theme::get_default()->get_font(item,control); else if (Theme::get_default()->has_icon(item,control)) value=Theme::get_default()->get_icon(item,control); else if (Theme::get_default()->has_color(item,control)) value=Theme::get_default()->get_color(item,control); else if (Theme::get_default()->has_constant(item,control)) value=Theme::get_default()->get_constant(item,control); else { memdelete(f); ERR_EXPLAIN(p_path+":"+itos(line)+": Default not present for: '"+control+"."+item+"'."); ERR_FAIL_V(RES()); } } if (value.get_type()==Variant::OBJECT) { Ref<Resource> res = value; if (!res.is_valid()) { memdelete(f); ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid resource (NULL)."); ERR_FAIL_V(RES()); } if (res->cast_to<StyleBox>()) { theme->set_stylebox(item,control,res); } else if (res->cast_to<Font>()) { theme->set_font(item,control,res); } else if (res->cast_to<Font>()) { theme->set_font(item,control,res); } else if (res->cast_to<Texture>()) { theme->set_icon(item,control,res); } else { memdelete(f); ERR_EXPLAIN(p_path+":"+itos(line)+": Invalid resource type."); ERR_FAIL_V(RES()); } } else if (value.get_type()==Variant::COLOR) { theme->set_color(item,control,value); } else if (value.get_type()==Variant::INT) { theme->set_constant(item,control,value); } else { memdelete(f); ERR_EXPLAIN(p_path+":"+itos(line)+": Couldn't even determine what this setting is! what did you do!?"); ERR_FAIL_V(RES()); } } } f->close(); memdelete(f); return theme; }
ConnectDialog::~ConnectDialog() { memdelete(cdbinds); }