This class is refined by platform modules and so App can be specialized directly in the user application code.
app :: App :: accelerometer
app :: App :: accelerometer=
app :: App :: accept_event
Hook to receive and respond toevent triggered by the user or system
			app :: App :: app_delegate=
Application interface to the iOS systemapp :: App :: asset_manager
Assets Manager used to manage resources placed in theassets folder of the app
			app :: App :: asset_manager=
Assets Manager used to manage resources placed in theassets folder of the app
			app :: App :: assets_dir
Path to the expected location of the asset folder of this programapp :: App :: assets_dir=
Path to the expected location of the asset folder of this programapp :: App :: config_changed
Notification from the Android framework, the current device configuration has changedapp :: App :: content_rect_changed
Notification from the Android framework, the content area of the window has changedapp :: App :: control_spacing=
Spacing between GTK controls, default at 2app :: App :: create_gamnit
Hook to setup the OpenGL context: compiling shaders, creating VBO, reloading textures, etc.app :: App :: data_store=
Services to store and load dataapp :: App :: default_mediaplayer
Returns the default MediaPlayer of the application.app :: App :: default_mediaplayer=
Returns the default MediaPlayer of the application.app :: App :: default_soundpool
Returns the default MediaPlayer of the application.app :: App :: default_soundpool=
Returns the default MediaPlayer of the application.app :: App :: defaultinit
app :: App :: did_enter_background
The application just left foreground it can be suspended at any timeapp :: App :: did_finish_launching_with_options
The application just launched but is not yet displayed to the userGamnitDisplay initialized by create_gamnit
			GamnitDisplay initialized by create_gamnit
			app :: App :: dynamic_resolution_ratio
Resolution of the dynamic screen as ratio of the real screen resolution.app :: App :: dynamic_resolution_ratio=
Resolution of the dynamic screen as ratio of the real screen resolution.app :: App :: eventqueue
app :: App :: eventqueue=
app :: App :: explosion_program
Graphics program to display blowing up particlesapp :: App :: explosion_program=
Graphics program to display blowing up particlesapp :: App :: frame_core
Core of the frame logic, executed only when the display is visibleapp :: App :: frame_core_depth
Draw all elements ofactors and then call frame_core_flat
			app :: App :: frame_core_draw
Draw the whole screen, allglDraw... calls should be executed here
			app :: App :: frame_core_dynamic_resolution_after
Draw the dynamic screen to the real screen ifdynamic_resolution_ratio != 1.0
			app :: App :: frame_core_dynamic_resolution_before
Prepare to draw to the dynamic screen ifdynamic_resolution_ratio != 1.0
			app :: App :: frame_core_shadow_debug
Draw the light view in the bottom left of the screen, for debugging onlyapp :: App :: frame_core_shadow_prep
Update the depth texture from the light point of viewapp :: App :: frame_core_stereoscopic
Split the screen in two, and callframe_core_depth for each eyes
			app :: App :: frame_core_ui_sprites
Draw UI sprites fromui_sprites
			app :: App :: frame_core_world_sprites
Draw world sprites fromsprites
			app :: App :: frame_full
Full frame logic, executed even if the display is not visibleapp :: App :: gained_focus
Notification from the Android framework,native_activity has gained focus
			app :: App :: gamepad_spritesheet
Textures used forDPad and available to clients
			app :: App :: gamepad_spritesheet=
Textures used forDPad and available to clients
			app :: App :: gyroscope=
app :: App :: handle_looper_event
Handle an event retrieved by theALooper and poll_looper without a callback
			app :: App :: init_window
Notification from the native_app glue framework, a new ANativeWindow is readyapp :: App :: input_changed
Notification from the Android framework,native_app_glue.input_queue has changed
			app :: App :: load_music_from_res
Same asload_music but load the sound from the res/raw folder
			app :: App :: load_sound_from_res
Same asload_sound but load the sound from the res/raw folder
			app :: App :: lost_focus
Notification from the Android framework,native_activity has lost focus
			app :: App :: low_memory
Notification from the Android framework, the system is running low on memoryapp :: App :: magnetic_field
app :: App :: magnetic_field=
app :: App :: max_dynamic_resolution_ratio
Maximum dynamic screen resolution, must be set before first drawapp :: App :: max_dynamic_resolution_ratio=
Maximum dynamic screen resolution, must be set before first drawapp :: App :: maximum_fps=
Limit the frame-rate to a given frequencyapp :: App :: min_dynamic_resolution_ratio
Minimum dynamic screen resolutionapp :: App :: min_dynamic_resolution_ratio=
Minimum dynamic screen resolutionapp :: App :: native_activity
Main Java Activity of this applicationapp :: App :: native_app_glue
The underlying implementation using the Android native_app_glue frameworkapp :: App :: native_context
Current reference context, either an activity or a serviceapp :: App :: native_header_bar=
GTK 3 header barapp :: App :: native_stack
RootGtkStack used to simulate the many app.nit windows
			app :: App :: native_stack=
RootGtkStack used to simulate the many app.nit windows
			app :: App :: native_window=
Single GTK window of this applicationapp :: App :: particle_systems
Enabled particle emittersapp :: App :: particle_systems=
Enabled particle emittersapp :: App :: poll_looper
Call theALooper_pollAll to retrieve events and callback the application
			app :: App :: poll_looper_pause
Call theALooper_pollOnce to retrieve at most one event and callback the application
			app :: App :: pop_window
Pop the currentwindow from the stack and show the previous one
			app :: App :: pressed_keys=
Currently pressed keysapp :: App :: proximity=
app :: App :: push_window
Makewindow visible and push it on the top of the window_stack
			app :: App :: resource_manager
Resource Manager used to manage resources placed in theres folder of the app
			app :: App :: resource_manager=
Resource Manager used to manage resources placed in theres folder of the app
			app :: App :: run_on_ui_thread
Platform specific service to executetask on the main/UI thread
			app :: App :: save_state
Notification from the Android framework to generate a new saved stateapp :: App :: selection_program
Program drawing selection values to the bufferapp :: App :: selection_program=
Program drawing selection values to the bufferapp :: App :: sensormanager
app :: App :: sensormanager=
app :: App :: sensors_support_enabled
app :: App :: sensors_support_enabled=
app :: App :: shadow_depth_texture_available
Isshadow_context.depth_texture ready to be used?
			app :: App :: shadow_resolution
Resolution of the shadow texture, defaults to 4096 pixelsapp :: App :: shadow_resolution=
Resolution of the shadow texture, defaults to 4096 pixelsapp :: App :: show_splash_screen
Displaytexture as a splash screen
			app :: App :: smoke_program
Graphics program to display particles slowly drifting upwardsapp :: App :: smoke_program=
Graphics program to display particles slowly drifting upwardsapp :: App :: start_activity
Execute the intent and launch the appropriate applicationapp :: App :: start_service
LaunchService in the background, it will be set as service when ready
			app :: App :: start_service
Start a service that will be running until thestop_service call
			app :: App :: static_program
Graphics program to display static non-moving particlesapp :: App :: static_program=
Graphics program to display static non-moving particlesapp :: App :: supports_shadows
Are shadows supported by the current hardware configuration?app :: App :: supports_shadows=
Are shadows supported by the current hardware configuration?app :: App :: term_window
Notification from the native_app glue framework, the existing window needs to be terminatedapp :: App :: ui_application=
Main graphical applicationapp :: App :: ui_camera=
Camera forui_sprites using an orthogonal view
			app :: App :: ui_sprites
UI sprites drawn as seen byui_camera, over world sprites
			app :: App :: ui_sprites=
UI sprites drawn as seen byui_camera, over world sprites
			app :: App :: visible_at
WhichActor is on screen at x, y?
			app :: App :: visible_in_center
WhichActor is at the center of the screen?
			app :: App :: will_enter_foreground
The application will enter the foregroundapp :: App :: will_finish_launching_with_options
The application is about to launchapp :: App :: will_resign_active
The application is about to move from active to inactive stateapp :: App :: will_terminate
The application is about to terminate (from a state other than suspended)app :: App :: window_redraw_needed
Notification from the Android framework, the current ANativeWindow must be redrawnapp :: App :: window_resized
Notification from the Android framework, the window has been resized.app :: App :: window_stack=
Stack of active windowsapp :: App :: world_camera
Camera for worldsprites and depth::actors with perspective
			app :: App :: world_camera=
Camera for worldsprites and depth::actors with perspective
			gamnit :: virtual_gamepad $ App :: accept_event
Hook to receive and respond toevent triggered by the user or system
			gamnit :: keys $ App :: accept_event
Hook to receive and respond toevent triggered by the user or system
			gamnit :: gamnit_android $ App :: config_changed
Notification from the Android framework, the current device configuration has changedgamnit :: gamnit_android $ App :: content_rect_changed
Notification from the Android framework, the content area of the window has changedgamnit :: depth $ App :: create_gamnit
Hook to setup the OpenGL context: compiling shaders, creating VBO, reloading textures, etc.gamnit :: dynamic_resolution $ App :: create_gamnit
Hook to setup the OpenGL context: compiling shaders, creating VBO, reloading textures, etc.gamnit :: shadow $ App :: create_gamnit
Hook to setup the OpenGL context: compiling shaders, creating VBO, reloading textures, etc.gamnit :: flat_core $ App :: create_gamnit
Hook to setup the OpenGL context: compiling shaders, creating VBO, reloading textures, etc.gamnit :: cardboard $ App :: create_scene
Hook for client programs to setup the scenegamnit :: depth $ App :: create_scene
Hook for client programs to setup the scenegamnit :: gamnit_android $ App :: destroy
Notification from the Android framework,native_activity is being destroyed
			gamnit :: gamnit_ios $ App :: did_finish_launching_with_options
The application just launched but is not yet displayed to the userios :: hello_ios $ App :: did_finish_launching_with_options
The application just launched but is not yet displayed to the userios :: ui $ App :: did_finish_launching_with_options
The application just launched but is not yet displayed to the usergamnit :: selection $ App :: frame_core
Core of the frame logic, executed only when the display is visiblegamnit :: flat_core $ App :: frame_core
Core of the frame logic, executed only when the display is visiblegamnit :: stereoscopic_view $ App :: frame_core_draw
Draw the whole screen, allglDraw... calls should be executed here
			gamnit :: depth $ App :: frame_core_draw
Draw the whole screen, allglDraw... calls should be executed here
			gamnit :: limit_fps $ App :: frame_full
Full frame logic, executed even if the display is not visiblegamnit :: gamnit_android $ App :: gained_focus
Notification from the Android framework,native_activity has gained focus
			android :: game $ App :: gained_focus
Notification from the Android framework,native_activity has gained focus
			android :: sensors $ App :: handle_looper_event
Handle an event retrieved by theALooper and poll_looper without a callback
			gamnit :: gamnit_android $ App :: init_window
Notification from the native_app glue framework, a new ANativeWindow is readyandroid :: input_events $ App :: init_window
Notification from the native_app glue framework, a new ANativeWindow is readyandroid :: game $ App :: init_window
Notification from the native_app glue framework, a new ANativeWindow is readygamnit :: gamnit_android $ App :: lost_focus
Notification from the Android framework,native_activity has lost focus
			android :: game $ App :: lost_focus
Notification from the Android framework,native_activity has lost focus
			android :: native_app_glue $ App :: native_activity
Main Java Activity of this applicationandroid :: nit_activity $ App :: native_activity
The main Java Activity of this applicationandroid :: service $ App :: native_context
Prioritize an activity context if one is running, fallback on a servicegamnit :: dynamic_resolution $ App :: on_resize
The window has been resized by the user or systemapp :: ui $ App :: on_restore_state
The application is launching, restore its state from a previouson_save_state
			app :: ui $ App :: on_save_state
The application may be destroyed soon, save its state for a futureon_restore_state
			gamnit :: gamnit_android $ App :: pause
Notification from the Android framework, your app has been pausedios :: ui $ App :: push_window
Makewindow visible and push it on the top of the window_stack
			gamnit :: gamnit_android $ App :: recreate_gamnit
Hook to prepare for recreating the OpenGL contextgamnit :: gamnit_android $ App :: resume
Notification from the Android framework,native_activity has been resumed
			gamnit :: gamnit_ios $ App :: run
Disable the game loop to rely on the GLKView callbacks on each frame insteadios :: http_request $ App :: run_on_ui_thread
Platform specific service to executetask on the main/UI thread
			linux :: http_request $ App :: run_on_ui_thread
Platform specific service to executetask on the main/UI thread
			android :: http_request $ App :: run_on_ui_thread
Platform specific service to executetask on the main/UI thread
			android :: game $ App :: save_state
Notification from the Android framework to generate a new saved stateandroid :: native_app_glue $ App :: setup
Starts the internal setup of graphical and other stuffandroid :: nit_activity $ App :: setup
Starts the internal setup of graphical and other stuffgamnit :: gamnit_android $ App :: start
Notification from the Android framework,native_activity has been started
			gamnit :: gamnit_android $ App :: stop
Notification from the Android framework, your app has been stoppedgamnit :: gamnit_android $ App :: term_window
Notification from the native_app glue framework, the existing window needs to be terminatedandroid :: game $ App :: term_window
Notification from the native_app glue framework, the existing window needs to be terminatedgamnit :: gamnit_android $ App :: window_resized
Notification from the Android framework, the window has been resized.app :: App :: accelerometer
app :: App :: accelerometer=
app :: App :: accept_event
Hook to receive and respond toevent triggered by the user or system
			app :: App :: app_delegate=
Application interface to the iOS systemapp :: App :: asset_manager
Assets Manager used to manage resources placed in theassets folder of the app
			app :: App :: asset_manager=
Assets Manager used to manage resources placed in theassets folder of the app
			app :: App :: assets_dir
Path to the expected location of the asset folder of this programapp :: App :: assets_dir=
Path to the expected location of the asset folder of this programcore :: Object :: class_factory
Implementation used byget_class to create the specific class.
			app :: App :: config_changed
Notification from the Android framework, the current device configuration has changedapp :: App :: content_rect_changed
Notification from the Android framework, the content area of the window has changedapp :: App :: control_spacing=
Spacing between GTK controls, default at 2app :: App :: create_gamnit
Hook to setup the OpenGL context: compiling shaders, creating VBO, reloading textures, etc.app :: App :: data_store=
Services to store and load dataapp :: App :: default_mediaplayer
Returns the default MediaPlayer of the application.app :: App :: default_mediaplayer=
Returns the default MediaPlayer of the application.app :: App :: default_soundpool
Returns the default MediaPlayer of the application.app :: App :: default_soundpool=
Returns the default MediaPlayer of the application.core :: Object :: defaultinit
app :: App :: defaultinit
app :: AppComponent :: defaultinit
app :: AppObserver :: defaultinit
app :: App :: did_enter_background
The application just left foreground it can be suspended at any timeapp :: App :: did_finish_launching_with_options
The application just launched but is not yet displayed to the userGamnitDisplay initialized by create_gamnit
			GamnitDisplay initialized by create_gamnit
			app :: App :: dynamic_resolution_ratio
Resolution of the dynamic screen as ratio of the real screen resolution.app :: App :: dynamic_resolution_ratio=
Resolution of the dynamic screen as ratio of the real screen resolution.app :: App :: eventqueue
app :: App :: eventqueue=
app :: App :: explosion_program
Graphics program to display blowing up particlesapp :: App :: explosion_program=
Graphics program to display blowing up particlesapp :: App :: frame_core
Core of the frame logic, executed only when the display is visibleapp :: App :: frame_core_depth
Draw all elements ofactors and then call frame_core_flat
			app :: App :: frame_core_draw
Draw the whole screen, allglDraw... calls should be executed here
			app :: App :: frame_core_dynamic_resolution_after
Draw the dynamic screen to the real screen ifdynamic_resolution_ratio != 1.0
			app :: App :: frame_core_dynamic_resolution_before
Prepare to draw to the dynamic screen ifdynamic_resolution_ratio != 1.0
			app :: App :: frame_core_shadow_debug
Draw the light view in the bottom left of the screen, for debugging onlyapp :: App :: frame_core_shadow_prep
Update the depth texture from the light point of viewapp :: App :: frame_core_stereoscopic
Split the screen in two, and callframe_core_depth for each eyes
			app :: App :: frame_core_ui_sprites
Draw UI sprites fromui_sprites
			app :: App :: frame_core_world_sprites
Draw world sprites fromsprites
			app :: App :: frame_full
Full frame logic, executed even if the display is not visibleapp :: App :: gained_focus
Notification from the Android framework,native_activity has gained focus
			app :: App :: gamepad_spritesheet
Textures used forDPad and available to clients
			app :: App :: gamepad_spritesheet=
Textures used forDPad and available to clients
			app :: App :: gyroscope=
app :: App :: handle_looper_event
Handle an event retrieved by theALooper and poll_looper without a callback
			app :: App :: init_window
Notification from the native_app glue framework, a new ANativeWindow is readyapp :: App :: input_changed
Notification from the Android framework,native_app_glue.input_queue has changed
			core :: Object :: is_same_instance
Return true ifself and other are the same instance (i.e. same identity).
			core :: Object :: is_same_serialized
Isself the same as other in a serialization context?
			core :: Object :: is_same_type
Return true ifself and other have the same dynamic type.
			app :: App :: load_music_from_res
Same asload_music but load the sound from the res/raw folder
			app :: App :: load_sound_from_res
Same asload_sound but load the sound from the res/raw folder
			app :: App :: lost_focus
Notification from the Android framework,native_activity has lost focus
			app :: App :: low_memory
Notification from the Android framework, the system is running low on memoryapp :: App :: magnetic_field
app :: App :: magnetic_field=
app :: App :: max_dynamic_resolution_ratio
Maximum dynamic screen resolution, must be set before first drawapp :: App :: max_dynamic_resolution_ratio=
Maximum dynamic screen resolution, must be set before first drawapp :: App :: maximum_fps=
Limit the frame-rate to a given frequencyapp :: App :: min_dynamic_resolution_ratio
Minimum dynamic screen resolutionapp :: App :: min_dynamic_resolution_ratio=
Minimum dynamic screen resolutionapp :: App :: native_activity
Main Java Activity of this applicationapp :: App :: native_app_glue
The underlying implementation using the Android native_app_glue frameworkapp :: App :: native_context
Current reference context, either an activity or a serviceapp :: App :: native_header_bar=
GTK 3 header barapp :: App :: native_stack
RootGtkStack used to simulate the many app.nit windows
			app :: App :: native_stack=
RootGtkStack used to simulate the many app.nit windows
			app :: App :: native_window=
Single GTK window of this applicationapp :: AppComponent :: notify_observers
Propagateevent to all observers by calling AppObserver::on_event
			app :: AppComponent :: observers
AllAppObserver notified of events raised by self
			app :: AppComponent :: observers=
AllAppObserver notified of events raised by self
			app :: AppComponent :: on_pause
The application leaves the active state but is still partially visibleapp :: AppComponent :: on_restart
The application returns to a visible state from a previouson_stop
			app :: AppComponent :: on_restore_state
The application is launching, restore its state from a previouson_save_state
			app :: AppComponent :: on_resume
The application enters the active state, it is in the foreground and interactiveapp :: AppComponent :: on_save_state
The application may be destroyed soon, save its state for a futureon_restore_state
			app :: AppComponent :: on_start
The application is starting or restarting, it is visible to the usercore :: Object :: output_class_name
Display class name on stdout (debug only).app :: App :: particle_systems
Enabled particle emittersapp :: App :: particle_systems=
Enabled particle emittersapp :: App :: poll_looper
Call theALooper_pollAll to retrieve events and callback the application
			app :: App :: poll_looper_pause
Call theALooper_pollOnce to retrieve at most one event and callback the application
			app :: App :: pop_window
Pop the currentwindow from the stack and show the previous one
			app :: App :: pressed_keys=
Currently pressed keysapp :: App :: proximity=
app :: App :: push_window
Makewindow visible and push it on the top of the window_stack
			app :: App :: resource_manager
Resource Manager used to manage resources placed in theres folder of the app
			app :: App :: resource_manager=
Resource Manager used to manage resources placed in theres folder of the app
			app :: App :: run_on_ui_thread
Platform specific service to executetask on the main/UI thread
			app :: App :: save_state
Notification from the Android framework to generate a new saved stateapp :: App :: selection_program
Program drawing selection values to the bufferapp :: App :: selection_program=
Program drawing selection values to the bufferapp :: App :: sensormanager
app :: App :: sensormanager=
app :: App :: sensors_support_enabled
app :: App :: sensors_support_enabled=
app :: App :: shadow_depth_texture_available
Isshadow_context.depth_texture ready to be used?
			app :: App :: shadow_resolution
Resolution of the shadow texture, defaults to 4096 pixelsapp :: App :: shadow_resolution=
Resolution of the shadow texture, defaults to 4096 pixelsapp :: App :: show_splash_screen
Displaytexture as a splash screen
			app :: App :: smoke_program
Graphics program to display particles slowly drifting upwardsapp :: App :: smoke_program=
Graphics program to display particles slowly drifting upwardsapp :: App :: start_activity
Execute the intent and launch the appropriate applicationapp :: App :: start_service
Start a service that will be running until thestop_service call
			app :: App :: start_service
LaunchService in the background, it will be set as service when ready
			app :: App :: static_program
Graphics program to display static non-moving particlesapp :: App :: static_program=
Graphics program to display static non-moving particlesapp :: App :: supports_shadows
Are shadows supported by the current hardware configuration?app :: App :: supports_shadows=
Are shadows supported by the current hardware configuration?app :: App :: term_window
Notification from the native_app glue framework, the existing window needs to be terminatedapp :: App :: ui_application=
Main graphical applicationapp :: App :: ui_camera=
Camera forui_sprites using an orthogonal view
			app :: App :: ui_sprites
UI sprites drawn as seen byui_camera, over world sprites
			app :: App :: ui_sprites=
UI sprites drawn as seen byui_camera, over world sprites
			app :: App :: visible_at
WhichActor is on screen at x, y?
			app :: App :: visible_in_center
WhichActor is at the center of the screen?
			app :: App :: will_enter_foreground
The application will enter the foregroundapp :: App :: will_finish_launching_with_options
The application is about to launchapp :: App :: will_resign_active
The application is about to move from active to inactive stateapp :: App :: will_terminate
The application is about to terminate (from a state other than suspended)app :: App :: window_redraw_needed
Notification from the Android framework, the current ANativeWindow must be redrawnapp :: App :: window_resized
Notification from the Android framework, the window has been resized.app :: App :: window_stack=
Stack of active windowsapp :: App :: world_camera
Camera for worldsprites and depth::actors with perspective
			app :: App :: world_camera=
Camera for worldsprites and depth::actors with perspective
			app :: AppComponent
An element of an application that is notified of the application life cycle
# App subclasses are cross-platform applications
#
# This class is refined by platform modules and so
# App can be specialized directly in the user application code.
class App
	super AppComponent
	protected init do end
	# Starts the internal setup of graphical and other stuff
	# Is called just before run
	fun setup do end
	# Main entry point of your application
	fun run do end
end
					lib/app/app_base.nit:25,1--40,3
				
redef class App
	# Path to the expected location of the asset folder of this program
	#
	# The asset folder should be located relative to the executable at `../assets/`.
	# This value can be redefined to change the expected location.
	var assets_dir: String = sys.program_name.dirname / "../assets/" is lazy
	redef fun setup
	do
		super
		on_create
		on_restore_state
		on_resume
	end
	redef fun run
	do
		super
		on_pause
		on_save_state
		on_stop
	end
end
					lib/linux/linux.nit:23,1--47,3
				
redef class App
	# Main graphical application
	var ui_application: UIApplication
	# Application interface to the iOS system
	var app_delegate: AppDelegate
	# Copy back to C the command line arguments
	#
	# Nit extracts the first arguments from the `args` sequence,
	# so we need to add it back. That's why Nit's `args` is smaller than in C.
	private fun register_args(program_name: CString, argc: Int,
	argv: Sequence[String]) import Sequence[String].[], String.to_cstring in "ObjC" `{
		app_nit_ios_argc = (int)(argc+1);
		// TODO copy or pin the strings when needed
		app_nit_ios_argv = malloc(argc * sizeof(char*));
		app_nit_ios_argv[0] = program_name;
		for (int i = 0; i < argc; i ++) {
			String arg = Sequence_of_String__index(argv, i);
			app_nit_ios_argv[i+1] = String_to_cstring(arg);
		}
	`}
	# Register `self` globally in C so it can be retrieved from iOS callbacks
	private fun register_globally in "ObjC" `{
		App_incr_ref(self);
		app_nit_ios_app = self;
	`}
	# Entry point to the iOS framework
	private fun ui_application_main: Bool import did_finish_launching_with_options,
	will_finish_launching_with_options,
	will_resign_active, did_enter_background, will_enter_foreground,
	did_become_active, will_terminate, ui_application=, app_delegate= in "ObjC" `{
		@autoreleasepool {
			return UIApplicationMain(app_nit_ios_argc, app_nit_ios_argv,
				nil, NSStringFromClass([AppDelegate class]));
		}
	`}
	# The application is about to launch
	#
	# Redef this method to set the very first custom code to be executed.
	fun will_finish_launching_with_options: Bool do return true
	# The application just launched but is not yet displayed to the user
	#
	# Redef this method to customize the behavior.
	fun did_finish_launching_with_options: Bool
	do
		on_create
		on_restore_state
		return true
	end
	# The application is about to move from active to inactive state
	#
	# This can occur for certain types of temporary interruptions
	# (such as an incoming phone call or SMS message) or when the
	# user quits the application and it begins the transition to
	# the background state.
	#
	# Redef this method to pause ongoing tasks, disable timers, and
	# throttle down OpenGL ES frame rates. Games should use this
	# method to pause.
	fun will_resign_active do on_pause
	# The application just left foreground it can be suspended at any time
	#
	# Redef this method to release shared resources, save user data,
	# invalidate timers, and store application state to restore your
	# application to its current state in case it is terminated later.
	#
	# If your application supports background execution, this method
	# is called instead of `will_terminate` when the user quits.
	fun did_enter_background
	do
		on_save_state
		on_stop
	end
	# The application will enter the foreground
	#
	# Called as part of the transition from the background to the
	# inactive state.
	#
	# Redef to undo changes made on entering the background.
	fun will_enter_foreground do on_restart
	# The application just became active
	#
	# Redef to restart any tasks that were paused (or not yet started) while
	# the application was inactive. If the application was previously
	# in the background, optionally refresh the user interface.
	fun did_become_active do on_resume
	# The application is about to terminate (from a state other than suspended)
	#
	# Redef to save data if appropriate.
	fun will_terminate
	do
		# Usually a forced termination by the system
		on_save_state
		on_pause
		on_stop
	end
end
					lib/ios/app.nit:91,1--200,3
				
redef class App
	redef fun did_finish_launching_with_options
	do
		return app_delegate.hello_world
	end
end
					lib/ios/examples/hello_ios.nit:25,1--30,3
				
redef class App
	# Main Java Activity of this application
	#
	# Require: A Nit activity is currently running.
	fun native_activity: NativeActivity is abstract
	# Current reference context, either an activity or a service
	fun native_context: NativeContext do return native_activity
end
					lib/android/dalvik.nit:22,1--30,3
				
redef class App
	super AppComponent
	# The current `Window` of this activity
	#
	# This attribute is set by `push_window`.
	var window: Window is noinit
	# Make `window` visible and push it on the top of the `window_stack`
	#
	# This method can be called at any times while the app is active.
	fun push_window(window: Window)
	do
		window_stack.add window
		self.window = window
		window.on_create
	end
	# Pop the current `window` from the stack and show the previous one
	#
	# Require: `window_stack.not_empty`
	fun pop_window
	do
		assert window_stack.not_empty
		window_stack.pop
		window = window_stack.last
		window.on_resume
	end
	# Stack of active windows
	var window_stack = new Array[Window]
	redef fun on_create
	do
		var window = root_window
		push_window window
	end
	redef fun on_resume do window.on_resume
	redef fun on_pause do window.on_pause
	redef fun on_stop do window.on_stop
	redef fun on_restore_state do window.on_restore_state
	redef fun on_save_state do window.on_save_state
end
					lib/app/ui.nit:41,1--88,3
				
redef class App
	# Services to store and load data
	#
	# ~~~
	# import app::ui
	# import app::data_store
	#
	# class MyWindow
	#     super Window
	#
	#     var state = "Simple string or any serializable class"
	#
	#     redef fun on_save_state do app.data_store["state"] = state
	#
	#     redef fun on_restore_state
	#     do
	#         var state = app.data_store["state"]
	#         if state isa String then self.state = state
	#     end
	# end
	# ~~~
	var data_store = new DataStore is lazy
end
					lib/app/data_store.nit:31,1--54,3
				
redef class App
	# Display a _toast_ with `message`, for longer if `is_long`
	fun toast(message: String, is_long: Bool)
	do
		var jstr = message.to_java_string
		native_toast(jstr, is_long, native_activity)
		jstr.delete_local_ref
	end
	private fun native_toast(message: JavaString, is_long: Bool, native_activity: NativeActivity) in "Java" `{
		final android.app.Activity context = native_activity;
		final CharSequence final_message = message;
		final int duration = is_long? Toast.LENGTH_LONG: Toast.LENGTH_SHORT;
		context.runOnUiThread(new Runnable() {
			@Override
			public void run()  {
				Toast toast = Toast.makeText(context, final_message, duration);
				toast.show();
			}
		});
	`}
end
					lib/android/toast.nit:26,1--48,3
				
redef class App
	# Get the handle to this device vibrator as a global ref
	var vibrator: Vibrator is lazy do
		var v = vibrator_native(native_context)
		return v.new_global_ref
	end
	private fun vibrator_native(context: NativeContext): Vibrator in "Java" `{
		android.os.Vibrator v = (android.os.Vibrator)
			context.getSystemService(android.content.Context.VIBRATOR_SERVICE);
		return v;
	`}
end
					lib/android/vibration.nit:49,1--60,3
				
redef class App
	# Resource Manager used to manage resources placed in the `res` folder of the app
	var resource_manager: ResourcesManager is lazy do
		var res = native_context.resources
		var pkg = native_context.package_name
		return new ResourcesManager.native(res, pkg.to_s)
	end
	# Assets Manager used to manage resources placed in the `assets` folder of the app
	var asset_manager: AssetManager is lazy do return new AssetManager
end
					lib/android/assets_and_resources.nit:404,1--414,3
				
redef class App
	# Platform specific service to execute `task` on the main/UI thread
	fun run_on_ui_thread(task: Task) is abstract
end
					lib/app/http_request.nit:43,1--46,3
				
redef class App
	# Main `GamnitDisplay` initialized by `create_gamnit`
	var display: nullable GamnitDisplay = null
	# Hook to setup the OpenGL context: compiling shaders, creating VBO, reloading textures, etc.
	#
	# The gamnit services redefine this method to prepare optimizations and more.
	# Clients may also refine this method to prepare custom OpenGL resources.
	fun create_gamnit do end
	# Hook to prepare for recreating the OpenGL context
	#
	# Some gamnit services refine this method to reset caches before the
	# next call to `create_gamnit`.
	fun recreate_gamnit do end
	# Create and set `self.display`
	fun create_display
	do
		var display = new GamnitDisplay
		display.setup
		self.display = display
		# Print the current GL configuration, for debugging
		print "GL vendor: {glGetString(gl_VENDOR)}"
		print "GL renderer: {glGetString(gl_RENDERER)}"
		print "GL version: {glGetString(gl_VERSION)}"
		print "GLSL version: {glGetString(gl_SHADING_LANGUAGE_VERSION)}"
		print "GL extensions: {glGetString(gl_EXTENSIONS)}"
		print "GL max texture size: {glGetIntegerv(gl_MAX_TEXTURE_SIZE, 0)}"
	end
	# Hook for client programs to setup the scene
	#
	# Refine this method to build the game world or the main menu,
	# creating instances of `Sprite` and `Actor` as needed.
	#
	# This method is called only once per execution of the program and it should
	# be considered as the entry point of most game logic.
	fun create_scene do end
	# Core of the frame logic, executed only when the display is visible
	#
	# This method should be redefined by user modules to customize the behavior of the game.
	protected fun frame_core(display: GamnitDisplay) do end
	# Full frame logic, executed even if the display is not visible
	#
	# This method wraps `frame_core` and other services to be executed in the main app loop.
	#
	# To customize the behavior on each turn, it is preferable to redefined `frame_core`.
	# Still, `frame_full` can be redefined with care for more control.
	protected fun frame_full
	do
		var display = display
		if display != null then frame_core(display)
		feed_events
	end
	redef fun run
	do
		# TODO manage exit condition
		loop frame_full
	end
	# Loop on available events and feed them back to the app
	#
	# The implementation varies per platform.
	private fun feed_events do end
	# Hook to receive and respond to `event` triggered by the user or system
	#
	# Returns whether or not the event is used or intercepted.
	# If `true`, the event will not be processed further by the system.
	# Returns `false` to intercepts events like the back key on mobile devices.
	#
	# The instances passed as `event` may be freed (or overwritten),
	# right after this method returns. They should not be preserved.
	fun accept_event(event: InputEvent): Bool do return false
	# The window has been resized by the user or system
	#
	# The framework handles resizing the viewport automatically.
	fun on_resize(display: GamnitDisplay) do end
end
					lib/gamnit/gamnit.nit:29,1--115,3
				
redef class App
	redef fun setup
	do
		var native_app_glue = native_app_glue
		native_app_glue.user_data = self
		set_as_cmd_handler(native_app_glue)
	end
	# The underlying implementation using the Android native_app_glue framework
	fun native_app_glue: NativeAppGlue `{ return native_app_glue_data; `}
	redef fun native_activity do return native_app_glue.ndk_native_activity.java_native_activity
	# Set `native_app_glue` command handler to our C implementation which
	# will callback self.
	private fun set_as_cmd_handler(native_app_glue: NativeAppGlue) import save_state,
		init_window, term_window, gained_focus, lost_focus, pause, stop, destroy,
		start, resume, low_memory, config_changed, input_changed, window_resized,
		window_redraw_needed, content_rect_changed `{
		native_app_glue->onAppCmd = &app_cmd_handler;
	`}
	# Notification from the Android framework to generate a new saved state
	#
	# You can use the `shared_preferences` module or `NativeAppGlue::saved_state`.
	fun save_state do end
	# Notification from the native_app glue framework, a new ANativeWindow is ready
	#
	# When called, `NativeAppGlue::window` returns a poiter to the new window surface.
	fun init_window do end
	# Notification from the native_app glue framework, the existing window needs to be terminated
	#
	# Upon receiving this command, `native_app_glue.window` still contains the existing window.
	fun term_window do end
	# Notification from the Android framework, `native_activity` has gained focus
	fun gained_focus do end
	# Notification from the Android framework, `native_activity` has lost focus
	fun lost_focus do end
	# Notification from the Android framework, your app has been paused
	fun pause do end
	# Notification from the Android framework, your app has been stopped
	fun stop do end
	# Notification from the Android framework, `native_activity` is being destroyed
	#
	# Clean up and exit.
	fun destroy do end
	# Notification from the Android framework, `native_activity` has been started
	fun start do end
	# Notification from the Android framework, `native_activity` has been resumed
	fun resume do end
	# Notification from the Android framework, the system is running low on memory
	#
	# Try to reduce your memory use.
	fun low_memory do force_garbage_collection
	# Notification from the Android framework, the current device configuration has changed
	fun config_changed do end
	# Notification from the Android framework, `native_app_glue.input_queue` has changed
	fun input_changed do end
	# Notification from the Android framework, the window has been resized.
	#
	# Please redraw with its new size.
	fun window_resized do end
	# Notification from the Android framework, the current ANativeWindow must be redrawn
	fun window_redraw_needed do end
	# Notification from the Android framework, the content area of the window has changed
	#
	# Raised when the soft input window being shown or hidden, and similar events.
	fun content_rect_changed do end
	# Call the `ALooper_pollAll` to retrieve events and callback the application
	fun poll_looper(timeout_ms: Int) import handle_looper_event `{
		int ident;
		int event;
		void* source;
		while ((ident=ALooper_pollAll(timeout_ms, NULL, &event, &source)) >= 0) {
			App_handle_looper_event(self, ident, event, source);
		}
	`}
	# Call the `ALooper_pollOnce` to retrieve at most one event and callback the application
	fun poll_looper_pause(timeout_ms: Int) import handle_looper_event `{
		int event;
		void* source;
		int ident = ALooper_pollOnce(timeout_ms, NULL, &event, &source);
		if (ident >= 0) {
			App_handle_looper_event(self, ident, event, source);
		}
	`}
	# Handle an event retrieved by the `ALooper` and `poll_looper` without a callback
	protected fun handle_looper_event(ident, event: Int, data: Pointer) import native_app_glue,
		save_state, init_window, term_window, gained_focus, lost_focus, pause, stop,
		destroy, start, resume, low_memory, config_changed, input_changed,
		window_resized, window_redraw_needed, content_rect_changed `{
		struct android_app *app_glue = App_native_app_glue(self);
		struct android_poll_source* source = (struct android_poll_source*)data;
		// Process this event.
		if (source != NULL) source->process(app_glue, source);
	`}
end
					lib/android/native_app_glue.nit:148,1--265,3
				
redef class App
	# Returns the default MediaPlayer of the application.
	# When you load a music, it goes in this MediaPlayer.
	# Use it for advanced sound management
	var default_mediaplayer: MediaPlayer is lazy do return new MediaPlayer
	# Returns the default MediaPlayer of the application.
	# When you load a short sound (not a music), it's added to this soundpool.
	# Use it for advanced sound management.
	var default_soundpool: SoundPool is lazy do return new SoundPool
	# Get the native audio manager
	private fun audio_manager(native_activity: NativeContext): NativeAudioManager in "Java" `{
		return (AudioManager)native_activity.getSystemService(Context.AUDIO_SERVICE);
	`}
	# Sets the stream of the app to STREAM_MUSIC.
	# STREAM_MUSIC is the default stream used by android apps.
	private fun manage_audio_stream(native_activity: NativeActivity) in "Java" `{
		native_activity.setVolumeControlStream(AudioManager.STREAM_MUSIC);
	`}
	# Same as `load_sound` but load the sound from the `res/raw` folder
	fun load_sound_from_res(sound_name: String): Sound do
		return default_soundpool.load_name(resource_manager, native_activity, sound_name)
	end
	# Same as `load_music` but load the sound from the `res/raw` folder
	fun load_music_from_res(music: String): Music do
		return default_mediaplayer.load_sound(resource_manager.raw_id(music), native_activity)
	end
	redef fun on_pause do
		super
		for s in sounds do
			# Pausing sounds that are not already paused by user
			# `s.paused` is set to false because `pause` set it to true
			# and we want to know which sound has been paused by the user
			# and which one has been paused by the app
			if not s.paused then
				s.pause
				s.paused = false
			end
		end
		audio_manager(native_activity).abandon_audio_focus
	end
	redef fun on_create do
		super
		audio_manager(native_activity).request_audio_focus
		manage_audio_stream native_activity
	end
	redef fun on_resume do
		super
		audio_manager(native_activity).request_audio_focus
		for s in sounds do
			# Resumes only the sounds paused by the App
			if not s.paused then s.resume
		end
	end
end
					lib/android/audio.nit:670,1--732,3
				
redef class App
	# Currently pressed keys
	var pressed_keys = new Set[String] is lazy
	# Register `event` to update `app.pressed_keys`
	private fun register_key_event(event: KeyEvent)
	do
		var key = event.name
		if event.is_down then
			app.pressed_keys.add key
		else if app.pressed_keys.has(key) then
			app.pressed_keys.remove key
		end
	end
	redef fun accept_event(event)
	do
		if event isa KeyEvent then register_key_event event
		return super
	end
end
					lib/gamnit/keys.nit:48,1--69,3
				
redef class App
	# Limit the frame-rate to a given frequency
	#
	# This basically limits how much `frame_core` is called per second.
	# Zero (or a negative value) means no limit.
	#
	# Applications can modify this value even during the main-loop.
	var maximum_fps = 0.0 is writable
	# Current frame-rate
	#
	# Updated each 5 seconds, initialized at the value of `maximum_fps`.
	var current_fps: Float = maximum_fps is lazy
	redef fun frame_full
	do
		super
		limit_fps
	end
	# The clock for limit_fps
	private var clock = new Clock
	# Number of frames since the last deadline
	#
	# Used to compute `current_fps`.
	private var frame_count = 0
	# Deadline used to compute `current_fps`
	private var frame_count_deadline = 5.0
	# Check and sleep to maintain a frame-rate bellow `maximum_fps`
	#
	# Also periodically update `current_fps`
	# Is automatically called at the end of `full_frame`.
	fun limit_fps
	do
		var t = clock.total
		if t >= frame_count_deadline then
			var cfps = frame_count.to_f / 5.0
			self.current_fps = cfps
			frame_count = 0
			frame_count_deadline = t + 5.0
		end
		frame_count += 1
		var mfps = maximum_fps
		if mfps <= 0.0 then return
		var lapse = clock.lapse
		var dt = lapse.to_f
		var target_dt = 1.0 / mfps
		if dt < target_dt then
			var sleep_t = target_dt - dt
			sleep_t.sleep
			clock.lapse
		end
	end
end
					lib/gamnit/limit_fps.nit:21,1--78,3
				
redef class App
	# Resolution of the dynamic screen as ratio of the real screen resolution.
	#
	# - At 1.0, the default, the virtual screen is not used and the visuals are
	#   drawn directly to the real screen and pixels.
	# - When below 1.0, there is less pixels in the dynamic screen than in the
	#   real screen. This reduces the strain on the GPU, especially of high
	#   resolution displays.
	# - Values above 1.0 are not supported at this point, but they would allow
	#   super-sampling.
	#
	# This value must be set either by the user using a video quality slider or
	# by an heuristic according to the device capabilities.
	# A lower value should use less battery power on mobile devices.
	#
	# This value is applied to both X and Y, so it has an exponential effect on
	# the number of pixels.
	var dynamic_resolution_ratio = 1.0 is writable
	# Minimum dynamic screen resolution
	var min_dynamic_resolution_ratio = 0.0125 is writable
	# Maximum dynamic screen resolution, must be set before first draw
	var max_dynamic_resolution_ratio = 1.0 is writable
	private var dynres_program = new DynamicResolutionProgram
	private var perf_clock_dynamic_resolution = new Clock is lazy
	# Real screen framebuffer
	private var screen_framebuffer_cache: Int = -1
	# Real screen framebuffer name
	fun screen_framebuffer: Int
	do
		var cache = screen_framebuffer_cache
		if cache != -1 then return cache
		cache = glGetIntegerv(gl_FRAMEBUFFER_BINDING, 0)
		self.screen_framebuffer_cache = cache
		return cache
	end
	redef fun create_gamnit
	do
		super
		var program = dynres_program
		program.compile_and_link
		var error = program.error
		assert error == null else print_error error
		dynamic_context_cache = null
	end
	redef fun on_resize(display)
	do
		if dynamic_context_cache != null then dynamic_context.resize(display, max_dynamic_resolution_ratio)
		super
	end
	# Prepare to draw to the dynamic screen if `dynamic_resolution_ratio != 1.0`
	protected fun frame_core_dynamic_resolution_before(display: GamnitDisplay)
	do
		# TODO autodetect when to lower/increase resolution
		if dynamic_resolution_ratio == 1.0 then
			# Draw directly to the screen framebuffer
			bind_screen_framebuffer screen_framebuffer
			glViewport(0, 0, display.width, display.height)
			glClear gl_COLOR_BUFFER_BIT | gl_DEPTH_BUFFER_BIT
			assert glGetError == gl_NO_ERROR
			return
		end
		# Draw to our dynamic framebuffer
		glBindFramebuffer(gl_FRAMEBUFFER, dynamic_context.dynamic_framebuffer)
		var ratio = dynamic_resolution_ratio
		ratio = ratio.clamp(min_dynamic_resolution_ratio, max_dynamic_resolution_ratio)
		glViewport(0, 0, (display.width.to_f*ratio).to_i,
						 (display.height.to_f*ratio).to_i)
		glClear gl_COLOR_BUFFER_BIT | gl_DEPTH_BUFFER_BIT
		assert glGetError == gl_NO_ERROR
	end
	# Draw the dynamic screen to the real screen if `dynamic_resolution_ratio != 1.0`
	protected fun frame_core_dynamic_resolution_after(display: GamnitDisplay)
	do
		if dynamic_resolution_ratio == 1.0 then return
		perf_clock_dynamic_resolution.lapse
		var ratio = dynamic_resolution_ratio
		ratio = ratio.clamp(min_dynamic_resolution_ratio, max_dynamic_resolution_ratio)
		bind_screen_framebuffer screen_framebuffer
		glBindBuffer(gl_ARRAY_BUFFER, dynamic_context.buffer_array)
		glViewport(0, 0, display.width, display.height)
		glClear gl_COLOR_BUFFER_BIT | gl_DEPTH_BUFFER_BIT
		dynres_program.use
		# Uniforms
		glActiveTexture gl_TEXTURE0
		glBindTexture(gl_TEXTURE_2D, dynamic_context.texture)
		dynres_program.texture.uniform 0
		dynres_program.ratio.uniform ratio
		# Attributes
		var sizeof_gl_float = 4
		var n_floats = 3
		glEnableVertexAttribArray dynres_program.coord.location
		glVertexAttribPointeri(dynres_program.coord.location, n_floats, gl_FLOAT, false, 0, 0)
		var offset = 4 * n_floats * sizeof_gl_float
		n_floats = 2
		glEnableVertexAttribArray dynres_program.tex_coord.location
		glVertexAttribPointeri(dynres_program.tex_coord.location, n_floats, gl_FLOAT, false, 0, offset)
		assert glGetError == gl_NO_ERROR
		# Draw
		glDrawArrays(gl_TRIANGLE_STRIP, 0, 4)
		assert glGetError == gl_NO_ERROR
		# Take down
		glBindBuffer(gl_ARRAY_BUFFER, 0)
		assert glGetError == gl_NO_ERROR
		sys.perfs["gamnit flat dyn res"].add app.perf_clock_dynamic_resolution.lapse
	end
	# Framebuffer and texture for dynamic resolution intermediate drawing
	private fun dynamic_context: DynamicContext
	do
		var cache = dynamic_context_cache
		if cache != null then return cache
		cache = create_dynamic_context
		dynamic_context_cache = cache
		return cache
	end
	private var dynamic_context_cache: nullable DynamicContext = null
	private fun create_dynamic_context: DynamicContext
	do
		# TODO option or flag to regen on real resolution change.
		var display = display
		assert display != null
		var context = new DynamicContext
		context.prepare_once(display, max_dynamic_resolution_ratio)
		return context
	end
end
					lib/gamnit/dynamic_resolution.nit:28,1--185,3
				
redef class App
	redef fun run_on_ui_thread(task) do gdk_threads_add_idle task
end
					lib/linux/http_request.nit:22,1--24,3
				
redef class App
	private var sdl_event_buffer = new SDLEventBuffer.malloc
	redef fun feed_events
	do
		var display = display
		if display == null then return
		loop
			var avail = sdl_event_buffer.poll_event
			if not avail then break
			# Convert to an SDL event with data
			var sdl_event = sdl_event_buffer.to_event
			if sdl_event isa SDLWindowEvent and sdl_event.is_resized then
				display.width = sdl_event.data1
				display.height = sdl_event.data2
				display.aspect_ratio = sdl_event.data1.to_f / sdl_event.data2.to_f
				on_resize display
			end
			# Convert to `mnit::inputs` conforming objects
			var gamnit_event = sdl_event.to_gamnit_event(sdl_event_buffer)
			accept_event gamnit_event
		end
	end
	redef fun on_create
	do
		super
		create_display
		create_gamnit
		create_scene
	end
end
					lib/gamnit/gamnit_linux.nit:23,1--57,3
				
redef class App
	redef fun did_finish_launching_with_options
	do
		app_delegate.window = new UIWindow
		app_delegate.window.background_color = new UIColor.white_color
		super
		app_delegate.window.make_key_and_visible
		return true
	end
	private fun set_view_controller(window: UIWindow, native: UIViewController)
	in "ObjC" `{
		// Set the required root view controller
		UINavigationController *navController = (UINavigationController*)window.rootViewController;
		if (navController == NULL) {
			navController = [[UINavigationController alloc]initWithRootViewController:native];
			navController.edgesForExtendedLayout = UIRectEdgeNone;
			// Must be non-translucent for the controls to be placed under
			// (as in Y axis) of the navigation bar.
			navController.navigationBar.translucent = NO;
			window.rootViewController = navController;
		}
		else {
			[navController pushViewController:native animated:YES];
		}
		native.edgesForExtendedLayout = UIRectEdgeNone;
	`}
	redef fun push_window(window)
	do
		set_view_controller(app_delegate.window, window.native)
		super
	end
	# Use iOS ` popViewControllerAnimated`
	redef fun pop_window
	do
		manual_pop = true
		pop_view_controller app_delegate.window
		super
	end
	private fun pop_view_controller(window: UIWindow) in "ObjC" `{
		UINavigationController *navController = (UINavigationController*)window.rootViewController;
		[navController popViewControllerAnimated: YES];
	`}
	# Is the next `after_window_pop`  triggered by a call to `pop_window`?
	#
	# Otherwise, it's by the user via the navigation bar "Back" button.
	private var manual_pop = false
	# Callback when `window` is displayed again
	private fun after_window_pop
	do
		if not manual_pop then window_stack.pop
		manual_pop = false
		window.on_resume
	end
end
					lib/ios/ui/ui.nit:93,1--157,3
				
redef class App
	redef fun run_on_ui_thread(task) import Task.main in "ObjC" `{
		Task_incr_ref(task);
		dispatch_async(dispatch_get_main_queue(), ^{
			Task_main(task);
			Task_decr_ref(task);
		});
	`}
end
					lib/ios/http_request.nit:22,1--30,3
				
redef class App
	# Execute the intent and launch the appropriate application
	fun start_activity(intent: Intent) do native_context.start_activity(intent.intent)
	# Start a service that will be running until the `stop_service` call
	fun start_service(intent: Intent) do native_context.start_service(intent.intent)
	# Stop service
	fun stop_service(intent: Intent) do native_context.stop_service(intent.intent)
end
					lib/android/intent/intent_api10.nit:1332,1--1342,3
				
redef class App
	# Default graphic program to draw `sprites`
	private var simple_2d_program = new Simple2dProgram is lazy
	# Camera for world `sprites` and `depth::actors` with perspective
	#
	# By default, the camera is configured to a height of 1080 units
	# of world coordinates at `z == 0.0`.
	var world_camera: EulerCamera is lazy do
		var camera = new EulerCamera(app.display.as(not null))
		# Aim for full HD pixel resolution at level 0
		camera.reset_height 1080.0
		camera.near = 10.0
		return camera
	end
	# Camera for `ui_sprites` using an orthogonal view
	var ui_camera = new UICamera(app.display.as(not null)) is lazy
	# World sprites drawn as seen by `world_camera`
	var sprites = new SpriteSet
	# UI sprites drawn as seen by `ui_camera`, over world `sprites`
	var ui_sprites = new SpriteSet
	# Main method to refine in clients to update game logic and `sprites`
	fun update(dt: Float) do end
	# Display `texture` as a splash screen
	#
	# Load `texture` if needed and resets `ui_camera` to 1080 units on the Y axis.
	fun show_splash_screen(texture: Texture)
	do
		texture.load
		var splash = new Sprite(texture, ui_camera.center.offset(0.0, 0.0, 0.0))
		ui_sprites.add splash
		var display = display
		assert display != null
		glClear gl_COLOR_BUFFER_BIT
		ui_camera.reset_height 1080.0
		glViewport(0, 0, display.width, display.height)
		frame_core_ui_sprites display
		display.flip
		ui_sprites.remove splash
	end
	# ---
	# Support and implementation
	# Main clock used to count each frame `dt`, lapsed for `update` only
	private var clock = new Clock is lazy
	# Performance clock to for `frame_core_draw` operations
	private var perf_clock_main = new Clock
	# Second performance clock for smaller operations
	private var perf_clock_sprites = new Clock is lazy
	redef fun create_gamnit
	do
		super
		create_flat
	end
	# Prepare the flat framework services
	fun create_flat
	do
		var display = display
		assert display != null
		assert glGetError == gl_NO_ERROR
		# Prepare program
		var program = simple_2d_program
		program.compile_and_link
		var gamnit_error = program.error
		assert gamnit_error == null else print_error gamnit_error
		# Enable blending
		gl.capabilities.blend.enable
		glBlendFunc(gl_ONE, gl_ONE_MINUS_SRC_ALPHA)
		# Enable depth test
		gl.capabilities.depth_test.enable
		glDepthFunc gl_LEQUAL
		glDepthMask true
		# Prepare viewport and background color
		glViewport(0, 0, display.width, display.height)
		glClearColor(0.0, 0.0, 0.0, 1.0)
		assert glGetError == gl_NO_ERROR
		# Prepare to draw
		for tex in all_root_textures do
			tex.load
			gamnit_error = tex.error
			if gamnit_error != null then print_error gamnit_error
			glTexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MIN_FILTER, gl_LINEAR)
			glTexParameteri(gl_TEXTURE_2D, gl_TEXTURE_MAG_FILTER, gl_LINEAR)
		end
		sprites.reset
		ui_sprites.reset
	end
	redef fun on_stop
	do
		super
		# Close gamnit
		var display = display
		if display != null then display.close
	end
	redef fun on_resize(display)
	do
		super
		world_camera.mvp_matrix_cache = null
		ui_camera.mvp_matrix_cache = null
		# Update all sprites in the UI
		for sprite in ui_sprites do sprite.needs_update
	end
	redef fun on_resume
	do
		clock.lapse
		super
	end
	redef fun frame_core(display)
	do
		# Check errors
		assert glGetError == gl_NO_ERROR
		# Update game logic and set sprites
		perf_clock_main.lapse
		var dt = clock.lapse.to_f
		update dt
		frame_dt = dt
		sys.perfs["gamnit flat update client"].add perf_clock_main.lapse
		# Draw and flip screen
		frame_core_draw display
		display.flip
		# Check errors
		assert glGetError == gl_NO_ERROR
	end
	private var frame_dt = 0.0
	# Draw the whole screen, all `glDraw...` calls should be executed here
	protected fun frame_core_draw(display: GamnitDisplay)
	do
		frame_core_dynamic_resolution_before display
		perf_clock_main.lapse
		frame_core_world_sprites display
		perfs["gamnit flat world_sprites"].add perf_clock_main.lapse
		frame_core_ui_sprites display
		perfs["gamnit flat ui_sprites"].add perf_clock_main.lapse
		frame_core_dynamic_resolution_after display
	end
	private fun frame_core_sprites(display: GamnitDisplay, sprite_set: SpriteSet, camera: Camera)
	do
		var simple_2d_program = app.simple_2d_program
		simple_2d_program.use
		simple_2d_program.mvp.uniform camera.mvp_matrix
		sprite_set.time += frame_dt*sprite_set.time_mod
		simple_2d_program.time.uniform sprite_set.time
		# draw
		sprite_set.draw
		assert glGetError == gl_NO_ERROR
	end
	# Draw world sprites from `sprites`
	protected fun frame_core_world_sprites(display: GamnitDisplay)
	do
		frame_core_sprites(display, sprites, world_camera)
	end
	# Draw UI sprites from `ui_sprites`
	protected fun frame_core_ui_sprites(display: GamnitDisplay)
	do
		# Reset only the depth buffer
		glClear gl_DEPTH_BUFFER_BIT
		frame_core_sprites(display, ui_sprites, ui_camera)
	end
end
					lib/gamnit/flat/flat_core.nit:359,1--565,3
				
redef class App
	redef fun did_finish_launching_with_options
	do
		create_gamnit
		create_scene
		return super
	end
	# Disable the game loop to rely on the GLKView callbacks on each frame instead
	redef fun run do end
	private fun frame_full_indirect do frame_full
end
					lib/gamnit/gamnit_ios.nit:23,1--35,3
				
redef class App
	redef fun init_window
	do
		super
		on_create
		on_restore_state
	end
	redef fun term_window
	do
		super
		on_stop
	end
	# Is the application currently paused?
	var paused = true
	redef fun pause
	do
		paused = true
		on_pause
		super
	end
	redef fun resume
	do
		paused = false
		on_resume
		super
	end
	redef fun save_state do on_save_state
	redef fun lost_focus
	do
		paused = true
		super
	end
	redef fun gained_focus
	do
		paused = false
		super
	end
end
					lib/android/game.nit:24,1--68,3
				
redef class App
	redef fun init_window
	do
		set_as_input_handler native_app_glue
		super
	end
	private fun set_as_input_handler(app_glue: NativeAppGlue)
	import native_input_key, native_input_motion `{
		app_glue->onInputEvent = mnit_handle_input;
	`}
	# these are used as a callback from native to type incoming events
	private fun native_input_key(event: AndroidKeyEvent): Bool is abstract
	private fun native_input_motion(event: NativeAndroidMotionEvent): Bool is abstract
end
					lib/android/input_events.nit:257,1--274,3
				
redef class App
	# Known activities
	var activities = new Array[Activity]
	# The main Java Activity of this application
	redef fun native_activity do return activities.first.native
	redef fun setup do set_global_app
	# Register app in C
	private fun set_global_app import register_activity,
	Activity.on_create, Activity.on_destroy,
	Activity.on_start, Activity.on_restart, Activity.on_stop,
	Activity.on_pause, Activity.on_resume,
	Activity.on_save_instance_state, Activity.on_restore_instance_state,
	Activity.on_back_pressed,
	Activity.on_key_down, Activity.on_key_long_press,
	Activity.on_key_multiple, Activity.on_key_up `{
		App_incr_ref(self);
		global_app = self;
	`}
	# Create the Nit side to this new `native` Java activity, and return it to Java
	private fun register_activity(native: NativeNitActivity): Activity
	do
		native = native.new_global_ref
		var activity = new Activity(native)
		activities.add activity
		return activity
	end
end
					lib/android/nit_activity.nit:179,1--209,3
				
redef class App
	# Graphics program to display static non-moving particles
	var static_program = new ParticleProgram
	# Graphics program to display blowing up particles
	var explosion_program = new ExplosionProgram
	# Graphics program to display particles slowly drifting upwards
	var smoke_program = new SmokeProgram
	# Enabled particle emitters
	#
	# To be populated by the client program.
	var particle_systems = new Array[ParticleSystem]
end
					lib/gamnit/depth/particles.nit:40,1--55,3
				
redef class App
	# Resolution of the shadow texture, defaults to 4096 pixels
	#
	# TODO make configurable / ask the hardware for gl_MAX_TEXTURE_SIZE
	var shadow_resolution = 4096
	# Are shadows supported by the current hardware configuration?
	#
	# The implementation may change in the future, but it currently relies on
	# the GL extension `GL_EOS_depth_texture`.
	var supports_shadows: Bool is lazy do
		return display.as(not null).gl_extensions.has("GL_OES_depth_texture")
	end
	# Is `shadow_context.depth_texture` ready to be used?
	fun shadow_depth_texture_available: Bool
	do return supports_shadows and shadow_context.depth_texture != -1
	private var shadow_depth_program = new ShadowDepthProgram
	private var perf_clock_shadow = new Clock is lazy
	redef fun create_gamnit
	do
		super
		var program = shadow_depth_program
		program.compile_and_link
		var error = program.error
		assert error == null else print_error error
	end
	private var shadow_context: ShadowContext = create_shadow_context is lazy
	private fun create_shadow_context: ShadowContext
	do
		var display = display
		assert display != null
		var context = new ShadowContext
		context.prepare_once(display, shadow_resolution)
		return context
	end
	# Update the depth texture from the light point of view
	#
	# This method updates `shadow_context.depth_texture`.
	protected fun frame_core_shadow_prep(display: GamnitDisplay)
	do
		if not supports_shadows then return
		var light = app.light
		if not light isa LightCastingShadows then return
		# Make sure there's no errors pending
		assert glGetError == gl_NO_ERROR
		# Bind the framebuffer and make sure it is OK
		glBindFramebuffer(gl_FRAMEBUFFER, shadow_context.light_view_framebuffer)
		assert glGetError == gl_NO_ERROR
		assert glCheckFramebufferStatus(gl_FRAMEBUFFER) == gl_FRAMEBUFFER_COMPLETE
		# Draw to fill the depth texture and only the depth
		glViewport(0, 0, shadow_resolution, shadow_resolution)
		glColorMask(false, false, false, false)
		glClear gl_COLOR_BUFFER_BIT | gl_DEPTH_BUFFER_BIT
		assert glGetError == gl_NO_ERROR
		# Update light position
		var camera = light.camera
		camera.position.x = app.world_camera.position.x
		camera.position.y = app.world_camera.position.y
		camera.position.z = app.world_camera.position.z
		# Draw all actors
		for actor in actors do
			for leaf in actor.model.leaves do
				leaf.material.draw_depth(actor, leaf, camera)
			end
		end
		# Take down, bring back default values
		bind_screen_framebuffer shadow_context.screen_framebuffer
		glColorMask(true, true, true, true)
	end
	# ---
	# Debug: show light view in the bottom left of the screen
	# Lazy load the debugging program
	private var shadow_debug_program: LightPointOfViewProgram is lazy do
		var program = new LightPointOfViewProgram
		program.compile_and_link
		var error = program.error
		assert error == null else print_error error
		return program
	end
	# Draw the light view in the bottom left of the screen, for debugging only
	#
	# The shadow depth texture is a square that can be deformed by this projection.
	protected fun frame_core_shadow_debug(display: GamnitDisplay)
	do
		if not supports_shadows then
			print_error "Error: Shadows are not supported by the current hardware configuration"
			return
		end
		perf_clock_shadow.lapse
		var program = shadow_debug_program
		glBindBuffer(gl_ARRAY_BUFFER, shadow_context.buffer_array)
		glViewport(0, 0, display.width/3, display.height/3)
		glClear gl_DEPTH_BUFFER_BIT
		program.use
		# Uniforms
		glActiveTexture gl_TEXTURE0
		glBindTexture(gl_TEXTURE_2D, shadow_context.depth_texture)
		program.texture.uniform 0
		# Attributes
		var sizeof_gl_float = 4
		var n_floats = 3
		glEnableVertexAttribArray program.coord.location
		glVertexAttribPointeri(program.coord.location, n_floats, gl_FLOAT, false, 0, 0)
		var offset = 4 * n_floats * sizeof_gl_float
		n_floats = 2
		glEnableVertexAttribArray program.tex_coord.location
		glVertexAttribPointeri(program.tex_coord.location, n_floats, gl_FLOAT, false, 0, offset)
		var gl_error = glGetError
		assert gl_error == gl_NO_ERROR else print_error gl_error
		# Draw
		glDrawArrays(gl_TRIANGLE_STRIP, 0, 4)
		gl_error = glGetError
		assert gl_error == gl_NO_ERROR else print_error gl_error
		# Take down
		glBindBuffer(gl_ARRAY_BUFFER, 0)
		gl_error = glGetError
		assert gl_error == gl_NO_ERROR else print_error gl_error
		sys.perfs["gamnit shadow debug"].add app.perf_clock_shadow.lapse
	end
end
					lib/gamnit/depth/shadow.nit:32,1--180,3
				
redef class App
	redef fun setup do gtk_init
	# Single GTK window of this application
	var native_window: GtkWindow is lazy do
		var win = new GtkWindow(new GtkWindowType.toplevel)
		win.connect_destroy_signal_to_quit
		win.titlebar = native_header_bar
		win.add native_stack
		return win
	end
	# GTK 3 header bar
	var native_header_bar: GtkHeaderBar is lazy do
		var bar = new GtkHeaderBar
		bar.title = "app.nit" # TODO offer a portable API to name windows
		bar.show_close_button = true
		bar.add back_button.native
		return bar
	end
	# Root `GtkStack` used to simulate the many app.nit windows
	var native_stack: GtkStack is lazy do
		var stack = new GtkStack
		stack.homogeneous = false
		return stack
	end
	# Button on the header bar to go back
	var back_button = new BackButton is lazy
	# On GNU/Linux, we go through all the callbacks once,
	# there is no complex life-cycle.
	redef fun run
	do
		app.on_create
		app.on_restore_state
		app.on_resume
		gtk_main
		app.on_pause
		app.on_stop
		app.on_save_state
	end
	# Spacing between GTK controls, default at 2
	var control_spacing = 2 is writable
	redef fun window=(window)
	do
		var root_view = window.view
		assert root_view != null
		native_stack.add root_view.native
		native_stack.visible_child = root_view.native
		# FIXME These settings forces the GTK window to resize to its minimum
		# size when changing app.nit windows. It is not pretty, but it could be
		# improved with GTK 3.18 and interpolate_size.
		native_window.resizable = false
		native_window.show_all
		super
		if window.enable_back_button then
			back_button.native.show
		else back_button.native.hide
	end
end
					lib/linux/ui.nit:28,1--99,3
				
redef class App
	# Current instance of `Service`, if any
	var service: nullable Service = null
	# Launch `Service` in the background, it will be set as `service` when ready
	fun start_service do native_context.start_service
	# Register a service from Java/C
	#
	# FIXME remove when #1941 is fixed
	private fun register_service(java_service: NativeService): Service
	do
		return new Service(java_service.new_global_ref)
	end
	# Prioritize an activity context if one is running, fallback on a service
	redef fun native_context
	do
		if activities.not_empty then return super
		var service = service
		assert service != null
		return service.native
	end
	# Dummy method to force the compilation of callbacks from C
	#
	# The callbacks are used in the launch of a Nit service from C code.
	private fun force_service_callbacks_in_c import Service, register_service,
		Service.on_start_command, Service.on_create, Service.on_destroy, Service.native `{ `}
	redef fun setup
	do
		super
		# Call the dummy method to force their compilation in global compilation
		force_service_callbacks_in_c
	end
end
					lib/android/service/service.nit:69,1--108,3
				
redef class App
	# Current touch gamepad, still may be invisible
	var gamepad: nullable VirtualGamepad = null is writable
	# Textures used for `DPad` and available to clients
	var gamepad_spritesheet = new VirtualGamepadSpritesheet
	redef fun accept_event(event)
	do
		# Priority to the gamepad
		var gamepad = gamepad
		if gamepad != null and gamepad.accept_event(event) then return true
		return super
	end
end
					lib/gamnit/virtual_gamepad/virtual_gamepad.nit:58,1--74,3
				
redef class App
	private var blinn_phong_program = new BlinnPhongProgram is lazy
	private var normals_program = new NormalProgram is lazy
end
					lib/gamnit/depth/more_materials.nit:661,1--665,3
				
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
					lib/gamnit/gamnit_android.nit:34,1--276,3
				
redef class App
	# Which `Actor` is at the center of the screen?
	fun visible_in_center: nullable Actor
	do
		var display = display
		assert display != null
		return visible_at(display.width/2, display.height/2)
	end
	# Which `Actor` is on screen at `x, y`?
	fun visible_at(x, y: Numeric): nullable Actor
	do
		var display = display
		assert display != null
		if not selection_calculated then draw_selection_screen
		x = x.to_i
		y = y.to_i
		y = display.height - y
		# Read selection values
		var data = once new NativeCByteArray(4)
		glReadPixels(x, y, 1, 1, gl_RGBA, gl_UNSIGNED_BYTE, data)
		assert_no_gl_error
		var r = display.red_bits
		var g = display.green_bits
		var b = display.blue_bits
		# Rebuild ID from pixel color
		var rv = data[0].to_i >> (8-r)
		var gv = data[1].to_i >> (8-g) << (r)
		var bv = data[2].to_i >> (8-b) << (r+g)
		if data[0].to_i & (2**(8-r)-1) > (2**(8-r-1)) then rv += 1
		if data[1].to_i & (2**(8-g)-1) > (2**(8-g-1)) then gv += 1 << r
		if data[2].to_i & (2**(8-b)-1) > (2**(8-b-1)) then bv += 1 << (r+g)
		var id = rv + gv + bv
		# ID 0 is the background
		if id == 0 then return null
		# Wrongful selection? This should not happen.
		if not selection_map.keys.has(id) then
			print_error "Gamnit Warning: Invalid selection {id}"
			return null
		end
		return selection_map[id]
	end
	# Program drawing selection values to the buffer
	var selection_program = new SelectionProgram
	# Map IDs to actors
	private var selection_map = new Map[Int, Actor]
	# Is there a valid selection draw in the buffer?
	private var selection_calculated = false
	# Draw the selection values to the buffer
	private fun draw_selection_screen
	do
		selection_calculated = true
		app.selection_program.use
		app.selection_program.mvp.uniform app.world_camera.mvp_matrix
		# Set aside previous buffer clear color
		var user_r = glGetFloatv(gl_COLOR_CLEAR_VALUE, 0)
		var user_g = glGetFloatv(gl_COLOR_CLEAR_VALUE, 1)
		var user_b = glGetFloatv(gl_COLOR_CLEAR_VALUE, 2)
		var user_a = glGetFloatv(gl_COLOR_CLEAR_VALUE, 3)
		glClearColor(0.0, 0.0, 0.0, 1.0)
		glClear(gl_DEPTH_BUFFER_BIT | gl_COLOR_BUFFER_BIT)
		# TODO restrict the list of actors with a valid ID, maybe with an `active_actors` list?
		var id = 1
		for actor in actors do
			selection_map[id] = actor
			for leaf in actor.model.leaves do
				leaf.material.draw_selection(actor, leaf, id)
			end
			id += 1
			#id += 100 # Debug
		end
		# Debug, show the selection values for half a second
		#display.flip
		#0.5.sleep
		glClearColor(user_r, user_g, user_b, user_a)
	end
	redef fun frame_core(display)
	do
		super
		# Invalidate the selection values
		selection_calculated = false
	end
end
					lib/gamnit/depth/selection.nit:38,1--143,3
				
redef class App
	var accelerometer = new AndroidSensor
	var magnetic_field = new AndroidSensor
	var gyroscope = new AndroidSensor
	var light = new AndroidSensor
	var proximity = new AndroidSensor
	var sensormanager: ASensorManager
	var eventqueue: ASensorEventQueue
	var sensors_support_enabled = false is writable
	private fun extern_input_sensor_accelerometer(event: ASensorAccelerometer) do accept_event(event)
	private fun extern_input_sensor_magnetic_field(event: ASensorMagneticField) do accept_event(event)
	private fun extern_input_sensor_gyroscope(event: ASensorGyroscope) do accept_event(event)
	private fun extern_input_sensor_light(event: ASensorLight) do accept_event(event)
	private fun extern_input_sensor_proximity(event: ASensorProximity) do accept_event(event)
	# Sensors support
	# The user decides which sensors he wants to use by setting them enabled
	private fun enable_sensors
	do
		if sensors_support_enabled then enable_sensors_management else return
		if accelerometer.enabled then enable_accelerometer
		if magnetic_field.enabled then enable_magnetic_field
		if gyroscope.enabled then enable_gyroscope
		if light.enabled then enable_light
		if proximity.enabled then enable_proximity
	end
	private fun enable_sensors_management
	do
		sensormanager = new ASensorManager.get_instance
		#eventqueue = sensormanager.create_event_queue(new NdkAndroidApp)
		eventqueue = initialize_event_queue(sensormanager, native_app_glue.looper)
	end
	# HACK: need a nit method to get mnit_java_app, then we can use the appropriate sensormanager.create_event_queue method to initialize the event queue
	private fun initialize_event_queue(sensormanager: ASensorManager, looper: ALooper): ASensorEventQueue `{
		return ASensorManager_createEventQueue(sensormanager, looper, LOOPER_ID_USER, NULL, NULL);
	`}
	private fun enable_accelerometer
	do
		accelerometer.asensor = sensormanager.get_default_sensor(new ASensorType.accelerometer)
		if accelerometer.asensor.address_is_null then
				print "Accelerometer sensor unavailable"
		else
				if eventqueue.enable_sensor(accelerometer.asensor) < 0 then print "Accelerometer enabling failed"
			eventqueue.set_event_rate(accelerometer.asensor, accelerometer.event_rate)
		end
	end
	private fun enable_magnetic_field
	do
		magnetic_field.asensor = sensormanager.get_default_sensor(new ASensorType.magnetic_field)
		if magnetic_field.asensor.address_is_null then
				print "Magnetic Field unavailable"
		else
			if eventqueue.enable_sensor(magnetic_field.asensor) < 0 then print "Magnetic Field enabling failed"
			eventqueue.set_event_rate(magnetic_field.asensor, magnetic_field.event_rate)
		end
	end
	private fun enable_gyroscope
	do
		gyroscope.asensor = sensormanager.get_default_sensor(new ASensorType.gyroscope)
		if gyroscope.asensor.address_is_null then
				print "Gyroscope sensor unavailable"
		else
			if eventqueue.enable_sensor(gyroscope.asensor) < 0 then print "Gyroscope enabling failed"
			eventqueue.set_event_rate(gyroscope.asensor, gyroscope.event_rate)
		end
	end
	private fun enable_light
	do
		light.asensor = sensormanager.get_default_sensor(new ASensorType.light)
		if light.asensor.address_is_null then
				print "Light sensor unavailable"
		else
			if eventqueue.enable_sensor(light.asensor) < 0 then print "Light enabling failed"
			eventqueue.set_event_rate(light.asensor, light.event_rate)
		end
	end
	private fun enable_proximity
	do
		proximity.asensor = sensormanager.get_default_sensor(new ASensorType.proximity)
		if proximity.asensor.address_is_null then
				print "Proximity sensor unavailable"
		else
			if eventqueue.enable_sensor(proximity.asensor) < 0 then print "Proximity enabling failed"
			eventqueue.set_event_rate(light.asensor, light.event_rate)
		end
	end
	redef fun run
	do
		enable_sensors
		super
	end
	redef fun handle_looper_event(ident, event, data)
	do
		super
		handle_sensor_events(ident)
	end
	private fun handle_sensor_events(ident: Int) import extern_input_sensor_accelerometer, extern_input_sensor_magnetic_field, extern_input_sensor_gyroscope, extern_input_sensor_light, extern_input_sensor_proximity, eventqueue `{
		//If a sensor has data, process it
		if(ident == LOOPER_ID_USER) {
			//maybe add a boolean to the app to know if we want to use Sensor API or ASensorEvent directly ...
			ASensorEvent* events = malloc(sizeof(ASensorEvent)*10);
			int nbevents;
			ASensorEventQueue* queue = App_eventqueue(self);
			while((nbevents = ASensorEventQueue_getEvents(queue, events, 10)) > 0) {
				int i;
				for(i = 0; i < nbevents; i++){
					ASensorEvent event = events[i];
					switch (event.type) {
						case ASENSOR_TYPE_ACCELEROMETER:
							App_extern_input_sensor_accelerometer(self, &event);
							break;
						case ASENSOR_TYPE_MAGNETIC_FIELD:
							App_extern_input_sensor_magnetic_field(self, &event);
							break;
						case ASENSOR_TYPE_GYROSCOPE:
							App_extern_input_sensor_gyroscope(self, &event);
							break;
						case ASENSOR_TYPE_LIGHT:
							App_extern_input_sensor_light(self, &event);
							break;
						case ASENSOR_TYPE_PROXIMITY:
							App_extern_input_sensor_proximity(self, &event);
							break;
					}
				}
			}
		}
	`}
end
					lib/android/sensors.nit:232,1--372,3
				
redef class App
	redef fun create_scene
	do
		# Move the camera back a bit
		world_camera.reset_height(10.0)
		world_camera.near = 0.1
		super
	end
	redef fun create_gamnit
	do
		super
		# Cull the invisible triangles in the back of the geometries
		glCullFace gl_BACK
		# Prepare programs
		var programs = [blinn_phong_program, normals_program, explosion_program, smoke_program, static_program, selection_program: GamnitProgram]
		for program in programs do
			program.compile_and_link
			var gamnit_error = program.error
			assert gamnit_error == null else print_error gamnit_error
		end
	end
	redef fun frame_core_draw(display) do frame_core_depth display
	# Draw all elements of `actors` and then call `frame_core_flat`
	protected fun frame_core_depth(display: GamnitDisplay)
	do
		frame_core_depth_clock.lapse
		# Compute shadows
		if light isa LightCastingShadows then
			frame_core_shadow_prep display
			perfs["gamnit depth shadows"].add frame_core_depth_clock.lapse
		end
		glViewport(0, 0, display.width, display.height)
		frame_core_dynamic_resolution_before display
		perfs["gamnit depth dynres"].add frame_core_depth_clock.lapse
		for actor in actors do
			for leaf in actor.model.leaves do
				leaf.material.draw(actor, leaf, app.world_camera)
				assert glGetError == gl_NO_ERROR else print_error "Gamnit error on material {leaf.material.class_name}"
			end
		end
		perfs["gamnit depth actors"].add frame_core_depth_clock.lapse
		frame_core_world_sprites display
		perfs["gamnit depth sprites"].add frame_core_depth_clock.lapse
		# Toggle writing to the depth buffer for particles effects
		glDepthMask false
		for system in particle_systems do
			system.draw
			assert glGetError == gl_NO_ERROR else print_error "OpenGL error in {system}"
		end
		glDepthMask true
		perfs["gamnit depth particles"].add frame_core_depth_clock.lapse
		# Stop using the dynamic resolution before drawing UI sprites
		frame_core_dynamic_resolution_after display
		frame_core_ui_sprites display
		perfs["gamnit depth ui_sprites"].add frame_core_depth_clock.lapse
		# Debug, show the light point of view
		#frame_core_shadow_debug display
	end
	private var frame_core_depth_clock = new Clock
end
					lib/gamnit/depth/depth.nit:26,1--101,3
				
redef class App
	redef fun on_create
	do
		app.native_activity.remove_title_bar
		native_activity.insert_root_layout(root_layout_id)
		super
	end
	# Identifier of the container holding the fragments
	private var root_layout_id = 0xFFFF
	redef fun window=(window)
	do
		native_activity.show_fragment(root_layout_id, window.native)
		super
	end
	redef fun on_start do window.on_start
	redef fun on_destroy do window.on_destroy
end
					lib/android/ui/ui.nit:66,1--86,3
				
redef class App
	redef fun frame_core_draw(display) do frame_core_stereoscopic display
	# Split the screen in two, and call `frame_core_depth` for each eyes
	protected fun frame_core_stereoscopic(display: GamnitDisplay)
	do
		var half_width = display.width / 2
		# Left eye
		glViewport(0, 0, half_width, display.height)
		world_camera.mvp_matrix = world_camera.mvp_matrix_left
		frame_core_depth display
		# Right eye
		glViewport(half_width, 0, half_width, display.height)
		world_camera.mvp_matrix = world_camera.mvp_matrix_right
		frame_core_depth display
		# We reset the viewport for selection
		glViewport(0, 0, display.width, display.height)
		# Check for errors
		var gl_error = glGetError
		assert gl_error == gl_NO_ERROR else print gl_error
	end
end
					lib/gamnit/depth/stereoscopic_view.nit:63,1--88,3
				
redef class App
	redef fun run_on_ui_thread(task)
	do
		if app.activities.not_empty then
			app.native_activity.run_on_ui_thread task
		else
			# There is no UI, it must be a service, run on the caller thread
			task.main
		end
	end
end
					lib/android/http_request.nit:32,1--42,3
				
redef class App
	# Cardboard's head tacker instance
	private var head_tracker: nullable NativeHeadTracker = null
	# Rotation matrix read from `head_tracker`, reusing the same structure as a buffer
	private var java_rotation_matrix = new JavaFloatArray(16) is lazy
	# Initialize and set `head_tracker`
	fun initialize_head_tracker
	do
		# Initialize the Cardboard head orientation tracker service
		var head_tracker = new NativeHeadTracker(app.native_activity)
		head_tracker.neck_model_enabled = true
		head_tracker.start_tracking
		self.head_tracker = head_tracker
		# Set a wide field of view
		world_camera.field_of_view_y = 1.0
	end
	# Read the rotation matrix from Cardboard and update `world_camera`
	private fun update_from_head_tracker
	do
		var head_tracker = head_tracker
		if head_tracker == null then return
		head_tracker.last_head_view(java_rotation_matrix, 0)
		# Copy values from the Java array to our matrix
		for y in [0..4[ do
			for x in [0..4[ do
				world_camera.rotation_matrix[y, x] = java_rotation_matrix[y*4+x]
			end
		end
	end
	redef fun create_scene
	do
		super
		initialize_head_tracker
	end
	redef fun update(dt)
	do
		super
		update_from_head_tracker
	end
	redef fun pause
	do
		super
		var tracker = head_tracker
		if tracker != null then tracker.stop_tracking
	end
	redef fun resume
	do
		super
		var tracker = head_tracker
		if tracker != null then tracker.start_tracking
	end
end
					lib/gamnit/depth/cardboard.nit:46,1--108,3