mirror of
https://github.com/saymrwulf/xous-core.git
synced 2026-11-12 07:44:18 +00:00
clean up enum-based dispatch for Layouts, pulling in enum_dispatch crate.
This commit is contained in:
parent
356b07dacc
commit
03bcf18348
4 changed files with 48 additions and 63 deletions
14
Cargo.lock
generated
14
Cargo.lock
generated
|
|
@ -548,6 +548,18 @@ dependencies = [
|
|||
"xous-names",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "enum_dispatch"
|
||||
version = "0.3.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "bd53b3fde38a39a06b2e66dc282f3e86191e53bd04cc499929c15742beae3df8"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2 1.0.24",
|
||||
"quote 1.0.8",
|
||||
"syn 1.0.60",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "env_logger"
|
||||
version = "0.7.1"
|
||||
|
|
@ -602,11 +614,11 @@ dependencies = [
|
|||
name = "gam"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"blitstr-ref",
|
||||
"chrono",
|
||||
"com",
|
||||
"content-plugin-api",
|
||||
"enum_dispatch",
|
||||
"graphics-server",
|
||||
"heapless 0.7.0",
|
||||
"ime-plugin-api",
|
||||
|
|
|
|||
|
|
@ -6,12 +6,11 @@ name = "gam"
|
|||
version = "0.1.0"
|
||||
|
||||
[dependencies]
|
||||
bitflags = "1.2.1"
|
||||
blitstr-ref = {path = "../../imports/blitstr-ref"}
|
||||
com = {path = "../com"}
|
||||
content-plugin-api = {path = "../content-plugin-api"}
|
||||
graphics-server = {path = "../graphics-server"}
|
||||
heapless = "0.7"
|
||||
heapless = "0.7" # used for creating a sortable heap of canvas objects
|
||||
ime-plugin-api = {path = "../ime-plugin-api"}
|
||||
ime-plugin-shell = {path = "../ime-plugin-shell"}
|
||||
keyboard = {path = "../keyboard"}
|
||||
|
|
@ -29,6 +28,8 @@ num-derive = {version = "0.3", default-features = false}
|
|||
num-traits = {version = "0.2", default-features = false}
|
||||
rkyv = {version = "0.4.3", default-features = false, features = ["const_generics"]}
|
||||
|
||||
enum_dispatch = "0.3.7" # used for trait-based dispatch off of multiple layout objects.
|
||||
|
||||
[target.'cfg(not(any(windows,unix)))'.dependencies]
|
||||
utralib = {path = "../../utralib"}
|
||||
|
||||
|
|
|
|||
|
|
@ -5,19 +5,7 @@ use blitstr_ref as blitstr;
|
|||
use blitstr::GlyphStyle;
|
||||
use graphics_server::*;
|
||||
|
||||
pub(crate) trait LayoutApi {
|
||||
type Layout;
|
||||
|
||||
fn init(gfx: &graphics_server::Gfx, trng: &trng::Trng,
|
||||
base_trust: u8, status_canvas: &Canvas,
|
||||
canvases: &mut FnvIndexMap<Gid, Canvas, {crate::MAX_CANVASES}>) -> Result<Self::Layout, xous::Error>;
|
||||
fn clear(&self, gfx: &graphics_server::Gfx, canvases: &mut FnvIndexMap<Gid, Canvas, {crate::MAX_CANVASES}>) -> Result<(), xous::Error>;
|
||||
// for Chats, this resizes the height of the input area; for menus, it resizes the overall height
|
||||
fn resize_height(&mut self, gfx: &graphics_server::Gfx, new_height: i16, status_canvas: &Canvas, canvases: &mut FnvIndexMap<Gid, Canvas, {crate::MAX_CANVASES}>) -> Result<Point, xous::Error>;
|
||||
fn get_input_canvas(&self) -> Option<Gid> { None }
|
||||
fn get_prediction_canvas(&self) -> Option<Gid> { None }
|
||||
fn get_content_canvas(&self) -> Gid; // layouts always have a content canvas
|
||||
}
|
||||
use crate::LayoutApi;
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
// GIDs of canvases that are used the "Chat" layout.
|
||||
|
|
@ -34,10 +22,9 @@ pub(crate) struct ChatLayout {
|
|||
small_height: i16,
|
||||
regular_height: i16,
|
||||
}
|
||||
impl LayoutApi for ChatLayout {
|
||||
type Layout = ChatLayout;
|
||||
impl ChatLayout {
|
||||
// pass in the status canvas so we can size around it, but we can't draw on it
|
||||
fn init(gfx: &graphics_server::Gfx, trng: &trng::Trng, base_trust: u8,
|
||||
pub fn init(gfx: &graphics_server::Gfx, trng: &trng::Trng, base_trust: u8,
|
||||
status_canvas: &Canvas, canvases: &mut FnvIndexMap<Gid, Canvas, {crate::MAX_CANVASES}>) -> Result<ChatLayout, xous::Error> {
|
||||
let screensize = gfx.screen_size().expect("Couldn't get screen size");
|
||||
// get the height of various text regions to compute the layout
|
||||
|
|
@ -77,6 +64,8 @@ impl LayoutApi for ChatLayout {
|
|||
regular_height,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl LayoutApi for ChatLayout {
|
||||
fn clear(&self, gfx: &graphics_server::Gfx, canvases: &mut FnvIndexMap<Gid, Canvas, {crate::MAX_CANVASES}>) -> Result<(), xous::Error> {
|
||||
let input_canvas = canvases.get(&self.input).expect("couldn't find input canvas");
|
||||
let content_canvas = canvases.get(&self.content).expect("couldn't find content canvas");
|
||||
|
|
@ -147,9 +136,8 @@ pub(crate) struct MenuLayout {
|
|||
screensize: Point,
|
||||
small_height: i16,
|
||||
}
|
||||
impl LayoutApi for MenuLayout {
|
||||
type Layout = MenuLayout;
|
||||
fn init(gfx: &graphics_server::Gfx, trng: &trng::Trng, base_trust: u8, _status_canvas: &Canvas, canvases: &mut FnvIndexMap<Gid, Canvas, {crate::MAX_CANVASES}>) -> Result<MenuLayout, xous::Error> {
|
||||
impl MenuLayout {
|
||||
pub fn init(gfx: &graphics_server::Gfx, trng: &trng::Trng, base_trust: u8, _status_canvas: &Canvas, canvases: &mut FnvIndexMap<Gid, Canvas, {crate::MAX_CANVASES}>) -> Result<MenuLayout, xous::Error> {
|
||||
let screensize = gfx.screen_size().expect("Couldn't get screen size");
|
||||
// get the height of various text regions to compute the layout
|
||||
let small_height: i16 = gfx.glyph_height_hint(GlyphStyle::Small).expect("couldn't get glyph height") as i16;
|
||||
|
|
@ -172,6 +160,8 @@ impl LayoutApi for MenuLayout {
|
|||
small_height,
|
||||
})
|
||||
}
|
||||
}
|
||||
impl LayoutApi for MenuLayout {
|
||||
fn clear(&self, gfx: &graphics_server::Gfx, canvases: &mut FnvIndexMap<Gid, Canvas, {crate::MAX_CANVASES}>) -> Result<(), xous::Error> {
|
||||
let menu_canvas = canvases.get(&self.menu).expect("couldn't find menu canvas");
|
||||
|
||||
|
|
|
|||
|
|
@ -27,46 +27,28 @@ use xous::{msg_scalar_unpack, msg_blocking_scalar_unpack};
|
|||
|
||||
use core::{sync::atomic::{AtomicU32, Ordering}};
|
||||
|
||||
use enum_dispatch::enum_dispatch;
|
||||
|
||||
//// todo:
|
||||
// - create menu server
|
||||
// - move vibe call to the GAM, reduce keyboard connections to 1
|
||||
// - add auth tokens to audio streams, so less trusted processes can make direct connections to the codec and reduce latency
|
||||
// - create menu server
|
||||
// - macro-ize the unwrapping of the UxLayout enum
|
||||
|
||||
#[enum_dispatch]
|
||||
pub(crate) trait LayoutApi {
|
||||
fn clear(&self, gfx: &graphics_server::Gfx, canvases: &mut FnvIndexMap<Gid, Canvas, {crate::MAX_CANVASES}>) -> Result<(), xous::Error>;
|
||||
// for Chats, this resizes the height of the input area; for menus, it resizes the overall height
|
||||
fn resize_height(&mut self, gfx: &graphics_server::Gfx, new_height: i16, status_canvas: &Canvas, canvases: &mut FnvIndexMap<Gid, Canvas, {crate::MAX_CANVASES}>) -> Result<Point, xous::Error>;
|
||||
fn get_input_canvas(&self) -> Option<Gid> { None }
|
||||
fn get_prediction_canvas(&self) -> Option<Gid> { None }
|
||||
fn get_content_canvas(&self) -> Gid; // layouts always have a content canvas
|
||||
}
|
||||
|
||||
#[enum_dispatch(LayoutApi)]
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
pub(crate) enum UxLayout {
|
||||
Chat(ChatLayout),
|
||||
Menu(MenuLayout),
|
||||
}
|
||||
pub(crate) fn uxlayout_get_content_canvas(ul: UxLayout) -> Gid {
|
||||
match ul {
|
||||
UxLayout::Chat(layout) => layout.get_content_canvas(),
|
||||
UxLayout::Menu(layout) => layout.get_content_canvas(),
|
||||
}
|
||||
}
|
||||
pub(crate) fn uxlayout_resize_height(ul: &mut UxLayout, gfx: &graphics_server::Gfx, new_height: i16, status_canvas: &Canvas, canvases: &mut FnvIndexMap<Gid, Canvas, MAX_CANVASES>) -> Result<Point, xous::Error> {
|
||||
match ul {
|
||||
UxLayout::Chat(layout) => layout.resize_height(gfx, new_height, status_canvas, canvases),
|
||||
UxLayout::Menu(layout) => layout.resize_height(gfx, new_height, status_canvas, canvases),
|
||||
}
|
||||
}
|
||||
pub(crate) fn uxlayout_clear(ul: UxLayout, gfx: &graphics_server::Gfx, canvases: &mut FnvIndexMap<Gid, Canvas, {crate::MAX_CANVASES}>) -> Result<(), xous::Error> {
|
||||
match ul {
|
||||
UxLayout::Chat(layout) => layout.clear(gfx, canvases),
|
||||
UxLayout::Menu(layout) => layout.clear(gfx, canvases),
|
||||
}
|
||||
}
|
||||
pub(crate) fn uxlayout_get_input_canvas(ul: UxLayout) -> Option<Gid> {
|
||||
match ul {
|
||||
UxLayout::Chat(layout) => layout.get_input_canvas(),
|
||||
UxLayout::Menu(layout) => layout.get_input_canvas(),
|
||||
}
|
||||
}
|
||||
pub(crate) fn uxlayout_get_prediction_canvas(ul: UxLayout) -> Option<Gid> {
|
||||
match ul {
|
||||
UxLayout::Chat(layout) => layout.get_prediction_canvas(),
|
||||
UxLayout::Menu(layout) => layout.get_prediction_canvas(),
|
||||
}
|
||||
ChatLayout,
|
||||
MenuLayout,
|
||||
}
|
||||
|
||||
#[derive(Debug, Copy, Clone)]
|
||||
|
|
@ -136,7 +118,7 @@ impl ContextManager {
|
|||
let chatlayout = ChatLayout::init(&gfx, &trng,
|
||||
BOOT_CONTEXT_TRUSTLEVEL, &status_canvas, canvases).expect("couldn't create chat layout");
|
||||
let ux_context = UxContext {
|
||||
layout: UxLayout::Chat(chatlayout),
|
||||
layout: UxLayout::ChatLayout(chatlayout),
|
||||
predictor: registration.predictor,
|
||||
app_token: token,
|
||||
gam_token: [trng.get_u32().unwrap(), trng.get_u32().unwrap(), trng.get_u32().unwrap(), trng.get_u32().unwrap(), ],
|
||||
|
|
@ -159,7 +141,7 @@ impl ContextManager {
|
|||
let menulayout = MenuLayout::init(&gfx, &trng,
|
||||
BOOT_CONTEXT_TRUSTLEVEL, &status_canvas, canvases).expect("couldn't create menu layout");
|
||||
let ux_context = UxContext {
|
||||
layout: UxLayout::Menu(menulayout),
|
||||
layout: UxLayout::MenuLayout(menulayout),
|
||||
predictor: None,
|
||||
app_token: token,
|
||||
gam_token: [trng.get_u32().unwrap(), trng.get_u32().unwrap(), trng.get_u32().unwrap(), trng.get_u32().unwrap(), ],
|
||||
|
|
@ -196,7 +178,7 @@ impl ContextManager {
|
|||
for maybe_context in self.contexts.iter() {
|
||||
if let Some(context) = maybe_context {
|
||||
if context.app_token == token {
|
||||
return Some(uxlayout_get_content_canvas(context.layout));
|
||||
return Some(context.layout.get_content_canvas());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -212,7 +194,7 @@ impl ContextManager {
|
|||
for maybe_context in self.contexts.iter_mut() {
|
||||
if let Some(context) = maybe_context {
|
||||
if context.gam_token == gam_token {
|
||||
let result = uxlayout_resize_height(&mut context.layout, gfx, new_height, status_canvas, canvases).expect("couldn't adjust height of active Ux context");
|
||||
let result = context.layout.resize_height(gfx, new_height, status_canvas, canvases).expect("couldn't adjust height of active Ux context");
|
||||
return Some(result)
|
||||
}
|
||||
}
|
||||
|
|
@ -230,14 +212,14 @@ impl ContextManager {
|
|||
if let Some(context) = maybe_context {
|
||||
if context.app_token == token {
|
||||
let descriptor = ImefDescriptor {
|
||||
input_canvas: uxlayout_get_input_canvas(context.layout),
|
||||
prediction_canvas: uxlayout_get_prediction_canvas(context.layout),
|
||||
input_canvas: context.layout.get_input_canvas(),
|
||||
prediction_canvas: context.layout.get_prediction_canvas(),
|
||||
predictor: context.predictor,
|
||||
token: context.gam_token,
|
||||
};
|
||||
imef.connect_backend(descriptor).expect("couldn't connect IMEF to the current app");
|
||||
if clear {
|
||||
uxlayout_clear(context.layout, gfx, canvases).expect("can't clear on context activation");
|
||||
context.layout.clear(gfx, canvases).expect("can't clear on context activation");
|
||||
}
|
||||
// now update the IMEF area, since we're initialized
|
||||
// note: we may need to skip this call if the context does not utilize a predictor...
|
||||
|
|
|
|||
Loading…
Reference in a new issue