Merge pull request #1735 from player-03/ConfigData

Make it easier to configure AndroidManifest.xml from project.xml.
This commit is contained in:
player-03
2024-01-14 13:42:52 -05:00
committed by GitHub
4 changed files with 126 additions and 140 deletions

View File

@@ -9,6 +9,8 @@ import haxe.xml.Fast as Access;
abstract ConfigData(Dynamic) to Dynamic from Dynamic
{
private static inline var ARRAY:String = "___array";
public function new()
{
this = {};
@@ -32,39 +34,12 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic
public function exists(id:String):Bool
{
var tree = id.split('.');
if (tree.length <= 1)
{
return Reflect.hasField(this, id);
}
var current = this;
for (leaf in tree)
{
if (Reflect.hasField(current, leaf))
{
current = Reflect.field(current, leaf);
}
else
{
return false;
}
}
return true;
return get(id) != null;
}
public function get(id:String):ConfigData
{
var tree = id.split('.');
if (tree.length <= 1)
{
return Reflect.field(this, id);
}
var tree = id.split(".");
var current = this;
for (leaf in tree)
@@ -82,41 +57,29 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic
public function getArray(id:String, defaultValue:Array<Dynamic> = null):Array<Dynamic>
{
var tree = id.split('.');
var tree = id.split(".");
var array:Array<Dynamic> = null;
if (tree.length <= 1)
{
array = Reflect.field(this, id + "___array");
var current = this;
var field = tree.pop();
if (array == null && Reflect.hasField(this, id))
for (leaf in tree)
{
current = Reflect.field(current, leaf);
if (current == null)
{
array = [Reflect.field(this, id)];
break;
}
}
else
if (current != null)
{
var current = this;
var field = tree.pop();
array = Reflect.field(current, field + ARRAY);
for (leaf in tree)
if (array == null && Reflect.hasField(current, field))
{
current = Reflect.field(current, leaf);
if (current == null)
{
break;
}
}
if (current != null)
{
array = Reflect.field(current, field + "___array");
if (array == null && Reflect.hasField(current, field))
{
array = [Reflect.field(current, field)];
}
array = [Reflect.field(current, field)];
}
}
@@ -207,6 +170,32 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic
return defaultValue;
}
public function getKeyValueArray(id:String, defaultValues:Dynamic = null):Array<{ key:Dynamic, value:Dynamic }>
{
var values = {};
if (defaultValues != null)
{
ObjectTools.copyFields(defaultValues, values);
}
var data = get(id);
for (key in Reflect.fields(data))
{
if (!StringTools.endsWith (key, ARRAY))
{
Reflect.setField(values, key, Reflect.field(data, key));
}
}
var pairs = [];
for (key in Reflect.fields(values))
{
pairs.push({ key: key, value: Reflect.field(values, key) });
}
return pairs;
}
private function log(v:Dynamic):Void
{
if (Log.verbose)
@@ -227,7 +216,7 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic
{
for (field in Reflect.fields(source))
{
if (StringTools.endsWith(field, "___array"))
if (StringTools.endsWith(field, ARRAY))
{
continue;
}
@@ -257,17 +246,17 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic
if (doCopy && Reflect.field(source, field) != Reflect.field(destination, field) && typeSource != "TObject")
{
if (!Reflect.hasField(destination, field + "___array"))
if (!Reflect.hasField(destination, field + ARRAY))
{
Reflect.setField(destination, field + "___array", [ObjectTools.deepCopy(Reflect.field(destination, field))]);
Reflect.setField(destination, field + ARRAY, [ObjectTools.deepCopy(Reflect.field(destination, field))]);
}
var array:Array<Dynamic> = Reflect.field(destination, field + "___array");
var array:Array<Dynamic> = Reflect.field(destination, field + ARRAY);
if (Reflect.hasField(source, field + "___array"))
if (Reflect.hasField(source, field + ARRAY))
{
array = array.concat(Reflect.field(source, field + "___array"));
Reflect.setField(destination, field + "___array", array);
array = array.concat(Reflect.field(source, field + ARRAY));
Reflect.setField(destination, field + ARRAY, array);
}
else
{
@@ -289,9 +278,9 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic
{
Reflect.setField(destination, field, Reflect.field(source, field));
if (Reflect.hasField(source, field + "___array"))
if (Reflect.hasField(source, field + ARRAY))
{
Reflect.setField(destination, field + "___array", Reflect.field(source, field + "___array"));
Reflect.setField(destination, field + ARRAY, Reflect.field(source, field + ARRAY));
}
}
}
@@ -305,7 +294,7 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic
if (StringTools.startsWith(elem.name, "config:"))
{
var items = elem.name.split(':');
var items = elem.name.split(":");
bucketType = items[1];
}
@@ -353,12 +342,13 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic
if (Reflect.hasField(bucket, child.name))
{
if (!Reflect.hasField(bucket, child.name + "___array"))
var array:Array<Dynamic> = Reflect.field(bucket, child.name + ARRAY);
if (array == null)
{
Reflect.setField(bucket, child.name + "___array", [ObjectTools.deepCopy(Reflect.field(bucket, child.name))]);
array = [ObjectTools.deepCopy(Reflect.field(bucket, child.name))];
Reflect.setField(bucket, child.name + ARRAY, array);
}
var array:Array<Dynamic> = Reflect.field(bucket, child.name + "___array");
var arrayBucket = {};
array.push(arrayBucket);
@@ -410,27 +400,9 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic
}
}
public function push(id:String, value:Dynamic):Void
public function push(id:String, value:Dynamic, ?unique:Bool = false):Void
{
var tree = id.split('.');
if (tree.length <= 1)
{
if (Reflect.hasField(this, id))
{
if (!Reflect.hasField(this, id + "___array"))
{
Reflect.setField(this, id + "___array", Reflect.hasField(this, id) ? [ObjectTools.deepCopy(Reflect.field(this, id))] : []);
}
var array:Array<Dynamic> = Reflect.field(this, id + "___array");
array.push(value);
}
Reflect.setField(this, id, value);
return;
}
var tree = id.split(".");
var current = this;
var field = tree.pop();
@@ -454,13 +426,18 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic
if (Reflect.hasField(current, field))
{
if (!Reflect.hasField(current, field + "___array"))
var array:Array<Dynamic> = Reflect.field(current, field + ARRAY);
if (array == null)
{
Reflect.setField(current, field + "___array", Reflect.hasField(current, field) ? [ObjectTools.deepCopy(Reflect.field(current, field))] : []);
array = [ObjectTools.deepCopy(Reflect.field(current, field))];
Reflect.setField(current, field + ARRAY, array);
}
var array:Array<Dynamic> = Reflect.field(current, field + "___array");
array.push(value);
if (!unique || array.indexOf(value) == -1)
{
array.push(value);
}
}
Reflect.setField(current, field, value);
@@ -468,14 +445,7 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic
public function set(id:String, value:Dynamic):Void
{
var tree = id.split('.');
if (tree.length <= 1)
{
Reflect.setField(this, id, value);
return;
}
var tree = id.split(".");
var current = this;
var field = tree.pop();
@@ -525,12 +495,14 @@ abstract ConfigData(Dynamic) to Dynamic from Dynamic
{
if (typeSource != "TObject")
{
if (!Reflect.hasField(bucket, node + "___array"))
var array:Array<Dynamic> = Reflect.field(bucket, node + ARRAY);
if (array == null)
{
Reflect.setField(bucket, node + "___array", [ObjectTools.deepCopy(Reflect.field(bucket, node))]);
array = [ObjectTools.deepCopy(Reflect.field(bucket, node))];
Reflect.setField(bucket, node + ARRAY, array);
}
cast(Reflect.field(bucket, node + "___array"), Array<Dynamic>).push(value);
array.push(value);
}
Reflect.setField(bucket, node, value);

View File

@@ -1632,21 +1632,8 @@ class ProjectXMLParser extends HXProject
case "install-location":
config.set("android.install-location", value);
case "extension":
var extensions = config.getArrayString("android.extension");
if (extensions == null || extensions.indexOf(value) == -1)
{
config.push("android.extension", value);
}
case "permission":
var permissions = config.getArrayString("android.permission");
if (permissions == null || permissions.indexOf(value) == -1)
{
config.push("android.permission", value);
}
case "extension", "permission":
config.push("android." + name, value, true);
case "gradle-version":
config.set("android.gradle-version", value);

View File

@@ -4,20 +4,18 @@
<uses-feature android:glEsVersion="0x00020000" android:required="true" />
<uses-feature android:name="android.hardware.touchscreen" android:required="false" />
::if (ANDROID_PERMISSIONS != null)::::foreach ANDROID_PERMISSIONS::<uses-permission android:name="::__current__::" />
::end::::end::
::foreach ANDROID_PERMISSIONS::<uses-permission android:name="::__current__::" />
::end::
<application android:label="::APP_TITLE::" ::if (HAS_ICON):: android:icon="@drawable/icon"::end:: android:allowBackup="true" android:theme="@android:style/Theme.NoTitleBar::if (WIN_FULLSCREEN)::.Fullscreen::end::" android:hardwareAccelerated="true" ::if (ANDROID_TARGET_SDK_VERSION>=30):: android:allowNativeHeapPointerTagging="false" ::end::>
<application ::foreach ANDROID_APPLICATION::::if ((value != null) && (value != ""))::::key::="::value::" ::end::::end::>
::if (WIN_ORIENTATION=="portrait")::
<meta-data android:name="SDL_ENV.SDL_IOS_ORIENTATIONS" android:value= "Portrait PortraitUpsideDown" />
<meta-data android:name="SDL_ENV.SDL_IOS_ORIENTATIONS" android:value="Portrait PortraitUpsideDown" />
::elseif (WIN_ORIENTATION=="landscape")::
<meta-data android:name="SDL_ENV.SDL_IOS_ORIENTATIONS" android:value="LandscapeLeft LandscapeRight" />
::end::
::if (WIN_ORIENTATION=="landscape")::
<meta-data android:name="SDL_ENV.SDL_IOS_ORIENTATIONS" android:value= "LandscapeLeft LandscapeRight" />
::end::
<activity android:name="MainActivity" android:exported="true" android:launchMode="singleTask" android:label="::APP_TITLE::" android:configChanges="keyboardHidden|orientation|screenSize|screenLayout|uiMode"::if (WIN_ORIENTATION=="portrait"):: android:screenOrientation="sensorPortrait"::end::::if (WIN_ORIENTATION=="landscape"):: android:screenOrientation="sensorLandscape"::end::>
<activity ::foreach ANDROID_ACTIVITY::::if ((value != null) && (value != ""))::::key::="::value::" ::end::::end::>
<intent-filter>

View File

@@ -469,7 +469,21 @@ class AndroidPlatform extends PlatformTarget
context.ANDROID_USE_ANDROIDX = project.config.getString("android.useAndroidX", "true");
context.ANDROID_ENABLE_JETIFIER = project.config.getString("android.enableJetifier", "false");
context.ANDROID_LIBRARY_PROJECTS = [];
context.ANDROID_APPLICATION = project.config.getKeyValueArray("android.application", {
"android:label": project.meta.title,
"android:allowBackup": "true",
"android:theme": "@android:style/Theme.NoTitleBar" + (project.window.fullscreen ? ".Fullscreen" : null),
"android:hardwareAccelerated": "true",
"android:allowNativeHeapPointerTagging": context.ANDROID_TARGET_SDK_VERSION >= 30 ? "false" : null
});
context.ANDROID_ACTIVITY = project.config.getKeyValueArray("android.activity", {
"android:name": "MainActivity",
"android:exported": "true",
"android:launchMode": "singleTask",
"android:label": project.meta.title,
"android:configChanges": project.config.getArrayString("android.configChanges", ["keyboardHidden", "orientation", "screenSize", "screenLayout", "uiMode"]).join("|"),
"android:screenOrientation": project.window.orientation == PORTRAIT ? "sensorPortrait" : (project.window.orientation == LANDSCAPE ? "sensorLandscape" : null)
});
if (!project.environment.exists("ANDROID_SDK") || !project.environment.exists("ANDROID_NDK_ROOT"))
{
@@ -505,6 +519,7 @@ class AndroidPlatform extends PlatformTarget
"KEY_STORE_ALIAS_PASSWORD")) context.KEY_STORE_ALIAS_PASSWORD = StringTools.replace(context.KEY_STORE_ALIAS_PASSWORD, "\\", "\\\\");
var index = 1;
context.ANDROID_LIBRARY_PROJECTS = [];
for (dependency in project.dependencies)
{
@@ -528,24 +543,38 @@ class AndroidPlatform extends PlatformTarget
}
}
var iconTypes = ["ldpi", "mdpi", "hdpi", "xhdpi", "xxhdpi", "xxxhdpi"];
var iconSizes = [36, 48, 72, 96, 144, 192];
var icons = project.icons;
if (icons.length == 0)
for (attribute in context.ANDROID_APPLICATION)
{
icons = [new Icon(System.findTemplate(project.templatePaths, "default/icon.svg"))];
}
for (i in 0...iconTypes.length)
{
if (IconHelper.createIcon(icons, iconSizes[i], iconSizes[i], sourceSet + "/res/drawable-" + iconTypes[i] + "/icon.png"))
if (attribute.key == "android:icon")
{
context.HAS_ICON = true;
break;
}
}
IconHelper.createIcon(icons, 732, 412, sourceSet + "/res/drawable-xhdpi/ouya_icon.png");
if (context.HAS_ICON == null)
{
var iconTypes = ["ldpi", "mdpi", "hdpi", "xhdpi", "xxhdpi", "xxxhdpi"];
var iconSizes = [36, 48, 72, 96, 144, 192];
var icons = project.icons;
if (icons.length == 0)
{
icons = [new Icon(System.findTemplate(project.templatePaths, "default/icon.svg"))];
}
for (i in 0...iconTypes.length)
{
// create multiple icons, only set "android:icon" once
if (IconHelper.createIcon(icons, iconSizes[i], iconSizes[i], sourceSet + "/res/drawable-" + iconTypes[i] + "/icon.png")
&& !context.HAS_ICON)
{
context.HAS_ICON = true;
context.ANDROID_APPLICATION.push({ key: "android:icon", value: "@drawable/icon" });
}
}
IconHelper.createIcon(icons, 732, 412, sourceSet + "/res/drawable-xhdpi/ouya_icon.png");
}
var packageDirectory = project.meta.packageName;
packageDirectory = sourceSet + "/java/" + packageDirectory.split(".").join("/");