Skip to content

Commit

Permalink
[tvOS] extend tvOS plugins to support linker flags and plist types
Browse files Browse the repository at this point in the history
  • Loading branch information
naithar committed Mar 22, 2022
1 parent 115634c commit ba49259
Show file tree
Hide file tree
Showing 2 changed files with 155 additions and 8 deletions.
75 changes: 72 additions & 3 deletions platform/tvos/export/export.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,30 @@ void EditorExportPlatformTVOS::get_export_options(List<ExportOption> *r_options)
r_options->push_back(ExportOption(PropertyInfo(Variant::BOOL, "plugins/" + found_plugins[i].name), false));
}

Set<String> plist_keys;

for (int i = 0; i < found_plugins.size(); i++) {
// Editable plugin plist values
PluginConfigTVOS plugin = found_plugins[i];
const String *K = nullptr;

while ((K = plugin.plist.next(K))) {
String key = *K;
PluginConfigTVOS::PlistItem item = plugin.plist[key];
switch (item.type) {
case PluginConfigTVOS::PlistItemType::STRING_INPUT: {
String preset_name = "plugins_plist/" + key;
if (!plist_keys.has(preset_name)) {
r_options->push_back(ExportOption(PropertyInfo(Variant::STRING, preset_name), item.value));
plist_keys.insert(preset_name);
}
} break;
default:
continue;
}
}
}

plugins_changed.clear();
plugins = found_plugins;
}
Expand Down Expand Up @@ -787,6 +811,8 @@ Error EditorExportPlatformTVOS::_export_tvos_plugins(const Ref<EditorExportPrese
Vector<String> added_embedded_dependenciy_names;
HashMap<String, String> plist_values;

Set<String> plugin_linker_flags;

Error err;

for (int i = 0; i < enabled_plugins.size(); i++) {
Expand Down Expand Up @@ -853,19 +879,41 @@ Error EditorExportPlatformTVOS::_export_tvos_plugins(const Ref<EditorExportPrese
p_config_data.capabilities.push_back(capability);
}

// Linker flags
// Checking duplicates
for (int j = 0; j < plugin.linker_flags.size(); j++) {
String linker_flag = plugin.linker_flags[j];
plugin_linker_flags.insert(linker_flag);
}

// Plist
// Using hash map container to remove duplicates
const String *K = nullptr;

while ((K = plugin.plist.next(K))) {
String key = *K;
String value = plugin.plist[key];
PluginConfigTVOS::PlistItem item = plugin.plist[key];

String value;

switch (item.type) {
case PluginConfigTVOS::PlistItemType::STRING_INPUT: {
String preset_name = "plugins_plist/" + key;
String input_value = p_preset->get(preset_name);
value = "<string>" + input_value + "</string>";
} break;
default:
value = item.value;
break;
}

if (key.empty() || value.empty()) {
continue;
}

plist_values[key] = value;
String plist_key = "<key>" + key + "</key>";

plist_values[plist_key] = value;
}

// CPP Code
Expand All @@ -892,7 +940,7 @@ Error EditorExportPlatformTVOS::_export_tvos_plugins(const Ref<EditorExportPrese
continue;
}

p_config_data.plist_content += "<key>" + key + "</key><string>" + value + "</string>\n";
p_config_data.plist_content += key + value + "\n";
}
}

Expand Down Expand Up @@ -933,6 +981,27 @@ Error EditorExportPlatformTVOS::_export_tvos_plugins(const Ref<EditorExportPrese

p_config_data.cpp_code += plugin_cpp_code.format(plugin_format, "$_");
}

// Update Linker Flag Values
{
String result_linker_flags = " ";
for (Set<String>::Element *E = plugin_linker_flags.front(); E; E = E->next()) {
const String &flag = E->get();

if (flag.length() == 0) {
continue;
}

if (result_linker_flags.length() > 0) {
result_linker_flags += ' ';
}

result_linker_flags += flag;
}
result_linker_flags = result_linker_flags.replace("\"", "\\\"");
p_config_data.linker_flags += result_linker_flags;
}

return OK;
}

Expand Down
88 changes: 83 additions & 5 deletions platform/tvos/export/godot_plugin_config.h
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,24 @@ struct PluginConfigTVOS {
static const char *DEPENDENCIES_SYSTEM_KEY;
static const char *DEPENDENCIES_CAPABILITIES_KEY;
static const char *DEPENDENCIES_FILES_KEY;
static const char *DEPENDENCIES_LINKER_FLAGS;

static const char *PLIST_SECTION;

enum PlistItemType {
UNKNOWN,
STRING,
INTEGER,
BOOLEAN,
RAW,
STRING_INPUT,
};

struct PlistItem {
PlistItemType type;
String value;
};

// Set to true when the config file is properly loaded.
bool valid_config = false;
bool supports_targets = false;
Expand All @@ -86,10 +101,13 @@ struct PluginConfigTVOS {

Vector<String> files_to_copy;
Vector<String> capabilities;
Vector<String> linker_flags;

// Optional plist section
// Supports only string types for now
HashMap<String, String> plist;
// String value is default value.
// Currently supports `string`, `boolean`, `integer`, `raw`, `string_input` types
// <name>:<type> = <value>
HashMap<String, PlistItem> plist;
};

const char *PluginConfigTVOS::PLUGIN_CONFIG_EXT = ".gdatvp";
Expand All @@ -106,6 +124,7 @@ const char *PluginConfigTVOS::DEPENDENCIES_EMBEDDED_KEY = "embedded";
const char *PluginConfigTVOS::DEPENDENCIES_SYSTEM_KEY = "system";
const char *PluginConfigTVOS::DEPENDENCIES_CAPABILITIES_KEY = "capabilities";
const char *PluginConfigTVOS::DEPENDENCIES_FILES_KEY = "files";
const char *PluginConfigTVOS::DEPENDENCIES_LINKER_FLAGS = "linker_flags";

const char *PluginConfigTVOS::PLIST_SECTION = "plist";

Expand Down Expand Up @@ -247,6 +266,8 @@ static inline PluginConfigTVOS load_plugin_config(Ref<ConfigFile> config_file, c
return plugin_config;
}

config_file->clear();

Error err = config_file->load(path);

if (err != OK) {
Expand Down Expand Up @@ -275,20 +296,77 @@ static inline PluginConfigTVOS load_plugin_config(Ref<ConfigFile> config_file, c
plugin_config.files_to_copy = resolve_local_dependencies(config_base_dir, files);

plugin_config.capabilities = config_file->get_value(PluginConfigTVOS::DEPENDENCIES_SECTION, PluginConfigTVOS::DEPENDENCIES_CAPABILITIES_KEY, Vector<String>());

plugin_config.linker_flags = config_file->get_value(PluginConfigTVOS::DEPENDENCIES_SECTION, PluginConfigTVOS::DEPENDENCIES_LINKER_FLAGS, Vector<String>());
}

if (config_file->has_section(PluginConfigTVOS::PLIST_SECTION)) {
List<String> keys;
config_file->get_section_keys(PluginConfigTVOS::PLIST_SECTION, &keys);

for (int i = 0; i < keys.size(); i++) {
String value = config_file->get_value(PluginConfigTVOS::PLIST_SECTION, keys[i], String());
Vector<String> key_components = keys[i].split(":");

String key_value = "";
PluginConfigTVOS::PlistItemType key_type = PluginConfigTVOS::PlistItemType::UNKNOWN;

if (key_components.size() == 1) {
key_value = key_components[0];
key_type = PluginConfigTVOS::PlistItemType::STRING;
} else if (key_components.size() == 2) {
key_value = key_components[0];

if (key_components[1].to_lower() == "string") {
key_type = PluginConfigTVOS::PlistItemType::STRING;
} else if (key_components[1].to_lower() == "integer") {
key_type = PluginConfigTVOS::PlistItemType::INTEGER;
} else if (key_components[1].to_lower() == "boolean") {
key_type = PluginConfigTVOS::PlistItemType::BOOLEAN;
} else if (key_components[1].to_lower() == "raw") {
key_type = PluginConfigTVOS::PlistItemType::RAW;
} else if (key_components[1].to_lower() == "string_input") {
key_type = PluginConfigTVOS::PlistItemType::STRING_INPUT;
}
}

if (value.empty()) {
if (key_value.empty() || key_type == PluginConfigTVOS::PlistItemType::UNKNOWN) {
continue;
}

plugin_config.plist[keys[i]] = value;
String value;

switch (key_type) {
case PluginConfigTVOS::PlistItemType::STRING: {
String raw_value = config_file->get_value(PluginConfigTVOS::PLIST_SECTION, keys[i], String());
value = "<string>" + raw_value + "</string>";
} break;
case PluginConfigTVOS::PlistItemType::INTEGER: {
int raw_value = config_file->get_value(PluginConfigTVOS::PLIST_SECTION, keys[i], 0);
Dictionary value_dictionary;
String value_format = "<integer>$value</integer>";
value_dictionary["value"] = raw_value;
value = value_format.format(value_dictionary, "$_");
} break;
case PluginConfigTVOS::PlistItemType::BOOLEAN:
if (config_file->get_value(PluginConfigTVOS::PLIST_SECTION, keys[i], false)) {
value = "<true/>";
} else {
value = "<false/>";
}
break;
case PluginConfigTVOS::PlistItemType::RAW: {
String raw_value = config_file->get_value(PluginConfigTVOS::PLIST_SECTION, keys[i], String());
value = raw_value;
} break;
case PluginConfigTVOS::PlistItemType::STRING_INPUT: {
String raw_value = config_file->get_value(PluginConfigTVOS::PLIST_SECTION, keys[i], String());
value = raw_value;
} break;
default:
continue;
}

plugin_config.plist[key_value] = PluginConfigTVOS::PlistItem{ key_type, value };
}
}

Expand Down

0 comments on commit ba49259

Please sign in to comment.