Support services for Gamnit on Android

Redefined classes

redef class App

gamnit :: gamnit_android $ App

App subclasses are cross-platform applications
redef class GamnitDisplay

gamnit :: gamnit_android $ GamnitDisplay

General display class, is sized and drawable
redef extern class NativeActivity

gamnit :: gamnit_android $ NativeActivity

An activity, a single, focused thing a user can do on Android
redef class Sys

gamnit :: gamnit_android $ Sys

The main class of the program.

All class definitions

redef class App

gamnit :: gamnit_android $ App

App subclasses are cross-platform applications
redef class GamnitDisplay

gamnit :: gamnit_android $ GamnitDisplay

General display class, is sized and drawable
redef extern class NativeActivity

gamnit :: gamnit_android $ NativeActivity

An activity, a single, focused thing a user can do on Android
redef class Sys

gamnit :: gamnit_android $ Sys

The main class of the program.
package_diagram gamnit::gamnit_android gamnit_android android android gamnit::gamnit_android->android gamnit gamnit gamnit::gamnit_android->gamnit android::input_events input_events gamnit::gamnit_android->android::input_events realtime realtime gamnit::gamnit_android->realtime gamnit::display_android display_android gamnit::gamnit_android->gamnit::display_android android->gamnit java java android->java app app android->app core core android->core mnit mnit android->mnit c c android->c json json android->json mnit::input input android::input_events->mnit::input android::game game android::input_events->android::game realtime->core gamnit::display_android->android::game android::load_image load_image gamnit::display_android->android::load_image gamnit::egl egl gamnit::display_android->gamnit::egl gamnit::textures textures gamnit::display_android->gamnit::textures ...java ... ...java->java ...app ... ...app->app ...core ... ...core->core ...mnit ... ...mnit->mnit ...c ... ...c->c ...gamnit ... ...gamnit->gamnit ...json ... ...json->json ...mnit::input ... ...mnit::input->mnit::input ...android::game ... ...android::game->android::game ...android::load_image ... ...android::load_image->android::load_image ...gamnit::egl ... ...gamnit::egl->gamnit::egl ...gamnit::textures ... ...gamnit::textures->gamnit::textures android::sensors sensors android::sensors->gamnit::gamnit_android gamnit::android19 android19 gamnit::android19->gamnit::gamnit_android gamnit::camera_control_android camera_control_android gamnit::camera_control_android->gamnit::gamnit_android a_star-m a_star-m a_star-m->android::sensors a_star-m->gamnit::android19 a_star-m->gamnit::camera_control_android a_star-m... ... a_star-m...->a_star-m

Ancestors

module abstract_collection

core :: abstract_collection

Abstract collection classes and services.
module abstract_text

core :: abstract_text

Abstract class for manipulation of sequences of characters
module activities

android :: activities

Android Activities wrapper
module app

app :: app

app.nit is a framework to create cross-platform applications
module app_base

app :: app_base

Base of the app.nit framework, defines App
module array

core :: array

This module introduces the standard array structure.
module assets

android :: assets

Implementation of app::assets
module assets

app :: assets

Portable services to load resources from the assets folder
module assets_and_resources

android :: assets_and_resources

Android Assets and Resources Management
module aware

android :: aware

Android compatibility module
module bitset

core :: bitset

Services to handle BitSet
module bytes

core :: bytes

Services for byte streams and arrays
module c

c :: c

Structures and services for compatibility with the C language
module caching

serialization :: caching

Services for caching serialization engines
module circular_array

core :: circular_array

Efficient data structure to access both end of the sequence.
module codec_base

core :: codec_base

Base for codecs to use with streams
module codecs

core :: codecs

Group module for all codec-related manipulations
module collection

core :: collection

This module define several collection classes.
module collections

java :: collections

Basic Java collections
module core

core :: core

Standard classes and methods used by default by Nit programs and libraries.
module dalvik

android :: dalvik

Java related services specific to Android and its Dalvik VM
module display

gamnit :: display

Abstract display services
module egl

egl :: egl

Interface between rendering APIs (OpenGL, OpenGL ES, etc.) and the native windowing system.
module egl

gamnit :: egl

Use of EGL to implement Gamnit on GNU/Linux and Android
module engine_tools

serialization :: engine_tools

Advanced services for serialization engines
module environ

core :: environ

Access to the environment variables of the process
module error

core :: error

Standard error-management infrastructure.
module exec

core :: exec

Invocation and management of operating system sub-processes.
module ffi_support

java :: ffi_support

Core supporting services for the FFI with Java
module file

core :: file

File manipulations (create, read, write, etc.)
module fixed_ints

core :: fixed_ints

Basic integers of fixed-precision
module fixed_ints_text

core :: fixed_ints_text

Text services to complement fixed_ints
module flat

core :: flat

All the array-based text representations
module game

android :: game

Android services and implementation of app.nit for gamnit and mnit
module gc

core :: gc

Access to the Nit internal garbage collection mechanism
module glesv2

glesv2 :: glesv2

OpenGL graphics rendering library for embedded systems, version 2.0
module hash_collection

core :: hash_collection

Introduce HashMap and HashSet.
module input

mnit :: input

Defines abstract classes for user and general inputs to the application.
module inspect

serialization :: inspect

Refine Serializable::inspect to show more useful information
module io

java :: io

Services from the java.io package
module iso8859_1

core :: iso8859_1

Codec for ISO8859-1 I/O
module java

java :: java

Supporting services for the FFI with Java and to access Java libraries
module jvm

jvm :: jvm

Java Virtual Machine invocation API and others services from the JNI C API
module kernel

core :: kernel

Most basic classes and methods.
module list

core :: list

This module handle double linked lists
module load_image

android :: load_image

Low-level services to load pixel data from the assets
module log

android :: log

Advanced Android logging services
module math

core :: math

Mathematical operations
module matrix

matrix :: matrix

Services for matrices of Float values
module meta

meta :: meta

Simple user-defined meta-level to manipulate types of instances as object.
module more_collections

more_collections :: more_collections

Highly specific, but useful, collections-related classes.
module native

core :: native

Native structures for text and bytes
module native_app_glue

android :: native_app_glue

Wrapper of the Android native_app_glue framework to implement app.nit
module numeric

core :: numeric

Advanced services for Numeric types
module platform

android :: platform

Triggers compilation for the android platform
module poset

poset :: poset

Pre order sets and partial order set (ie hierarchies)
module programs

gamnit :: programs

Services for graphical programs with shaders, attributes and uniforms
module protocol

core :: protocol

module queue

core :: queue

Queuing data structures and wrappers
module range

core :: range

Module for range of discrete objects.
module re

core :: re

Regular expression support for all services based on Pattern
module ropes

core :: ropes

Tree-based representation of a String.
module serialization

serialization :: serialization

General serialization services
module serialization_core

serialization :: serialization_core

Abstract services to serialize Nit objects to different formats
module sorter

core :: sorter

This module contains classes used to compare things and sorts arrays.
module stream

core :: stream

Input and output streams of characters
module text

core :: text

All the classes and methods related to the manipulation of text entities
module textures

gamnit :: textures

Load textures, create subtextures and manage their life-cycle
module time

core :: time

Management of time and dates
module union_find

core :: union_find

union–find algorithm using an efficient disjoint-set data structure
module utf8

core :: utf8

Codec for UTF-8 I/O

Parents

module android

android :: android

Android services and implementation of app.nit
module display_android

gamnit :: display_android

Gamnit display implementation for Android
module gamnit

gamnit :: gamnit

Game and multimedia framework for Nit
module input_events

android :: input_events

Pointer and hardware key events
module realtime

realtime :: realtime

Services to keep time of the wall clock time

Children

module android19

gamnit :: android19

Variation using features from Android API 19
module camera_control_android

gamnit :: camera_control_android

Two fingers camera manipulation, pinch to zoom and slide to scroll
module sensors

android :: sensors

Access Android sensors

Descendants

module a_star-m

a_star-m

# 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