Browse Source

Allow export plugins to override export option values

David Snopek 1 year ago
parent
commit
ac88acde6f

+ 24 - 0
doc/classes/EditorExportPlugin.xml

@@ -178,6 +178,30 @@
 				- [code]update_visibility[/code]: An optional boolean value. If set to [code]true[/code], the preset will emit [signal Object.property_list_changed] when the option is changed.
 			</description>
 		</method>
+		<method name="_get_export_options_overrides" qualifiers="virtual const">
+			<return type="Dictionary" />
+			<param index="0" name="platform" type="EditorExportPlatform" />
+			<description>
+				Return a [Dictionary] of override values for export options, that will be used instead of user-provided values. Overridden options will be hidden from the user interface.
+				[codeblock]
+				class MyExportPlugin extends EditorExportPlugin:
+				    func _get_name() -&gt; String:
+				        return "MyExportPlugin"
+
+				    func _supports_platform(platform) -&gt; bool:
+				        if platform is EditorExportPlatformPC:
+				            # Run on all desktop platforms including Windows, MacOS and Linux.
+				            return true
+				        return false
+
+				    func _get_export_options_overrides(platform) -&gt; Dictionary:
+				        # Override "Embed PCK" to always be enabled.
+				        return {
+				            "binary_format/embed_pck": true,
+				        }
+				[/codeblock]
+			</description>
+		</method>
 		<method name="_get_name" qualifiers="virtual const">
 			<return type="String" />
 			<description>

+ 1 - 0
editor/editor_node.cpp

@@ -955,6 +955,7 @@ void EditorNode::_fs_changed() {
 				err = FAILED;
 				export_error = vformat("Export preset \"%s\" doesn't have a matching platform.", preset_name);
 			} else {
+				export_preset->update_value_overrides();
 				if (export_defer.pack_only) { // Only export .pck or .zip data pack.
 					if (export_path.ends_with(".zip")) {
 						err = platform->export_zip(export_preset, export_defer.debug, export_path);

+ 7 - 0
editor/export/editor_export_plugin.cpp

@@ -285,6 +285,12 @@ String EditorExportPlugin::_get_export_option_warning(const Ref<EditorExportPlat
 	return ret;
 }
 
+Dictionary EditorExportPlugin::_get_export_options_overrides(const Ref<EditorExportPlatform> &p_platform) const {
+	Dictionary ret;
+	GDVIRTUAL_CALL(_get_export_options_overrides, p_platform, ret);
+	return ret;
+}
+
 void EditorExportPlugin::_export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features) {
 }
 
@@ -327,6 +333,7 @@ void EditorExportPlugin::_bind_methods() {
 	GDVIRTUAL_BIND(_end_customize_resources);
 
 	GDVIRTUAL_BIND(_get_export_options, "platform");
+	GDVIRTUAL_BIND(_get_export_options_overrides, "platform");
 	GDVIRTUAL_BIND(_should_update_export_options, "platform");
 	GDVIRTUAL_BIND(_get_export_option_warning, "platform", "option");
 

+ 2 - 0
editor/export/editor_export_plugin.h

@@ -128,6 +128,7 @@ protected:
 
 	GDVIRTUAL2RC(PackedStringArray, _get_export_features, const Ref<EditorExportPlatform> &, bool);
 	GDVIRTUAL1RC(TypedArray<Dictionary>, _get_export_options, const Ref<EditorExportPlatform> &);
+	GDVIRTUAL1RC(Dictionary, _get_export_options_overrides, const Ref<EditorExportPlatform> &);
 	GDVIRTUAL1RC(bool, _should_update_export_options, const Ref<EditorExportPlatform> &);
 	GDVIRTUAL2RC(String, _get_export_option_warning, const Ref<EditorExportPlatform> &, String);
 
@@ -155,6 +156,7 @@ protected:
 
 	virtual PackedStringArray _get_export_features(const Ref<EditorExportPlatform> &p_export_platform, bool p_debug) const;
 	virtual void _get_export_options(const Ref<EditorExportPlatform> &p_export_platform, List<EditorExportPlatform::ExportOption> *r_options) const;
+	virtual Dictionary _get_export_options_overrides(const Ref<EditorExportPlatform> &p_export_platform) const;
 	virtual bool _should_update_export_options(const Ref<EditorExportPlatform> &p_export_platform) const;
 	virtual String _get_export_option_warning(const Ref<EditorExportPlatform> &p_export_platform, const String &p_option_name) const;
 

+ 42 - 1
editor/export/editor_export_preset.cpp

@@ -37,6 +37,7 @@ bool EditorExportPreset::_set(const StringName &p_name, const Variant &p_value)
 	EditorExport::singleton->save_presets();
 	if (update_visibility.has(p_name)) {
 		if (update_visibility[p_name]) {
+			update_value_overrides();
 			notify_property_list_changed();
 		}
 		return true;
@@ -46,6 +47,11 @@ bool EditorExportPreset::_set(const StringName &p_name, const Variant &p_value)
 }
 
 bool EditorExportPreset::_get(const StringName &p_name, Variant &r_ret) const {
+	if (value_overrides.has(p_name)) {
+		r_ret = value_overrides[p_name];
+		return true;
+	}
+
 	if (values.has(p_name)) {
 		r_ret = values[p_name];
 		return true;
@@ -59,6 +65,10 @@ void EditorExportPreset::_bind_methods() {
 }
 
 String EditorExportPreset::_get_property_warning(const StringName &p_name) const {
+	if (value_overrides.has(p_name)) {
+		return String();
+	}
+
 	String warning = platform->get_export_option_warning(this, p_name);
 	if (!warning.is_empty()) {
 		warning += "\n";
@@ -83,7 +93,7 @@ String EditorExportPreset::_get_property_warning(const StringName &p_name) const
 
 void EditorExportPreset::_get_property_list(List<PropertyInfo> *p_list) const {
 	for (const KeyValue<StringName, PropertyInfo> &E : properties) {
-		if (platform->get_export_option_visibility(this, E.key)) {
+		if (!value_overrides.has(E.key) && platform->get_export_option_visibility(this, E.key)) {
 			p_list->push_back(E.value);
 		}
 	}
@@ -119,6 +129,37 @@ void EditorExportPreset::update_files() {
 	}
 }
 
+void EditorExportPreset::update_value_overrides() {
+	Vector<Ref<EditorExportPlugin>> export_plugins = EditorExport::get_singleton()->get_export_plugins();
+	HashMap<StringName, Variant> new_value_overrides;
+
+	value_overrides.clear();
+
+	for (int i = 0; i < export_plugins.size(); i++) {
+		if (!export_plugins[i]->supports_platform(platform)) {
+			continue;
+		}
+
+		export_plugins.write[i]->set_export_preset(Ref<EditorExportPreset>(this));
+
+		Dictionary plugin_overrides = export_plugins[i]->_get_export_options_overrides(platform);
+		if (!plugin_overrides.is_empty()) {
+			Array keys = plugin_overrides.keys();
+			for (int x = 0; x < keys.size(); x++) {
+				StringName key = keys[x];
+				Variant value = plugin_overrides[key];
+				if (new_value_overrides.has(key) && new_value_overrides[key] != value) {
+					WARN_PRINT_ED(vformat("Editor export plugin '%s' overrides pre-existing export option override '%s' with new value.", export_plugins[i]->get_name(), key));
+				}
+				new_value_overrides[key] = value;
+			}
+		}
+	}
+
+	value_overrides = new_value_overrides;
+	notify_property_list_changed();
+}
+
 Vector<String> EditorExportPreset::get_files_to_export() const {
 	Vector<String> files;
 	for (const String &E : selected_files) {

+ 2 - 0
editor/export/editor_export_preset.h

@@ -78,6 +78,7 @@ private:
 
 	HashMap<StringName, PropertyInfo> properties;
 	HashMap<StringName, Variant> values;
+	HashMap<StringName, Variant> value_overrides;
 	HashMap<StringName, bool> update_visibility;
 
 	String name;
@@ -107,6 +108,7 @@ public:
 	bool has(const StringName &p_property) const { return values.has(p_property); }
 
 	void update_files();
+	void update_value_overrides();
 
 	Vector<String> get_files_to_export() const;
 	Dictionary get_customized_files() const;

+ 5 - 0
editor/export/project_export.cpp

@@ -276,6 +276,9 @@ void ProjectExportDialog::_edit_preset(int p_index) {
 	export_path->update_property();
 	runnable->set_disabled(false);
 	runnable->set_pressed(current->is_runnable());
+	if (parameters->get_edited_object() != current.ptr()) {
+		current->update_value_overrides();
+	}
 	parameters->set_object_class(current->get_platform()->get_class_name());
 	parameters->edit(current.ptr());
 
@@ -1100,6 +1103,7 @@ void ProjectExportDialog::_export_project_to_path(const String &p_path) {
 	exporting = true;
 
 	platform->clear_messages();
+	current->update_value_overrides();
 	Error err = platform->export_project(current, export_debug->is_pressed(), current->get_export_path(), 0);
 	result_dialog_log->clear();
 	if (err != ERR_SKIP) {
@@ -1149,6 +1153,7 @@ void ProjectExportDialog::_export_all(bool p_debug) {
 			ep.step(preset->get_name(), i);
 
 			platform->clear_messages();
+			preset->update_value_overrides();
 			Error err = platform->export_project(preset, p_debug, preset->get_export_path(), 0);
 			if (err == ERR_SKIP) {
 				exporting = false;