aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRonald Kinard <[email protected]>2015-09-17 23:52:23 -0500
committerRonald Kinard <[email protected]>2015-09-17 23:52:23 -0500
commit5154868f0409b7eb18b4cc15da91830b843fec20 (patch)
tree7092d8456a4fe2396608c6d6d9f47df43f818070 /src
parentAdd Hid struct. (diff)
downloadctru-rs-5154868f0409b7eb18b4cc15da91830b843fec20.tar.xz
ctru-rs-5154868f0409b7eb18b4cc15da91830b843fec20.zip
Overhaul Apt service.
Applications should implement the Application trait and use that to interface with apt. An example is provided in rust3ds-template.
Diffstat (limited to 'src')
-rw-r--r--src/services/apt.rs151
-rw-r--r--src/services/mod.rs1
2 files changed, 77 insertions, 75 deletions
diff --git a/src/services/apt.rs b/src/services/apt.rs
index b7e7b82..c37ac23 100644
--- a/src/services/apt.rs
+++ b/src/services/apt.rs
@@ -1,4 +1,4 @@
-use ::Result;
+use core::marker::PhantomData;
use ::raw::services::apt;
@@ -14,96 +14,97 @@ pub enum AppStatus {
AppletClosed
}
-
-fn to_raw_appstatus(status: AppStatus) -> apt::APP_STATUS {
- use self::AppStatus::*;
- match status {
- NotInitialized => apt::APP_STATUS::APP_NOTINITIALIZED,
- Running => apt::APP_STATUS::APP_RUNNING,
- Suspended => apt::APP_STATUS::APP_SUSPENDED,
- Exiting => apt::APP_STATUS::APP_EXITING,
- Suspending => apt::APP_STATUS::APP_SUSPENDING,
- SleepMode => apt::APP_STATUS::APP_SLEEPMODE,
- PrepareSleepMode => apt::APP_STATUS::APP_PREPARE_SLEEPMODE,
- AppletStarted => apt::APP_STATUS::APP_APPLETSTARTED,
- AppletClosed => apt::APP_STATUS::APP_APPLETCLOSED,
+impl From<AppStatus> for apt::APP_STATUS {
+ fn from(a: AppStatus) -> apt::APP_STATUS {
+ use self::AppStatus::*;
+ match a {
+ NotInitialized => apt::APP_STATUS::APP_NOTINITIALIZED,
+ Running => apt::APP_STATUS::APP_RUNNING,
+ Suspended => apt::APP_STATUS::APP_SUSPENDED,
+ Exiting => apt::APP_STATUS::APP_EXITING,
+ Suspending => apt::APP_STATUS::APP_SUSPENDING,
+ SleepMode => apt::APP_STATUS::APP_SLEEPMODE,
+ PrepareSleepMode => apt::APP_STATUS::APP_PREPARE_SLEEPMODE,
+ AppletStarted => apt::APP_STATUS::APP_APPLETSTARTED,
+ AppletClosed => apt::APP_STATUS::APP_APPLETCLOSED,
+ }
}
}
-fn from_raw_appstatus(status: apt::APP_STATUS) -> AppStatus {
- use self::AppStatus::*;
- match status {
- apt::APP_STATUS::APP_NOTINITIALIZED => NotInitialized,
- apt::APP_STATUS::APP_RUNNING => Running,
- apt::APP_STATUS::APP_SUSPENDED => Suspended,
- apt::APP_STATUS::APP_EXITING => Exiting,
- apt::APP_STATUS::APP_SUSPENDING => Suspending,
- apt::APP_STATUS::APP_SLEEPMODE => SleepMode,
- apt::APP_STATUS::APP_PREPARE_SLEEPMODE => PrepareSleepMode,
- apt::APP_STATUS::APP_APPLETSTARTED => AppletStarted,
- apt::APP_STATUS::APP_APPLETCLOSED => AppletClosed
+impl From<apt::APP_STATUS> for AppStatus {
+ fn from(a: apt::APP_STATUS) -> AppStatus {
+ use self::AppStatus::*;
+ match a {
+ apt::APP_STATUS::APP_NOTINITIALIZED => NotInitialized,
+ apt::APP_STATUS::APP_RUNNING => Running,
+ apt::APP_STATUS::APP_SUSPENDED => Suspended,
+ apt::APP_STATUS::APP_EXITING => Exiting,
+ apt::APP_STATUS::APP_SUSPENDING => Suspending,
+ apt::APP_STATUS::APP_SLEEPMODE => SleepMode,
+ apt::APP_STATUS::APP_PREPARE_SLEEPMODE => PrepareSleepMode,
+ apt::APP_STATUS::APP_APPLETSTARTED => AppletStarted,
+ apt::APP_STATUS::APP_APPLETCLOSED => AppletClosed
+ }
}
}
-pub fn init() -> Result {
- unsafe {
- return apt::aptInit();
- }
+pub struct Apt {
+ pd: PhantomData<()>
}
-pub fn exit() -> () {
- unsafe {
- apt::aptExit();
+impl Apt {
+ pub fn new() -> Result<Apt, i32> {
+ unsafe {
+ let r = apt::aptInit();
+ if r < 0 {
+ Err(r)
+ } else {
+ Ok(Apt { pd: PhantomData })
+ }
+ }
}
-}
-pub fn get_status() -> AppStatus {
- unsafe {
- return from_raw_appstatus(apt::aptGetStatus());
+ pub fn get_status(&self) -> AppStatus {
+ unsafe { apt::aptGetStatus().into() }
}
-}
-pub fn set_status(status: AppStatus) -> () {
- unsafe {
- apt::aptSetStatus(to_raw_appstatus(status));
+ pub fn set_status(&mut self, status: AppStatus) {
+ unsafe { apt::aptSetStatus(status.into()) };
+ }
+
+ /// Return to the home menu.
+ ///
+ /// When `get_status` returns `AppStatus::Suspending`, you should call this,
+ /// otherwise the app will be left stuck in that state.
+ ///
+ /// The program will not return from this function until the system returns
+ /// to the application, or when the status changes to `AppStatus::Exiting`.
+ pub fn return_to_menu(&mut self) {
+ unsafe { apt::aptReturnToMenu() };
}
-}
-/// Return to the home menu.
-///
-/// When `get_status` returns `AppStatus::Suspending`, you should call this,
-/// otherwise the app will be left stuck in that state.
-///
-/// The program will not return from this function until the system returns
-/// to the application, or when the status changes to `AppStatus::Exiting`.
-///
-/// # Examples
-///
-/// ```
-/// if get_status() == Suspending {
-/// return_to_menu();
-/// }
-/// ```
-pub fn return_to_menu() -> () {
- unsafe {
- apt::aptReturnToMenu();
+ pub fn main_loop(&mut self, app: &mut Application) {
+ unsafe {
+ while apt::aptMainLoop() != 0 {
+ app.main_loop(self);
+ if app.ready_to_quit() {
+ self.set_status(AppStatus::Exiting)
+ }
+ }
+ };
}
}
-/// Execute a function repeatedly until the apt main loop is over.
-///
-/// # Examples
-///
-/// ```rust
-/// main_loop(|| {
-/// // do things here
-/// false
-/// });
-/// ```
-pub fn main_loop<F>(mut f: F) -> () where F : FnMut() -> bool {
- unsafe {
- while apt::aptMainLoop() != 0 {
- if !f() { break; }
- }
+impl Drop for Apt {
+ fn drop(&mut self) {
+ unsafe { apt::aptExit() };
}
}
+
+pub trait Application {
+ /// Program app loop body.
+ fn main_loop(&mut self, apt: &mut Apt);
+
+ /// True if the application is ready to quit.
+ fn ready_to_quit(&self) -> bool;
+}
diff --git a/src/services/mod.rs b/src/services/mod.rs
index d5a8f4d..0757352 100644
--- a/src/services/mod.rs
+++ b/src/services/mod.rs
@@ -3,3 +3,4 @@ pub mod hid;
pub mod gsp;
pub use self::hid::Hid;
+pub use self::apt::{Apt, Application};