My SDK will handle bootstrapping of the application (e.g. the entry point uses agera::application::start!
and does not define any main function manually). This is necessary because the SDK should be able to export an application into a publishable APK or Windows installer and it should be possible for the developer to do things similiar to:
use agera::file::*;
File::new("app://some-file.txt").read_utf8();
File::new("app-storage://some-file.bin").write(content);
File
itself is similiar to flash.filesystem.File
from Adobe AIR. The app:
and app-storage:
schemes identify files in directories that are very inpredictable by Rust code, including because:
- The Rust code does not know the application ID. For example, it could be
com.microsoft.todo
,com.nintendo.mariomaker
. - These directories vary per operating system.
- These directories, when debugging, will be inside the recipes directory (
target
), and not be the actual exported application installation's and storage's directories.
In respect to the file API, I'm aiming to support only Windows, Linux, OSX and Android for now. The web, too, will be supported, however I've no idea of how the synchronous operations will be done given that the origin-private file system API has no synchronous operations at all.
I'd like to know if anyone has any input on what I should use for Windows, Linux and OSX; is it data_dir()
from dirs
? I'm wondering if, e.g., appending the application ID to the native OS's data directory will be compatible with the Steam applications sandbox. To be honest, I've no idea of how the proper application directory is even determined by Steam.
So right now I've this in src/target.rs
:
...
#[cfg(target_os = "android")]
pub use ::android_activity as activity;
#[cfg(target_os = "android")]
pub use ::jni;
#[cfg(target_os = "android")]
#[doc(hidden)]
pub static APPLICATION: Lazy<RwLock<Option<activity::AndroidApp>>> = Lazy::new(|| RwLock::new(None));
#[cfg(target_os = "android")]
pub fn application() -> activity::AndroidApp {
APPLICATION.read().unwrap().as_ref().unwrap().clone()
}
...
I'll also read the application ID from the application descriptor and likely put it in agera::application::id()
.
Here's what I've of relevant in src/file/file.rs
:
pub(crate) fn application_installation_directory() -> String {
if_native_target! {{
if cfg!(target_os = "android") {
let path = if let Some(p) = crate::target::application().external_data_path() { p.to_string_lossy().into_owned() } else { crate::target::application().internal_data_path().unwrap().to_string_lossy().into_owned() };
return FlexPath::new_common(&path).resolve(".install").to_string();
} else {
unsupported_platform!();
}
}}
if_browser_target! {{
unsupported_platform!();
}}
}
pub(crate) fn application_storage_directory() -> String {
if_native_target! {{
if cfg!(target_os = "android") {
let path = if let Some(p) = crate::target::application().external_data_path() { p.to_string_lossy().into_owned() } else { crate::target::application().internal_data_path().unwrap().to_string_lossy().into_owned() };
return FlexPath::new_common(&path).resolve(".storage").to_string();
} else {
unsupported_platform!();
}
}}
if_browser_target! {{
unsupported_platform!();
}}
}