Commit Graph

13 Commits

Author SHA1 Message Date
Robert Bragg 57b5192366 Update examples
This updates both the examples to Gradle 9 and AGP 9.1

The examples are identical, except that `na-mainloop` is based on
NativeActivity and the `agdk-mainloop` based on GameActivity.

The examples demonstrate:
- Using the `jni` API to define enough bindings to be able to send a Toast
- Using an `android_on_create` entry point for logging initialization
  and JNI initialization
- Using `AndroidApp::run_on_java_main_thread()` to send a toast from the
  Java main / UI thread
- Running an `android_main` event loop, including printing historic
  pointer samples (a new 0.6.1 feature)

The examples support two input actions:
- Lifting your finger in the top-left corner of the screen will show the
  onscreen keyboard
- Lifting your finger in the top-right corner of the screen will hide
  the onscreen keyboard

If you edit and disable `configChanges` in `AndroidManifest.xml` then
these examples can also demonstrate that `android-activity` gracefully
handles repeated `Activity` create -> run -> destroy cycles.
2026-03-23 22:37:54 +00:00
Robert Bragg af331e3bff Rework input_events API and expose KeyCharacterMap bindings
With the way events are delivered via an `InputQueue` with
`NativeActivity` there is no direct access to the underlying KeyEvent
and MotionEvent Java objects and no `ndk` API that supports the
equivalent of `KeyEvent.getUnicodeChar()`

What `getUnicodeChar` does under the hood though is to do lookups into a
`KeyCharacterMap` for the corresponding `InputDevice` based on the
event's `key_code` and `meta_state` - which are things we can do via
some JNI bindings for `KeyCharacterMap`.

Although it's still awkward to expose an API like
`key_event.get_unicode_char()` we can instead provide an API that
lets you look up a `KeyCharacterMap` for any `device_id` and
applications can then use that for character mapping.

This approach is also more general than the `getUnicodeChar` utility
since it exposes other useful state, such as being able to check what
kind of keyboard input events are coming from (such as a full physical
keyboard vs a virtual / 'predictive' keyboard)

For consistency this exposes the same API through the game-activity
backend, even though the game-activity backend is technically able to
support unicode lookups via `getUnicodeChar` (since it has access to the
Java `KeyEvent` object).

This highlighted a need to be able to use other `AndroidApp` APIs while
processing input, which wasn't possible with the `.input_events()` API
design because the `AndroidApp` held a lock over the backend while
iterating events.

This changes `input_events()` to `input_events_iter()` which now returns
a form of lending iterator and instead of taking a callback that gets
called repeatedly by `input_events()` a similar callback is now passed
to `iter.next(callback)`.

The API isn't as ergonomic as I would have liked, considering that
lending iterators aren't a standard feature for Rust yet but also since
we still want to have the handling for each individual event go via a
callback that can report whether an event was "handled". I think the
slightly awkward ergonomics are acceptable though considering that
the API will generally be used as an implementation detail within
middleware frameworks like Winit.

Since this is the first example where we're creating non-trivial Java
bindings for an Android SDK API this adds some JNI utilities and
establishes a pattern for how we can implement a class binding.

It's an implementation detail but with how I wrote the binding I tried
to keep in mind the possibility of creating a procmacro later that would
generate some of the JNI boilerplate involved.
2023-08-07 18:36:50 +01:00
Robert Bragg cd81420638 Update agdk-mainloop 2023-06-26 00:08:42 +01:00
Robert Bragg 7cdb77eca4 Let applications report if they handled input events
The callback given to `AndroidApp::input_events()` is now expected to return
`InputStatus::Handled` or `InputStatus::Unhandled`.

When running with NativeActivity then if we know an input event hasn't been
handled we can notify the InputQueue which may result in fallback
handling.

Although the status is currently ignored with the GameActivity backend.

Since this is a breaking change that also affects the current Winit
backend this updates the winit based examples to stick with the 0.3
release of android-activity for now.

Fixes: #31
2022-09-20 00:14:38 +01:00
Robert Bragg a654f72f62 Expose the application Configuration by reference
This provides an API to access `Configuration` state for the application
without having to make deep copies of the large `Configuration` struct.

This should avoid the need for Winit to create a global static copy of
the Configuration whenever it changes - and instead it can just get
a `ConfigurationRef` which will always reflect the latest config for
the application.

Fixes: #5
2022-08-14 11:02:22 +01:00
Robert Bragg 3d1b1c5cb9 Supports InputAvailable events with GameActivity
This makes a small change to the C glue code for GameActivity to send
looper wake ups when new input is received (only sending a single wake
up, until the application next handles input).

When a wake up is received and we recognise that new input is available
then an `InputAvailable` event is sent to the application - consistent
with how NativeActivity can deliver `InputAvailable` events.

This addresses a significant feature disparity between GameActivity and
NativeActivity that meant GameActivity was not practically usable for
GUI applications that wouldn't want to render continuously like a game.

Addresses #4
2022-08-13 20:26:00 +01:00
Robert Bragg 0d0c10ebb2 Runs cargo fmt across everything 2022-08-11 23:16:55 +01:00
Robert Bragg 2264826535 Update examples to use android_activity 2022-07-03 22:18:46 +01:00
Robert Bragg d4459921b9 Remove global android_app() API
android_main() now takes an `app: AndroidApp` argument and has an
extern "Rust" ABI instead of "C" ABI.

This should help make it possible to run multiple native Activities in a
single process.
2022-07-03 22:18:45 +01:00
Robert Bragg 5d38fdf593 A few minor simplifications of the *-mainloop examples 2022-05-25 22:27:53 +01:00
Robert Bragg 164957ec65 game-activity: rework input API
This leaves the InputBuffer abstraction as an implementation detail
and just exposes an API like this for processing input:

  app.input_events(|event| {
      // handle event
  });

The main consideration here was to have an API that could also be
supported via NativeActivity to keep open the possibility of a standard
Android 'glue' API.
2022-05-20 02:46:01 +01:00
Robert Bragg 74e8ff645a Remove unused src/shader.wgsl from agdk-mainloop example 2022-05-10 03:08:56 +01:00
Robert Bragg 02dda282d0 Add basic agdk-mainloop example 2022-05-10 02:00:47 +01:00