gamnit :: gamnit_android $ GamnitDisplay
General display class, is sized and drawablegamnit :: gamnit_android $ NativeActivity
An activity, a single, focused thing a user can do on Androidgamnit :: gamnit_android $ GamnitDisplay
General display class, is sized and drawablegamnit :: gamnit_android $ NativeActivity
An activity, a single, focused thing a user can do on AndroidSerializable::inspect
to show more useful information
more_collections :: more_collections
Highly specific, but useful, collections-related classes.serialization :: serialization_core
Abstract services to serialize Nit objects to different formatscore :: union_find
union–find algorithm using an efficient disjoint-set data structuregamnit :: camera_control_android
Two fingers camera manipulation, pinch to zoom and slide to scroll
# Support services for Gamnit on Android
module gamnit_android is
android_api_min 15
android_api_target 15
android_manifest_activity """android:theme="@android:style/Theme.NoTitleBar.Fullscreen""""
android_manifest_activity """android:configChanges="orientation|screenSize|keyboard|keyboardHidden""""
end
import android
intrude import gamnit
intrude import android::input_events
import egl
private import realtime
# Print Android lifecycle events to the log?
fun print_lifecycle_events: Bool do return true
redef class App
# ---
# User inputs
redef fun feed_events do app.poll_looper 0
redef fun native_input_key(event) do return accept_event(event)
redef fun native_input_motion(event)
do
if not scene_created then return false
var ie = new AndroidMotionEvent(event)
var handled = accept_event(ie)
if not handled then accept_event ie.acting_pointer
return handled
end
# ---
# Handle OS lifecycle and set current state flag
# State between `init_window` and `term_window`
private var window_created = false
# State between `gained_focus` and `lost_focus`
private var focused = false
# State between `resume` and `pause`
private var resumed = false
# Stage after `destroy`
private var destroyed = false
redef fun init_window
do
if print_lifecycle_events then print "+ init_window"
window_created = true
set_active
super
end
redef fun term_window
do
if print_lifecycle_events then print "+ term_window"
window_created = false
set_inactive
super
end
redef fun resume
do
if print_lifecycle_events then print "+ resume"
resumed = true
set_active
super
end
redef fun pause
do
if print_lifecycle_events then print "+ pause"
resumed = false
set_inactive
super
end
redef fun gained_focus
do
if print_lifecycle_events then print "+ gained_focus"
focused = true
set_active
super
end
redef fun lost_focus
do
if print_lifecycle_events then print "+ lost_focus"
focused = false
super
end
redef fun destroy
do
if print_lifecycle_events then print "+ destroy"
destroyed = true
super
end
redef fun start
do
if print_lifecycle_events then print "+ start"
super
end
redef fun stop
do
if print_lifecycle_events then print "+ stop"
set_inactive
super
end
redef fun config_changed
do
if print_lifecycle_events then print "+ config_changed"
super
end
redef fun window_resized
do
if print_lifecycle_events then print "+ window_resized"
super
end
redef fun content_rect_changed
do
if print_lifecycle_events then print "+ content_rect_changed"
super
end
# ---
# Update gamnit app
# The app is fully visible and focused
private var active = false
# The scene was set up
private var scene_created = false
private fun set_active
do
assert not destroyed
if window_created and resumed and focused and not active then
var display = display
if display == null then
# Initial create
create_display
create_gamnit
display = self.display
else
# Try to reuse the EGL context
var native_window = app.native_app_glue.window
assert not native_window.address_is_null
var needs_recreate = display.check_egl_context(native_window)
if needs_recreate then
# Skip frame
if display.native_window_is_invalid then
print_error "the native window is invalid, skip frame"
return
end
# The context was lost, reload everything
create_gamnit
recreate_gamnit
end
end
# Update screen dimensions
assert display != null
display.update_size
app.on_resize display
if not scene_created then
# Initial launch
if debug_gamnit then print "set_active: create"
create_scene
scene_created = true
on_restore_state
else
# Next to first launch, reload
if debug_gamnit then print "set_active: recreate"
end
active = true
end
end
private fun set_inactive
do
active = false
end
# ---
# Implement gamnit entry points
redef fun recreate_gamnit
do
super
# Reload all textures
if debug_gamnit then print "recreate_gamnit: reloading {all_root_textures.length} textures"
for texture in all_root_textures do
if debug_gamnit then print "recreate_gamnit: loading {texture}"
texture.load true
var gamnit_error = texture.error
if gamnit_error != null then print_error gamnit_error
end
end
redef fun run
do
if debug_gamnit then print "run: start"
scene_created = false
while not destroyed do
if not active then
if debug_gamnit then print "run: wait"
app.poll_looper_pause -1
else
if debug_gamnit then print "run: frame"
var native_window = app.native_app_glue.window
assert not native_window.address_is_null
var display = display
assert display != null
var needs_recreate = display.check_egl_context(native_window)
if needs_recreate then
if display.native_window_is_invalid then
# This should be rare and may cause more issues, log it
print "The native window is invalid, skip frame"
set_inactive
continue
end
# The context was lost, reload everything
create_gamnit
recreate_gamnit
end
assert scene_created
frame_full
end
end
if debug_gamnit then print "run: exit"
exit 0
end
end
redef class GamnitDisplay
redef var width = 1080
redef var height = 720
# Update `width` and `height`
private fun update_size
do
var context = app.native_activity
self.width = context.window_width
self.height = context.window_height
end
end
redef class NativeActivity
private fun window_height: Int in "Java" `{
android.view.View view = self.getWindow().getDecorView();
return view.getBottom() - view.getTop();
`}
private fun window_width: Int in "Java" `{
android.view.View view = self.getWindow().getDecorView();
return view.getRight() - view.getLeft();
`}
private fun orientation: Int in "Java" `{
return self.getResources().getConfiguration().orientation;
`}
end
lib/gamnit/gamnit_android.nit:15,1--307,3