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