Skip to content

Commit

Permalink
Add readable export errors. Add RTL image vertical alignment support.
Browse files Browse the repository at this point in the history
  • Loading branch information
bruvzg committed Jun 8, 2022
1 parent 6536877 commit f5fa1ca
Show file tree
Hide file tree
Showing 16 changed files with 485 additions and 235 deletions.
13 changes: 13 additions & 0 deletions doc/classes/RichTextLabel.xml
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
<argument index="0" name="image" type="Texture" />
<argument index="1" name="width" type="int" default="0" />
<argument index="2" name="height" type="int" default="0" />
<argument index="3" name="align" type="int" enum="RichTextLabel.InlineAlign" default="2" />
<description>
Adds an image's opening and closing tags to the tag stack, optionally providing a [code]width[/code] and [code]height[/code] to resize the image.
If [code]width[/code] or [code]height[/code] is set to 0, the image size will be adjusted in order to keep the original aspect ratio.
Expand Down Expand Up @@ -335,6 +336,18 @@
<constant name="ALIGN_FILL" value="3" enum="Align">
Makes text fill width.
</constant>
<constant name="INLINE_ALIGN_TOP" value="0" enum="InlineAlign">
Aligns top of the inline image to the top of the text.
</constant>
<constant name="INLINE_ALIGN_CENTER" value="1" enum="InlineAlign">
Aligns center of the inline image to the center of the text.
</constant>
<constant name="INLINE_ALIGN_BASELINE" value="2" enum="InlineAlign">
Aligns bottom of the inline image to the baseline of the text.
</constant>
<constant name="INLINE_ALIGN_BOTTOM" value="3" enum="InlineAlign">
Aligns bottom of the inline image to the bottom of the text.
</constant>
<constant name="LIST_NUMBERS" value="0" enum="ListType">
Each list item has a number marker.
</constant>
Expand Down
115 changes: 95 additions & 20 deletions editor/editor_export.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@
#include "editor/editor_file_system.h"
#include "editor/plugins/script_editor_plugin.h"
#include "editor_node.h"
#include "editor_scale.h"
#include "editor_settings.h"
#include "scene/resources/resource_format_text.h"

Expand Down Expand Up @@ -220,6 +221,82 @@ EditorExportPreset::EditorExportPreset() :

///////////////////////////////////

bool EditorExportPlatform::fill_log_messages(RichTextLabel *p_log, Error p_err) {
bool has_messages = false;

int msg_count = get_message_count();

p_log->add_text(TTR("Project export for platform:") + " ");
p_log->add_image(get_logo(), 16 * EDSCALE, 16 * EDSCALE, RichTextLabel::INLINE_ALIGN_CENTER);
p_log->add_text(" ");
p_log->add_text(get_name());
p_log->add_text(" - ");
if (p_err == OK) {
if (get_worst_message_type() >= EditorExportPlatform::EXPORT_MESSAGE_WARNING) {
p_log->add_image(EditorNode::get_singleton()->get_gui_base()->get_icon("StatusWarning", "EditorIcons"), 16 * EDSCALE, 16 * EDSCALE, RichTextLabel::INLINE_ALIGN_CENTER);
p_log->add_text(" ");
p_log->add_text(TTR("Completed with errors."));
has_messages = true;
} else {
p_log->add_image(EditorNode::get_singleton()->get_gui_base()->get_icon("StatusSuccess", "EditorIcons"), 16 * EDSCALE, 16 * EDSCALE, RichTextLabel::INLINE_ALIGN_CENTER);
p_log->add_text(" ");
p_log->add_text(TTR("Completed sucessfully."));
if (msg_count > 0) {
has_messages = true;
}
}
} else {
p_log->add_image(EditorNode::get_singleton()->get_gui_base()->get_icon("StatusError", "EditorIcons"), 16 * EDSCALE, 16 * EDSCALE, RichTextLabel::INLINE_ALIGN_CENTER);
p_log->add_text(" ");
p_log->add_text(TTR("Failed."));
has_messages = true;
}

if (msg_count) {
p_log->push_table(2);
p_log->set_table_column_expand(0, false);
p_log->set_table_column_expand(1, true);
for (int m = 0; m < msg_count; m++) {
EditorExportPlatform::ExportMessage msg = get_message(m);
Color color = EditorNode::get_singleton()->get_gui_base()->get_color("font_color", "Label");
Ref<Texture> icon;

switch (msg.msg_type) {
case EditorExportPlatform::EXPORT_MESSAGE_INFO: {
color = EditorNode::get_singleton()->get_gui_base()->get_color("font_color", "Editor") * Color(1, 1, 1, 0.6);
} break;
case EditorExportPlatform::EXPORT_MESSAGE_WARNING: {
icon = EditorNode::get_singleton()->get_gui_base()->get_icon("Warning", "EditorIcons");
color = EditorNode::get_singleton()->get_gui_base()->get_color("warning_color", "Editor");
} break;
case EditorExportPlatform::EXPORT_MESSAGE_ERROR: {
icon = EditorNode::get_singleton()->get_gui_base()->get_icon("Error", "EditorIcons");
color = EditorNode::get_singleton()->get_gui_base()->get_color("error_color", "Editor");
} break;
default:
break;
}

p_log->push_cell();
p_log->add_text("\t");
if (icon.is_valid()) {
p_log->add_image(icon);
}
p_log->pop();

p_log->push_cell();
p_log->push_color(color);
p_log->add_text(vformat("[%s]: %s", msg.category, msg.text));
p_log->pop();
p_log->pop();
}
p_log->pop();
p_log->add_newline();
}
p_log->add_newline();
return has_messages;
}

void EditorExportPlatform::gen_debug_flags(Vector<String> &r_flags, int p_flags) {
String host = EditorSettings::get_singleton()->get("network/debug/remote_host");
int remote_port = (int)EditorSettings::get_singleton()->get("network/debug/remote_port");
Expand Down Expand Up @@ -961,7 +1038,10 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c

String tmppath = EditorSettings::get_singleton()->get_cache_dir().plus_file("packtmp");
FileAccess *ftmp = FileAccess::open(tmppath, FileAccess::WRITE);
ERR_FAIL_COND_V_MSG(!ftmp, ERR_CANT_CREATE, "Cannot create file '" + tmppath + "'.");
if (!ftmp) {
add_message(EXPORT_MESSAGE_ERROR, TTR("Save PCK"), vformat(TTR("Cannot create file \"%s\"."), tmppath));
return ERR_CANT_CREATE;
}

PackData pd;
pd.ep = &ep;
Expand All @@ -974,7 +1054,7 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c

if (err != OK) {
DirAccess::remove_file_or_error(tmppath);
ERR_PRINT("Failed to export project files");
add_message(EXPORT_MESSAGE_ERROR, TTR("Save PCK"), TTR("Failed to export project files."));
return err;
}

Expand Down Expand Up @@ -1066,7 +1146,8 @@ Error EditorExportPlatform::save_pack(const Ref<EditorExportPreset> &p_preset, c
if (!ftmp) {
memdelete(f);
DirAccess::remove_file_or_error(tmppath);
ERR_FAIL_V_MSG(ERR_CANT_CREATE, "Can't open file to read from path '" + String(tmppath) + "'.");
add_message(EXPORT_MESSAGE_ERROR, TTR("Save PCK"), vformat(TTR("Can't open file to read from path \"%s\"."), tmppath));
return ERR_CANT_CREATE;
}

const int bufsize = 16384;
Expand Down Expand Up @@ -1117,8 +1198,9 @@ Error EditorExportPlatform::save_zip(const Ref<EditorExportPreset> &p_preset, co
zd.zip = zip;

Error err = export_project_files(p_preset, _save_zip_file, &zd);
if (err != OK && err != ERR_SKIP)
ERR_PRINT("Failed to export project files");
if (err != OK && err != ERR_SKIP) {
add_message(EXPORT_MESSAGE_ERROR, TTR("Save ZIP"), TTR("Failed to export project files."));
}

zipClose(zip, nullptr);

Expand Down Expand Up @@ -1184,6 +1266,7 @@ void EditorExportPlatform::gen_export_flags(Vector<String> &r_flags, int p_flags
r_flags.push_back("--debug-navigation");
}
}

EditorExportPlatform::EditorExportPlatform() {
}

Expand Down Expand Up @@ -1638,6 +1721,7 @@ Error EditorExportPlatformPC::export_project(const Ref<EditorExportPreset> &p_pr

Error EditorExportPlatformPC::prepare_template(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) {
if (!DirAccess::exists(p_path.get_base_dir())) {
add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Template"), TTR("The given export path doesn't exist."));
return ERR_FILE_BAD_PATH;
}

Expand Down Expand Up @@ -1665,13 +1749,16 @@ Error EditorExportPlatformPC::prepare_template(const Ref<EditorExportPreset> &p_
}

if (template_path != String() && !FileAccess::exists(template_path)) {
EditorNode::get_singleton()->show_warning(TTR("Template file not found:") + "\n" + template_path);
add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Template"), vformat(TTR("Template file not found: \"%s\"."), template_path));
return ERR_FILE_NOT_FOUND;
}

DirAccessRef da = DirAccess::create(DirAccess::ACCESS_FILESYSTEM);
da->make_dir_recursive(p_path.get_base_dir());
Error err = da->copy(template_path, p_path, get_chmod_flags());
if (err != OK) {
add_message(EXPORT_MESSAGE_ERROR, TTR("Prepare Template"), TTR("Failed to copy export template."));
}

return err;
}
Expand All @@ -1691,14 +1778,11 @@ Error EditorExportPlatformPC::export_project_data(const Ref<EditorExportPreset>
Error err = save_pack(p_preset, pck_path, &so_files, p_preset->get("binary_format/embed_pck"), &embedded_pos, &embedded_size);
if (err == OK && p_preset->get("binary_format/embed_pck")) {
if (embedded_size >= 0x100000000 && !p_preset->get("binary_format/64_bits")) {
EditorNode::get_singleton()->show_warning(TTR("On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."));
add_message(EXPORT_MESSAGE_ERROR, TTR("PCK Embedding"), TTR("On 32-bit exports the embedded PCK cannot be bigger than 4 GiB."));
return ERR_INVALID_PARAMETER;
}

FixUpEmbeddedPckFunc fixup_func = get_fixup_embedded_pck_func();
if (fixup_func) {
err = fixup_func(p_path, embedded_pos, embedded_size);
}
err = fixup_embedded_pck(p_path, embedded_pos, embedded_size);
}

if (err == OK && !so_files.empty()) {
Expand Down Expand Up @@ -1778,17 +1862,8 @@ void EditorExportPlatformPC::set_chmod_flags(int p_flags) {
chmod_flags = p_flags;
}

EditorExportPlatformPC::FixUpEmbeddedPckFunc EditorExportPlatformPC::get_fixup_embedded_pck_func() const {
return fixup_embedded_pck_func;
}

void EditorExportPlatformPC::set_fixup_embedded_pck_func(FixUpEmbeddedPckFunc p_fixup_embedded_pck_func) {
fixup_embedded_pck_func = p_fixup_embedded_pck_func;
}

EditorExportPlatformPC::EditorExportPlatformPC() {
chmod_flags = -1;
fixup_embedded_pck_func = nullptr;
}

///////////////////////
Expand Down
66 changes: 58 additions & 8 deletions editor/editor_export.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@

#include "core/os/dir_access.h"
#include "core/resource.h"
#include "scene/gui/rich_text_label.h"
#include "scene/main/node.h"
#include "scene/main/timer.h"
#include "scene/resources/texture.h"
Expand Down Expand Up @@ -151,6 +152,19 @@ class EditorExportPlatform : public Reference {
typedef Error (*EditorExportSaveFunction)(void *p_userdata, const String &p_path, const Vector<uint8_t> &p_data, int p_file, int p_total);
typedef Error (*EditorExportSaveSharedObject)(void *p_userdata, const SharedObject &p_so);

enum ExportMessageType {
EXPORT_MESSAGE_NONE,
EXPORT_MESSAGE_INFO,
EXPORT_MESSAGE_WARNING,
EXPORT_MESSAGE_ERROR,
};

struct ExportMessage {
ExportMessageType msg_type;
String category;
String text;
};

private:
struct SavedData {
uint64_t ofs;
Expand Down Expand Up @@ -180,6 +194,8 @@ class EditorExportPlatform : public Reference {
PoolVector<String> features_pv;
};

Vector<ExportMessage> messages;

void _export_find_resources(EditorFileSystemDirectory *p_dir, Set<String> &p_paths);
void _export_find_dependencies(const String &p_path, Set<String> &p_paths);

Expand Down Expand Up @@ -220,6 +236,47 @@ class EditorExportPlatform : public Reference {

virtual Ref<EditorExportPreset> create_preset();

virtual void clear_messages() { messages.clear(); }
virtual void add_message(ExportMessageType p_type, const String &p_category, const String &p_message) {
ExportMessage msg;
msg.category = p_category;
msg.text = p_message;
msg.msg_type = p_type;
messages.push_back(msg);
switch (p_type) {
case EXPORT_MESSAGE_INFO: {
print_line(vformat("%s: %s\n", msg.category, msg.text));
} break;
case EXPORT_MESSAGE_WARNING: {
WARN_PRINT(vformat("%s: %s\n", msg.category, msg.text));
} break;
case EXPORT_MESSAGE_ERROR: {
ERR_PRINT(vformat("%s: %s\n", msg.category, msg.text));
} break;
default:
break;
}
}

virtual int get_message_count() const {
return messages.size();
}

virtual ExportMessage get_message(int p_index) const {
ERR_FAIL_INDEX_V(p_index, messages.size(), ExportMessage());
return messages[p_index];
}

virtual ExportMessageType get_worst_message_type() const {
ExportMessageType worst_type = EXPORT_MESSAGE_NONE;
for (int i = 0; i < messages.size(); i++) {
worst_type = MAX(worst_type, messages[i].msg_type);
}
return worst_type;
}

virtual bool fill_log_messages(RichTextLabel *p_log, Error p_err);

virtual void get_export_options(List<ExportOption> *r_options) = 0;
virtual bool should_update_export_options() { return false; }
virtual bool get_option_visibility(const String &p_option, const Map<StringName, Variant> &p_options) const { return true; }
Expand Down Expand Up @@ -400,9 +457,6 @@ class EditorExport : public Node {
class EditorExportPlatformPC : public EditorExportPlatform {
GDCLASS(EditorExportPlatformPC, EditorExportPlatform);

public:
typedef Error (*FixUpEmbeddedPckFunc)(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size);

private:
Ref<ImageTexture> logo;
String name;
Expand All @@ -418,8 +472,6 @@ class EditorExportPlatformPC : public EditorExportPlatform {

int chmod_flags;

FixUpEmbeddedPckFunc fixup_embedded_pck_func;

public:
virtual void get_preset_features(const Ref<EditorExportPreset> &p_preset, List<String> *r_features);

Expand All @@ -437,6 +489,7 @@ class EditorExportPlatformPC : public EditorExportPlatform {
virtual Error prepare_template(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags);
virtual Error modify_template(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags) { return OK; }
virtual Error export_project_data(const Ref<EditorExportPreset> &p_preset, bool p_debug, const String &p_path, int p_flags);
virtual Error fixup_embedded_pck(const String &p_path, int64_t p_embedded_start, int64_t p_embedded_size) { return OK; }

void set_extension(const String &p_extension, const String &p_feature_key = "default");
void set_name(const String &p_name);
Expand All @@ -456,9 +509,6 @@ class EditorExportPlatformPC : public EditorExportPlatform {
int get_chmod_flags() const;
void set_chmod_flags(int p_flags);

FixUpEmbeddedPckFunc get_fixup_embedded_pck_func() const;
void set_fixup_embedded_pck_func(FixUpEmbeddedPckFunc p_fixup_embedded_pck_func);

EditorExportPlatformPC();
};

Expand Down
17 changes: 5 additions & 12 deletions editor/editor_node.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -798,21 +798,14 @@ void EditorNode::_fs_changed() {
ERR_PRINT(vformat("Cannot export project with preset \"%s\" due to configuration errors:\n%s", preset_name, config_error));
err = missing_templates ? ERR_FILE_NOT_FOUND : ERR_UNCONFIGURED;
} else {
platform->clear_messages();
err = platform->export_project(preset, export_defer.debug, export_path);
}
}
switch (err) {
case OK:
break;
case ERR_FILE_NOT_FOUND:
export_error = vformat("Project export failed for preset \"%s\". The export template appears to be missing.", preset_name);
break;
case ERR_FILE_BAD_PATH:
export_error = vformat("Project export failed for preset \"%s\". The target path \"%s\" appears to be invalid.", preset_name, export_path);
break;
default:
export_error = vformat("Project export failed with error code %d for preset \"%s\".", (int)err, preset_name);
break;
if (err != OK) {
export_error = vformat("Project export for preset \"%s\" failed.", preset_name);
} else if (platform->get_worst_message_type() >= EditorExportPlatform::EXPORT_MESSAGE_WARNING) {
export_error = vformat("Project export for preset \"%s\" completed with errors.", preset_name);
}
}
}
Expand Down
Loading

0 comments on commit f5fa1ca

Please sign in to comment.