示例#1
0
FileDialog::~FileDialog() {

	if (unregister_func)
		unregister_func(this);
	memdelete(dir_access);
}
	~EditorFontImportDialog() {
		memdelete(options);
	}
示例#3
0
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;

}
示例#4
0
void godot_icall_RID_Dtor(RID *p_ptr) {
	ERR_FAIL_NULL(p_ptr);
	memdelete(p_ptr);
}
示例#5
0
文件: label.cpp 项目: jokance/godot
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();
}
示例#7
0
	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);
}
示例#10
0
void OS_Android::delete_main_loop() {

	memdelete( main_loop );
}
示例#11
0
void OS_Android::finalize() {

	memdelete(input);
}
示例#12
0
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;
}
示例#13
0
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
	};
}
示例#14
0
ThreadSafe::~ThreadSafe() {

	if (mutex)
		memdelete( mutex );
}
示例#15
0
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);
	}
}
示例#16
0
void unregister_theora_types() {

	memdelete( theora_stream_loader );
}
示例#17
0
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;
	}
}
示例#18
0
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);
	}
}
示例#20
0
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
}
示例#21
0
ScriptDebuggerRemote::~ScriptDebuggerRemote() {

	remove_print_handler(&phl);
	remove_error_handler(&eh);
	memdelete(mutex);
}
示例#22
0
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);
	}
}
示例#24
0
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;
}
示例#25
0
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);
}
示例#26
0
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;
}
示例#27
0
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;

}
示例#28
0
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;
}
示例#29
0
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;
}
示例#30
0
ConnectDialog::~ConnectDialog() {

	memdelete(cdbinds);
}