1 | /**************************************************************************/ |
2 | /* editor_export_plugin.cpp */ |
3 | /**************************************************************************/ |
4 | /* This file is part of: */ |
5 | /* GODOT ENGINE */ |
6 | /* https://godotengine.org */ |
7 | /**************************************************************************/ |
8 | /* Copyright (c) 2014-present Godot Engine contributors (see AUTHORS.md). */ |
9 | /* Copyright (c) 2007-2014 Juan Linietsky, Ariel Manzur. */ |
10 | /* */ |
11 | /* Permission is hereby granted, free of charge, to any person obtaining */ |
12 | /* a copy of this software and associated documentation files (the */ |
13 | /* "Software"), to deal in the Software without restriction, including */ |
14 | /* without limitation the rights to use, copy, modify, merge, publish, */ |
15 | /* distribute, sublicense, and/or sell copies of the Software, and to */ |
16 | /* permit persons to whom the Software is furnished to do so, subject to */ |
17 | /* the following conditions: */ |
18 | /* */ |
19 | /* The above copyright notice and this permission notice shall be */ |
20 | /* included in all copies or substantial portions of the Software. */ |
21 | /* */ |
22 | /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, */ |
23 | /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF */ |
24 | /* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. */ |
25 | /* IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY */ |
26 | /* CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, */ |
27 | /* TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE */ |
28 | /* SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */ |
29 | /**************************************************************************/ |
30 | |
31 | #include "editor_export_plugin.h" |
32 | |
33 | #include "core/config/project_settings.h" |
34 | #include "core/io/dir_access.h" |
35 | #include "core/io/file_access.h" |
36 | #include "editor/editor_paths.h" |
37 | #include "editor/editor_settings.h" |
38 | #include "editor/export/editor_export_platform.h" |
39 | #include "scene/resources/resource_format_text.h" |
40 | |
41 | void EditorExportPlugin::set_export_preset(const Ref<EditorExportPreset> &p_preset) { |
42 | if (p_preset.is_valid()) { |
43 | export_preset = p_preset; |
44 | } |
45 | } |
46 | |
47 | Ref<EditorExportPreset> EditorExportPlugin::get_export_preset() const { |
48 | return export_preset; |
49 | } |
50 | |
51 | void EditorExportPlugin::add_file(const String &p_path, const Vector<uint8_t> &p_file, bool p_remap) { |
52 | ExtraFile ef; |
53 | ef.data = p_file; |
54 | ef.path = p_path; |
55 | ef.remap = p_remap; |
56 | extra_files.push_back(ef); |
57 | } |
58 | |
59 | void EditorExportPlugin::add_shared_object(const String &p_path, const Vector<String> &p_tags, const String &p_target) { |
60 | shared_objects.push_back(SharedObject(p_path, p_tags, p_target)); |
61 | } |
62 | |
63 | void EditorExportPlugin::add_ios_framework(const String &p_path) { |
64 | ios_frameworks.push_back(p_path); |
65 | } |
66 | |
67 | void EditorExportPlugin::add_ios_embedded_framework(const String &p_path) { |
68 | ios_embedded_frameworks.push_back(p_path); |
69 | } |
70 | |
71 | Vector<String> EditorExportPlugin::get_ios_frameworks() const { |
72 | return ios_frameworks; |
73 | } |
74 | |
75 | Vector<String> EditorExportPlugin::get_ios_embedded_frameworks() const { |
76 | return ios_embedded_frameworks; |
77 | } |
78 | |
79 | void EditorExportPlugin::add_ios_plist_content(const String &p_plist_content) { |
80 | ios_plist_content += p_plist_content + "\n" ; |
81 | } |
82 | |
83 | String EditorExportPlugin::get_ios_plist_content() const { |
84 | return ios_plist_content; |
85 | } |
86 | |
87 | void EditorExportPlugin::add_ios_linker_flags(const String &p_flags) { |
88 | if (ios_linker_flags.length() > 0) { |
89 | ios_linker_flags += ' '; |
90 | } |
91 | ios_linker_flags += p_flags; |
92 | } |
93 | |
94 | String EditorExportPlugin::get_ios_linker_flags() const { |
95 | return ios_linker_flags; |
96 | } |
97 | |
98 | void EditorExportPlugin::add_ios_bundle_file(const String &p_path) { |
99 | ios_bundle_files.push_back(p_path); |
100 | } |
101 | |
102 | Vector<String> EditorExportPlugin::get_ios_bundle_files() const { |
103 | return ios_bundle_files; |
104 | } |
105 | |
106 | void EditorExportPlugin::add_ios_cpp_code(const String &p_code) { |
107 | ios_cpp_code += p_code; |
108 | } |
109 | |
110 | String EditorExportPlugin::get_ios_cpp_code() const { |
111 | return ios_cpp_code; |
112 | } |
113 | |
114 | void EditorExportPlugin::add_macos_plugin_file(const String &p_path) { |
115 | macos_plugin_files.push_back(p_path); |
116 | } |
117 | |
118 | const Vector<String> &EditorExportPlugin::get_macos_plugin_files() const { |
119 | return macos_plugin_files; |
120 | } |
121 | |
122 | void EditorExportPlugin::add_ios_project_static_lib(const String &p_path) { |
123 | ios_project_static_libs.push_back(p_path); |
124 | } |
125 | |
126 | Vector<String> EditorExportPlugin::get_ios_project_static_libs() const { |
127 | return ios_project_static_libs; |
128 | } |
129 | |
130 | Variant EditorExportPlugin::get_option(const StringName &p_name) const { |
131 | ERR_FAIL_NULL_V(export_preset, Variant()); |
132 | return export_preset->get(p_name); |
133 | } |
134 | |
135 | String EditorExportPlugin::_has_valid_export_configuration(const Ref<EditorExportPlatform> &p_export_platform, const Ref<EditorExportPreset> &p_preset) { |
136 | String warning; |
137 | if (!supports_platform(p_export_platform)) { |
138 | warning += vformat(TTR("Plugin \"%s\" is not supported on \"%s\"" ), get_name(), p_export_platform->get_name()); |
139 | warning += "\n" ; |
140 | return warning; |
141 | } |
142 | |
143 | set_export_preset(p_preset); |
144 | List<EditorExportPlatform::ExportOption> options; |
145 | _get_export_options(p_export_platform, &options); |
146 | for (const EditorExportPlatform::ExportOption &E : options) { |
147 | String option_warning = _get_export_option_warning(p_export_platform, E.option.name); |
148 | if (!option_warning.is_empty()) { |
149 | warning += option_warning + "\n" ; |
150 | } |
151 | } |
152 | |
153 | return warning; |
154 | } |
155 | |
156 | void EditorExportPlugin::_export_file_script(const String &p_path, const String &p_type, const Vector<String> &p_features) { |
157 | GDVIRTUAL_CALL(_export_file, p_path, p_type, p_features); |
158 | } |
159 | |
160 | void EditorExportPlugin::_export_begin_script(const Vector<String> &p_features, bool p_debug, const String &p_path, int p_flags) { |
161 | GDVIRTUAL_CALL(_export_begin, p_features, p_debug, p_path, p_flags); |
162 | } |
163 | |
164 | void EditorExportPlugin::_export_end_script() { |
165 | GDVIRTUAL_CALL(_export_end); |
166 | } |
167 | |
168 | // Customization |
169 | |
170 | bool EditorExportPlugin::_begin_customize_resources(const Ref<EditorExportPlatform> &p_platform, const Vector<String> &p_features) { |
171 | bool ret = false; |
172 | GDVIRTUAL_CALL(_begin_customize_resources, p_platform, p_features, ret); |
173 | return ret; |
174 | } |
175 | |
176 | Ref<Resource> EditorExportPlugin::_customize_resource(const Ref<Resource> &p_resource, const String &p_path) { |
177 | Ref<Resource> ret; |
178 | GDVIRTUAL_REQUIRED_CALL(_customize_resource, p_resource, p_path, ret); |
179 | return ret; |
180 | } |
181 | |
182 | bool EditorExportPlugin::_begin_customize_scenes(const Ref<EditorExportPlatform> &p_platform, const Vector<String> &p_features) { |
183 | bool ret = false; |
184 | GDVIRTUAL_CALL(_begin_customize_scenes, p_platform, p_features, ret); |
185 | return ret; |
186 | } |
187 | |
188 | Node *EditorExportPlugin::_customize_scene(Node *p_root, const String &p_path) { |
189 | Node *ret = nullptr; |
190 | GDVIRTUAL_REQUIRED_CALL(_customize_scene, p_root, p_path, ret); |
191 | return ret; |
192 | } |
193 | |
194 | uint64_t EditorExportPlugin::_get_customization_configuration_hash() const { |
195 | uint64_t ret = 0; |
196 | GDVIRTUAL_REQUIRED_CALL(_get_customization_configuration_hash, ret); |
197 | return ret; |
198 | } |
199 | |
200 | void EditorExportPlugin::_end_customize_scenes() { |
201 | GDVIRTUAL_CALL(_end_customize_scenes); |
202 | } |
203 | |
204 | void EditorExportPlugin::_end_customize_resources() { |
205 | GDVIRTUAL_CALL(_end_customize_resources); |
206 | } |
207 | |
208 | String EditorExportPlugin::get_name() const { |
209 | String ret; |
210 | GDVIRTUAL_REQUIRED_CALL(_get_name, ret); |
211 | return ret; |
212 | } |
213 | |
214 | bool EditorExportPlugin::supports_platform(const Ref<EditorExportPlatform> &p_export_platform) const { |
215 | bool ret = false; |
216 | GDVIRTUAL_CALL(_supports_platform, p_export_platform, ret); |
217 | return ret; |
218 | } |
219 | |
220 | PackedStringArray EditorExportPlugin::get_android_dependencies(const Ref<EditorExportPlatform> &p_export_platform, bool p_debug) const { |
221 | PackedStringArray ret; |
222 | GDVIRTUAL_CALL(_get_android_dependencies, p_export_platform, p_debug, ret); |
223 | return ret; |
224 | } |
225 | |
226 | PackedStringArray EditorExportPlugin::get_android_dependencies_maven_repos(const Ref<EditorExportPlatform> &p_export_platform, bool p_debug) const { |
227 | PackedStringArray ret; |
228 | GDVIRTUAL_CALL(_get_android_dependencies_maven_repos, p_export_platform, p_debug, ret); |
229 | return ret; |
230 | } |
231 | |
232 | PackedStringArray EditorExportPlugin::get_android_libraries(const Ref<EditorExportPlatform> &p_export_platform, bool p_debug) const { |
233 | PackedStringArray ret; |
234 | GDVIRTUAL_CALL(_get_android_libraries, p_export_platform, p_debug, ret); |
235 | return ret; |
236 | } |
237 | |
238 | String EditorExportPlugin::get_android_manifest_activity_element_contents(const Ref<EditorExportPlatform> &p_export_platform, bool p_debug) const { |
239 | String ret; |
240 | GDVIRTUAL_CALL(_get_android_manifest_activity_element_contents, p_export_platform, p_debug, ret); |
241 | return ret; |
242 | } |
243 | |
244 | String EditorExportPlugin::get_android_manifest_application_element_contents(const Ref<EditorExportPlatform> &p_export_platform, bool p_debug) const { |
245 | String ret; |
246 | GDVIRTUAL_CALL(_get_android_manifest_application_element_contents, p_export_platform, p_debug, ret); |
247 | return ret; |
248 | } |
249 | |
250 | String EditorExportPlugin::get_android_manifest_element_contents(const Ref<EditorExportPlatform> &p_export_platform, bool p_debug) const { |
251 | String ret; |
252 | GDVIRTUAL_CALL(_get_android_manifest_element_contents, p_export_platform, p_debug, ret); |
253 | return ret; |
254 | } |
255 | |
256 | PackedStringArray EditorExportPlugin::_get_export_features(const Ref<EditorExportPlatform> &p_platform, bool p_debug) const { |
257 | PackedStringArray ret; |
258 | GDVIRTUAL_CALL(_get_export_features, p_platform, p_debug, ret); |
259 | return ret; |
260 | } |
261 | |
262 | void EditorExportPlugin::_get_export_options(const Ref<EditorExportPlatform> &p_platform, List<EditorExportPlatform::ExportOption> *r_options) const { |
263 | TypedArray<Dictionary> ret; |
264 | GDVIRTUAL_CALL(_get_export_options, p_platform, ret); |
265 | for (int i = 0; i < ret.size(); i++) { |
266 | Dictionary option = ret[i]; |
267 | ERR_CONTINUE_MSG(!option.has("option" ), "Missing required element 'option'" ); |
268 | ERR_CONTINUE_MSG(!option.has("default_value" ), "Missing required element 'default_value'" ); |
269 | PropertyInfo property_info = PropertyInfo::from_dict(option["option" ]); |
270 | Variant default_value = option["default_value" ]; |
271 | bool update_visibility = option.has("update_visibility" ) && option["update_visibility" ]; |
272 | r_options->push_back(EditorExportPlatform::ExportOption(property_info, default_value, update_visibility)); |
273 | } |
274 | } |
275 | |
276 | bool EditorExportPlugin::_should_update_export_options(const Ref<EditorExportPlatform> &p_platform) const { |
277 | bool ret = false; |
278 | GDVIRTUAL_CALL(_should_update_export_options, p_platform, ret); |
279 | return ret; |
280 | } |
281 | |
282 | String EditorExportPlugin::_get_export_option_warning(const Ref<EditorExportPlatform> &p_export_platform, const String &p_option_name) const { |
283 | String ret; |
284 | GDVIRTUAL_CALL(_get_export_option_warning, p_export_platform, p_option_name, ret); |
285 | return ret; |
286 | } |
287 | |
288 | void EditorExportPlugin::_export_file(const String &p_path, const String &p_type, const HashSet<String> &p_features) { |
289 | } |
290 | |
291 | void EditorExportPlugin::_export_begin(const HashSet<String> &p_features, bool p_debug, const String &p_path, int p_flags) { |
292 | } |
293 | |
294 | void EditorExportPlugin::skip() { |
295 | skipped = true; |
296 | } |
297 | |
298 | void EditorExportPlugin::_bind_methods() { |
299 | ClassDB::bind_method(D_METHOD("add_shared_object" , "path" , "tags" , "target" ), &EditorExportPlugin::add_shared_object); |
300 | ClassDB::bind_method(D_METHOD("add_ios_project_static_lib" , "path" ), &EditorExportPlugin::add_ios_project_static_lib); |
301 | ClassDB::bind_method(D_METHOD("add_file" , "path" , "file" , "remap" ), &EditorExportPlugin::add_file); |
302 | ClassDB::bind_method(D_METHOD("add_ios_framework" , "path" ), &EditorExportPlugin::add_ios_framework); |
303 | ClassDB::bind_method(D_METHOD("add_ios_embedded_framework" , "path" ), &EditorExportPlugin::add_ios_embedded_framework); |
304 | ClassDB::bind_method(D_METHOD("add_ios_plist_content" , "plist_content" ), &EditorExportPlugin::add_ios_plist_content); |
305 | ClassDB::bind_method(D_METHOD("add_ios_linker_flags" , "flags" ), &EditorExportPlugin::add_ios_linker_flags); |
306 | ClassDB::bind_method(D_METHOD("add_ios_bundle_file" , "path" ), &EditorExportPlugin::add_ios_bundle_file); |
307 | ClassDB::bind_method(D_METHOD("add_ios_cpp_code" , "code" ), &EditorExportPlugin::add_ios_cpp_code); |
308 | ClassDB::bind_method(D_METHOD("add_macos_plugin_file" , "path" ), &EditorExportPlugin::add_macos_plugin_file); |
309 | ClassDB::bind_method(D_METHOD("skip" ), &EditorExportPlugin::skip); |
310 | ClassDB::bind_method(D_METHOD("get_option" , "name" ), &EditorExportPlugin::get_option); |
311 | |
312 | GDVIRTUAL_BIND(_export_file, "path" , "type" , "features" ); |
313 | GDVIRTUAL_BIND(_export_begin, "features" , "is_debug" , "path" , "flags" ); |
314 | GDVIRTUAL_BIND(_export_end); |
315 | |
316 | GDVIRTUAL_BIND(_begin_customize_resources, "platform" , "features" ); |
317 | GDVIRTUAL_BIND(_customize_resource, "resource" , "path" ); |
318 | |
319 | GDVIRTUAL_BIND(_begin_customize_scenes, "platform" , "features" ); |
320 | GDVIRTUAL_BIND(_customize_scene, "scene" , "path" ); |
321 | |
322 | GDVIRTUAL_BIND(_get_customization_configuration_hash); |
323 | |
324 | GDVIRTUAL_BIND(_end_customize_scenes); |
325 | GDVIRTUAL_BIND(_end_customize_resources); |
326 | |
327 | GDVIRTUAL_BIND(_get_export_options, "platform" ); |
328 | GDVIRTUAL_BIND(_should_update_export_options, "platform" ); |
329 | GDVIRTUAL_BIND(_get_export_option_warning, "platform" , "option" ); |
330 | |
331 | GDVIRTUAL_BIND(_get_export_features, "platform" , "debug" ); |
332 | GDVIRTUAL_BIND(_get_name); |
333 | |
334 | GDVIRTUAL_BIND(_supports_platform, "platform" ); |
335 | |
336 | GDVIRTUAL_BIND(_get_android_dependencies, "platform" , "debug" ); |
337 | GDVIRTUAL_BIND(_get_android_dependencies_maven_repos, "platform" , "debug" ); |
338 | GDVIRTUAL_BIND(_get_android_libraries, "platform" , "debug" ); |
339 | GDVIRTUAL_BIND(_get_android_manifest_activity_element_contents, "platform" , "debug" ); |
340 | GDVIRTUAL_BIND(_get_android_manifest_application_element_contents, "platform" , "debug" ); |
341 | GDVIRTUAL_BIND(_get_android_manifest_element_contents, "platform" , "debug" ); |
342 | } |
343 | |
344 | EditorExportPlugin::EditorExportPlugin() { |
345 | EDITOR_DEF("export/ssh/ssh" , "" ); |
346 | EDITOR_DEF("export/ssh/scp" , "" ); |
347 | } |
348 | |