Skip to content

Commit

Permalink
[UI] android.app.NativeActivity > WindowedAppActivity + code style
Browse files Browse the repository at this point in the history
  • Loading branch information
Triang3l committed Sep 18, 2021
1 parent 347c9f0 commit 26a2d81
Show file tree
Hide file tree
Showing 10 changed files with 377 additions and 106 deletions.
5 changes: 5 additions & 0 deletions .clang-format
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,8 @@ SortIncludes: true

# Regroup causes unnecessary noise due to clang-format bug.
IncludeBlocks: Preserve

---
Language: Java
DisableFormat: true
SortIncludes: false
25 changes: 19 additions & 6 deletions android/android_studio_project/app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,23 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="jp.xenia.emulator">

<uses-feature android:name="android.hardware.vulkan.level" android:version="0" android:required="true" />
<uses-feature android:name="android.hardware.vulkan.version" android:version="0x400000" android:required="true" />
<!-- Granted automatically - guest sockets -->
<uses-feature
android:name="android.hardware.vulkan.level"
android:required="true"
android:version="0" />

<uses-feature
android:name="android.hardware.vulkan.version"
android:required="true"
android:version="0x400000" />

<!-- Granted automatically - guest sockets. -->
<uses-permission android:name="android.permission.INTERNET" />
<!-- Needs to be requested - loading games from outside the app data directory -->
<!-- WRITE_EXTERNAL_STORAGE is not required to write to the external app data directory since API 19 -->

<!--
Needs to be requested - loading games from outside the app data directory.
WRITE_EXTERNAL_STORAGE is not required to write to the external app data directory since API 19.
-->
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />

<application
Expand All @@ -17,12 +28,14 @@
android:roundIcon="@mipmap/ic_launcher_round"
android:supportsRtl="true"
android:theme="@android:style/Theme.Material.Light">
<activity android:name="jp.xenia.emulator.DemoActivity">

<activity android:name="jp.xenia.emulator.WindowDemoActivity">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
</activity>

</application>

</manifest>

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package jp.xenia.emulator;

public class WindowDemoActivity extends WindowedAppActivity {
@Override
protected String getWindowedAppIdentifier() {
return "xenia_ui_window_vulkan_demo";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package jp.xenia.emulator;

import android.app.Activity;
import android.content.res.AssetManager;
import android.os.Bundle;
import android.util.Log;

public abstract class WindowedAppActivity extends Activity {
private static final String TAG = "WindowedAppActivity";

static {
// TODO(Triang3l): Move all demos to libxenia.so.
System.loadLibrary("xenia-ui-window-vulkan-demo");
}

private long mAppContext;

private native long initializeWindowedAppOnCreateNative(
String windowedAppIdentifier, AssetManager assetManager);

private native void onDestroyNative(long appContext);

protected abstract String getWindowedAppIdentifier();

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);

mAppContext = initializeWindowedAppOnCreateNative(getWindowedAppIdentifier(), getAssets());
if (mAppContext == 0) {
Log.e(TAG, "Error initializing the windowed app");
finish();
return;
}
}

@Override
protected void onDestroy() {
if (mAppContext != 0) {
onDestroyNative(mAppContext);
}
mAppContext = 0;
super.onDestroy();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,6 @@
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context="jp.xenia.emulator.DemoActivity">
tools:context="jp.xenia.emulator.WindowDemoActivity">

</RelativeLayout>
25 changes: 25 additions & 0 deletions src/xenia/ui/windowed_app.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
/**
******************************************************************************
* Xenia : Xbox 360 Emulator Research Project *
******************************************************************************
* Copyright 2021 Ben Vanik. All rights reserved. *
* Released under the BSD license - see LICENSE in the root for more details. *
******************************************************************************
*/

#include "xenia/ui/windowed_app.h"

#include <string>
#include <unordered_map>

namespace xe {
namespace ui {

#if XE_UI_WINDOWED_APPS_IN_LIBRARY
// A zero-initialized pointer to remove dependence on the initialization order
// of the map relatively to the app creator proxies.
std::unordered_map<std::string, WindowedApp::Creator>* WindowedApp::creators_;
#endif // XE_UI_WINDOWED_APPS_IN_LIBRARY

} // namespace ui
} // namespace xe
77 changes: 61 additions & 16 deletions src/xenia/ui/windowed_app.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,17 @@
#include <cstddef>
#include <memory>
#include <string>
#include <unordered_map>
#include <utility>
#include <vector>

#include "xenia/base/assert.h"
#include "xenia/base/platform.h"
#include "xenia/ui/windowed_app_context.h"

#if XE_PLATFORM_ANDROID
#include <android/native_activity.h>

#include "xenia/ui/windowed_app_context_android.h"
// Multiple apps in a single library instead of separate executables.
#define XE_UI_WINDOWED_APPS_IN_LIBRARY 1
#endif

namespace xe {
Expand All @@ -36,6 +38,9 @@ class WindowedApp {
// initialization of platform-specific parts, should preferably be as simple
// as possible).

using Creator = std::unique_ptr<xe::ui::WindowedApp> (*)(
xe::ui::WindowedAppContext& app_context);

WindowedApp(const WindowedApp& app) = delete;
WindowedApp& operator=(const WindowedApp& app) = delete;
virtual ~WindowedApp() = default;
Expand Down Expand Up @@ -101,27 +106,67 @@ class WindowedApp {
std::string name_;
std::string positional_options_usage_;
std::vector<std::string> positional_options_;

#if XE_UI_WINDOWED_APPS_IN_LIBRARY
public:
class CreatorRegistration {
public:
CreatorRegistration(const std::string_view identifier, Creator creator) {
if (!creators_) {
// Will be deleted by the last creator registration's destructor, no
// need for a library destructor.
creators_ = new std::unordered_map<std::string, WindowedApp::Creator>;
}
iterator_inserted_ = creators_->emplace(identifier, creator);
assert_true(iterator_inserted_.second);
}

~CreatorRegistration() {
if (iterator_inserted_.second) {
creators_->erase(iterator_inserted_.first);
if (creators_->empty()) {
delete creators_;
}
}
}

private:
std::pair<std::unordered_map<std::string, Creator>::iterator, bool>
iterator_inserted_;
};

static Creator GetCreator(const std::string& identifier) {
if (!creators_) {
return nullptr;
}
auto it = creators_->find(identifier);
return it != creators_->end() ? it->second : nullptr;
}

private:
static std::unordered_map<std::string, Creator>* creators_;
#endif // XE_UI_WINDOWED_APPS_IN_LIBRARY
};

#if XE_PLATFORM_ANDROID
// Multiple apps in a single library. ANativeActivity_onCreate chosen via
// android.app.func_name of the NativeActivity of each app.
#define XE_DEFINE_WINDOWED_APP(export_name, creator) \
__attribute__((visibility("default"))) extern "C" void export_name( \
ANativeActivity* activity, void* saved_state, size_t saved_state_size) { \
xe::ui::AndroidWindowedAppContext::StartAppOnActivityCreate( \
activity, saved_state, saved_state_size, creator); \
#if XE_UI_WINDOWED_APPS_IN_LIBRARY
// Multiple apps in a single library.
#define XE_DEFINE_WINDOWED_APP(identifier, creator) \
namespace xe { \
namespace ui { \
namespace windowed_app_creator_registrations { \
xe::ui::WindowedApp::CreatorRegistration identifier(#identifier, creator); \
} \
} \
}
#else
// Separate executables for each app.
std::unique_ptr<WindowedApp> (*GetWindowedAppCreator())(
WindowedAppContext& app_context);
#define XE_DEFINE_WINDOWED_APP(export_name, creator) \
std::unique_ptr<xe::ui::WindowedApp> (*xe::ui::GetWindowedAppCreator())( \
xe::ui::WindowedAppContext & app_context) { \
return creator; \
#define XE_DEFINE_WINDOWED_APP(identifier, creator) \
xe::ui::WindowedApp::Creator xe::ui::GetWindowedAppCreator() { \
return creator; \
}
#endif
#endif // XE_UI_WINDOWED_APPS_IN_LIBRARY

} // namespace ui
} // namespace xe
Expand Down
Loading

0 comments on commit 26a2d81

Please sign in to comment.