mirror of
https://github.com/saymrwulf/xous-core.git
synced 2026-11-15 08:30:02 +00:00
bug fixes in the REPL demo
This commit is contained in:
parent
0557caf9be
commit
617fc3b8f6
9 changed files with 97 additions and 56 deletions
|
|
@ -81,7 +81,6 @@ fn xmain() -> ! {
|
|||
}),
|
||||
Some(AppOp::FocusChange) => xous::msg_scalar_unpack!(msg, new_state_code, _, _, _, {
|
||||
let new_state = gam::FocusState::convert_focus_change(new_state_code);
|
||||
log::info!("got focus change with new state: {:?}", new_state);
|
||||
match new_state {
|
||||
gam::FocusState::Background => {
|
||||
allow_redraw = false; // this instantly terminates future updates, even if Pump messages are in our input queue
|
||||
|
|
|
|||
|
|
@ -1,4 +1,14 @@
|
|||
{
|
||||
"replapp.greeting": {
|
||||
"en": "Welcome to the simple REPL demo.",
|
||||
"zh": "简单的 repl 演示活动",
|
||||
"en-audio": "Welcome to the simple REPL demo."
|
||||
},
|
||||
"replapp.beep.start": {
|
||||
"en": "beep started...",
|
||||
"zh": "哔声开始...",
|
||||
"en-audio": "beep started..."
|
||||
},
|
||||
"replapp.beep.help": {
|
||||
"en": "beep [tone [freq [duration]]]",
|
||||
"zh": "beep [tone [音频 [时长]]]",
|
||||
|
|
|
|||
|
|
@ -89,6 +89,7 @@ pub struct CmdEnv {
|
|||
impl CmdEnv {
|
||||
pub fn new(xns: &xous_names::XousNames) -> CmdEnv {
|
||||
let ticktimer = ticktimer_server::Ticktimer::new().expect("Couldn't connect to Ticktimer");
|
||||
log::info!("creating CommonEnv");
|
||||
let common = CommonEnv {
|
||||
llio: llio::Llio::new(&xns),
|
||||
com: com::Com::new(&xns).expect("could't connect to COM"),
|
||||
|
|
@ -99,7 +100,7 @@ impl CmdEnv {
|
|||
trng: Trng::new(&xns).unwrap(),
|
||||
xns: xous_names::XousNames::new().unwrap(),
|
||||
};
|
||||
|
||||
log::info!("done creating CommonEnv");
|
||||
CmdEnv {
|
||||
common_env: common,
|
||||
lastverb: String::<256>::new(),
|
||||
|
|
|
|||
|
|
@ -15,8 +15,9 @@ pub struct Beep {
|
|||
}
|
||||
impl Beep {
|
||||
pub fn new(xns: &xous_names::XousNames) -> Self {
|
||||
log::info!("initializing beep");
|
||||
let callback_conn = xns.request_connection_blocking(crate::SERVER_NAME_REPL).unwrap();
|
||||
|
||||
log::info!("beep init returning");
|
||||
Beep {
|
||||
callback_id: None,
|
||||
callback_conn,
|
||||
|
|
@ -27,6 +28,7 @@ impl Beep {
|
|||
}
|
||||
}
|
||||
|
||||
const STOP_ID: usize = 1;
|
||||
const SAMPLE_RATE_HZ: f32 = 8000.0;
|
||||
// note to self: A4 = 440.0, E4 = 329.63, C4 = 261.63
|
||||
|
||||
|
|
@ -75,17 +77,18 @@ impl<'a> ShellCmdApi<'a> for Beep {
|
|||
|
||||
env.codec.resume().unwrap();
|
||||
|
||||
env.ticktimer.sleep_ms((duration * 1000.0) as usize).unwrap();
|
||||
|
||||
env.codec.pause().unwrap(); // this should stop callbacks from occurring too.
|
||||
write!(ret, "{} {} {}.",
|
||||
t!("replapp.beep.completion_a", xous::LANG),
|
||||
self.framecount,
|
||||
t!("replapp.beep.completion_b", xous::LANG),
|
||||
).unwrap();
|
||||
self.framecount = 0;
|
||||
self.play_sample = 0.0;
|
||||
env.codec.power_off().unwrap();
|
||||
// kick off a thread that stops the playback, after the designated delay
|
||||
std::thread::spawn({
|
||||
let cb_id = self.callback_id.unwrap().clone();
|
||||
let conn = self.callback_conn.clone();
|
||||
let duration = duration.clone();
|
||||
move || {
|
||||
let ticktimer = ticktimer_server::Ticktimer::new().unwrap();
|
||||
ticktimer.sleep_ms((duration * 1000.0) as usize).unwrap();
|
||||
xous::send_message(conn, Message::new_scalar(cb_id as usize, 0, 0, 0, STOP_ID)).unwrap();
|
||||
}
|
||||
});
|
||||
write!(ret, "{}", t!("replapp.beep.start", xous::LANG)).unwrap();
|
||||
}
|
||||
_ => {
|
||||
write!(ret, "{}", helpstring).unwrap();
|
||||
|
|
@ -100,32 +103,46 @@ impl<'a> ShellCmdApi<'a> for Beep {
|
|||
const AMPLITUDE: f32 = 0.8;
|
||||
|
||||
match &msg.body {
|
||||
Message::Scalar(xous::ScalarMessage{id: _, arg1: free_play, arg2: _avail_rec, arg3: _, arg4: _}) => {
|
||||
let mut frames: FrameRing = FrameRing::new();
|
||||
let frames_to_push = if frames.writeable_count() < *free_play {
|
||||
frames.writeable_count()
|
||||
} else {
|
||||
*free_play
|
||||
};
|
||||
self.framecount += frames_to_push as u32;
|
||||
Message::Scalar(xous::ScalarMessage{id: _, arg1: free_play, arg2: _avail_rec, arg3: _, arg4: routing_id}) => {
|
||||
if *routing_id == codec::AUDIO_CB_ROUTING_ID {
|
||||
let mut frames: FrameRing = FrameRing::new();
|
||||
let frames_to_push = if frames.writeable_count() < *free_play {
|
||||
frames.writeable_count()
|
||||
} else {
|
||||
*free_play
|
||||
};
|
||||
self.framecount += frames_to_push as u32;
|
||||
|
||||
log::debug!("f{} p{}", self.framecount, frames_to_push);
|
||||
for _ in 0..frames_to_push {
|
||||
let mut frame: [u32; codec::FIFO_DEPTH] = [ZERO_PCM as u32 | (ZERO_PCM as u32) << 16; codec::FIFO_DEPTH];
|
||||
// put the "expensive" f32 comparison outside the cosine wave table computation loop
|
||||
let omega = self.freq * 2.0 * std::f32::consts::PI / SAMPLE_RATE_HZ;
|
||||
for sample in frame.iter_mut() {
|
||||
let raw_sine: i16 = (AMPLITUDE * f32::cos( self.play_sample * omega ) * i16::MAX as f32) as i16;
|
||||
let left = raw_sine as u16;
|
||||
let right = raw_sine as u16;
|
||||
*sample = right as u32 | (left as u32) << 16;
|
||||
self.play_sample += 1.0;
|
||||
}
|
||||
|
||||
frames.nq_frame(frame).unwrap();
|
||||
|
||||
log::debug!("f{} p{}", self.framecount, frames_to_push);
|
||||
for _ in 0..frames_to_push {
|
||||
let mut frame: [u32; codec::FIFO_DEPTH] = [ZERO_PCM as u32 | (ZERO_PCM as u32) << 16; codec::FIFO_DEPTH];
|
||||
// put the "expensive" f32 comparison outside the cosine wave table computation loop
|
||||
let omega = self.freq * 2.0 * std::f32::consts::PI / SAMPLE_RATE_HZ;
|
||||
for sample in frame.iter_mut() {
|
||||
let raw_sine: i16 = (AMPLITUDE * f32::cos( self.play_sample * omega ) * i16::MAX as f32) as i16;
|
||||
let left = raw_sine as u16;
|
||||
let right = raw_sine as u16;
|
||||
*sample = right as u32 | (left as u32) << 16;
|
||||
self.play_sample += 1.0;
|
||||
}
|
||||
|
||||
frames.nq_frame(frame).unwrap();
|
||||
|
||||
env.codec.swap_frames(&mut frames).unwrap();
|
||||
} else if *routing_id == STOP_ID {
|
||||
let mut ret = String::<1024>::new();
|
||||
env.codec.pause().unwrap(); // this should stop callbacks from occurring too.
|
||||
write!(ret, "{} {} {}.",
|
||||
t!("replapp.beep.completion_a", xous::LANG),
|
||||
self.framecount,
|
||||
t!("replapp.beep.completion_b", xous::LANG),
|
||||
).unwrap();
|
||||
self.framecount = 0;
|
||||
self.play_sample = 0.0;
|
||||
env.codec.power_off().unwrap();
|
||||
return Ok(Some(ret));
|
||||
}
|
||||
env.codec.swap_frames(&mut frames).unwrap();
|
||||
},
|
||||
Message::Move(_mm) => {
|
||||
log::error!("received memory message when not expected")
|
||||
|
|
|
|||
|
|
@ -14,6 +14,8 @@ pub(crate) enum ReplOp {
|
|||
Line = 0, // make sure we occupy opcodes with discriminants < 1000, as the rest are used for callbacks
|
||||
/// redraw our UI
|
||||
Redraw,
|
||||
/// change focus
|
||||
ChangeFocus,
|
||||
/// exit the application
|
||||
Quit,
|
||||
}
|
||||
|
|
@ -29,12 +31,13 @@ fn xmain() -> ! {
|
|||
let xns = xous_names::XousNames::new().unwrap();
|
||||
// unlimited connections allowed, this is a user app and it's up to the app to decide its policy
|
||||
let sid = xns.register_name(SERVER_NAME_REPL, None).expect("can't register server");
|
||||
//log::trace!("registered with NS -- {:?}", sid);
|
||||
log::trace!("registered with NS -- {:?}", sid);
|
||||
|
||||
let mut repl = Repl::new(&xns, sid);
|
||||
let mut update_repl = false;
|
||||
let mut update_repl = true;
|
||||
let mut was_callback = false;
|
||||
|
||||
let mut allow_redraw = false;
|
||||
log::trace!("entering main loop");
|
||||
loop {
|
||||
let msg = xous::receive_message(sid).unwrap();
|
||||
log::debug!("got message {:?}", msg);
|
||||
|
|
@ -48,9 +51,22 @@ fn xmain() -> ! {
|
|||
was_callback = false;
|
||||
}
|
||||
Some(ReplOp::Redraw) => {
|
||||
log::trace!("got Redraw");
|
||||
repl.redraw().expect("REPL couldn't redraw");
|
||||
if allow_redraw {
|
||||
repl.redraw().expect("REPL couldn't redraw");
|
||||
}
|
||||
}
|
||||
Some(ReplOp::ChangeFocus) => xous::msg_scalar_unpack!(msg, new_state_code, _, _, _, {
|
||||
let new_state = gam::FocusState::convert_focus_change(new_state_code);
|
||||
match new_state {
|
||||
gam::FocusState::Background => {
|
||||
allow_redraw = false;
|
||||
}
|
||||
gam::FocusState::Foreground => {
|
||||
allow_redraw = true;
|
||||
update_repl = true;
|
||||
}
|
||||
}
|
||||
}),
|
||||
Some(ReplOp::Quit) => {
|
||||
log::error!("got Quit");
|
||||
break;
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ use graphics_server::{Gid, Point, Rectangle, TextBounds, TextView, DrawStyle, Pi
|
|||
use graphics_server::api::GlyphStyle;
|
||||
use xous::MessageEnvelope;
|
||||
use core::fmt::Write;
|
||||
use locales::t;
|
||||
|
||||
#[derive(Debug)]
|
||||
struct History {
|
||||
|
|
@ -54,7 +55,7 @@ impl Repl{
|
|||
gotinput_id: Some(ReplOp::Line.to_u32().unwrap()),
|
||||
audioframe_id: None,
|
||||
rawkeys_id: None,
|
||||
focuschange_id: None, // repl will keep running in the background even if it has lost focus
|
||||
focuschange_id: Some(ReplOp::Redraw.to_u32().unwrap()),
|
||||
}).expect("couldn't register Ux context for repl");
|
||||
|
||||
let content = gam.request_content_canvas(token.unwrap()).expect("couldn't get content canvas");
|
||||
|
|
@ -62,7 +63,7 @@ impl Repl{
|
|||
Repl {
|
||||
input: None,
|
||||
msg: None,
|
||||
history: Vec::new(),
|
||||
history: vec![History{text: String::from(t!("replapp.greeting", xous::LANG)), is_input: false}],
|
||||
history_len: 10,
|
||||
content,
|
||||
gam,
|
||||
|
|
@ -208,7 +209,6 @@ impl Repl{
|
|||
}
|
||||
}
|
||||
self.gam.redraw().expect("couldn't redraw screen");
|
||||
// self.gam.request_ime_redraw().expect("couldn't redraw the IME area");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
|
@ -6,6 +6,8 @@ use num_traits::{ToPrimitive, FromPrimitive};
|
|||
use xous_ipc::Buffer;
|
||||
pub use api::*;
|
||||
|
||||
/// This is a keyword reserved for the "arg4" slot of a scalar callback, where args are numbered 1-4.
|
||||
pub const AUDIO_CB_ROUTING_ID: usize = 0;
|
||||
#[derive(Debug)]
|
||||
pub struct Codec {
|
||||
conn: CID,
|
||||
|
|
@ -145,7 +147,7 @@ fn frame_cb_server(sid0: usize, sid1: usize, sid2: usize, sid3: usize) {
|
|||
Some(EventCallback::Event) => xous::msg_scalar_unpack!(msg, cid, id, free_play, avail_rec, {
|
||||
// directly pass the scalar message onto the CID with the ID memorized in the original hook
|
||||
send_message(cid as u32,
|
||||
Message::new_scalar(id, free_play, avail_rec, 0, 0)
|
||||
Message::new_scalar(id, free_play, avail_rec, 0, AUDIO_CB_ROUTING_ID)
|
||||
).unwrap();
|
||||
}),
|
||||
Some(EventCallback::Drop) => {
|
||||
|
|
|
|||
|
|
@ -323,6 +323,7 @@ impl ContextManager {
|
|||
None
|
||||
};
|
||||
let maybe_new_focus = self.get_context_by_token_mut(token);
|
||||
log::trace!("resolving visibility rules");
|
||||
if let Some(context) = maybe_new_focus {
|
||||
if let Some(leaving_focused_context) = maybe_leaving_focused_context {
|
||||
if token != leaving_focused_context.app_token {
|
||||
|
|
@ -355,6 +356,7 @@ impl ContextManager {
|
|||
}
|
||||
}
|
||||
}
|
||||
log::trace!("hiding old context");
|
||||
{
|
||||
// let all the previous operations go out of scope, so we can "check out" the old copy and modify it
|
||||
if self.focused_context.is_some() {
|
||||
|
|
@ -367,6 +369,7 @@ impl ContextManager {
|
|||
}
|
||||
}
|
||||
}
|
||||
log::trace!("rewiring IMEF and recomputing canvases");
|
||||
{
|
||||
// now re-check-out the new context and finalize things
|
||||
let maybe_new_focus = self.get_context_by_token(token);
|
||||
|
|
@ -404,6 +407,7 @@ impl ContextManager {
|
|||
*canvases = recompute_canvases(canvases, Rectangle::new(Point::new(0, 0), screensize));
|
||||
}
|
||||
}
|
||||
log::trace!("foregrounding new context");
|
||||
{
|
||||
// now re-check-out the new context and finalize things
|
||||
let maybe_new_focus = self.get_context_by_token(token);
|
||||
|
|
@ -427,6 +431,7 @@ impl ContextManager {
|
|||
self.last_context = self.focused_context;
|
||||
self.focused_context = Some(last_token);
|
||||
}
|
||||
log::trace!("defacing old canvases prior to redraw");
|
||||
// run the defacement before we redraw all the canvases
|
||||
deface(gfx, &self.trng, canvases);
|
||||
log::trace!("activate redraw");
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ fn imef_cb(s: String::<4000>) {
|
|||
#[xous::xous_main]
|
||||
fn xmain() -> ! {
|
||||
log_server::init_wait().unwrap();
|
||||
log::set_max_level(log::LevelFilter::Trace);
|
||||
log::set_max_level(log::LevelFilter::Info);
|
||||
info!("my PID is {}", xous::process::id());
|
||||
|
||||
let xns = xous_names::XousNames::new().unwrap();
|
||||
|
|
@ -484,15 +484,6 @@ fn xmain() -> ! {
|
|||
Some(Opcode::RevertFocusNb) => {
|
||||
context_mgr.revert_focus(&gfx, &mut canvases);
|
||||
},
|
||||
/*
|
||||
Some(Opcode::RequestFocus) => msg_blocking_scalar_unpack!(msg, t0, t1, t2, t3, {
|
||||
// TODO: add some limitations around who can request focus
|
||||
// for now, it's the boot set so we just trust the requestor
|
||||
context_mgr.activate(&gfx, &mut canvases, [t0 as u32, t1 as u32, t2 as u32, t3 as u32], true);
|
||||
|
||||
// this is a blocking scalar, so return /something/ so we know to move on
|
||||
xous::return_scalar(msg.sender, 1).expect("couldn't confirm focus activation");
|
||||
}), */
|
||||
Some(Opcode::QueryGlyphProps) => msg_blocking_scalar_unpack!(msg, style, _, _, _, {
|
||||
let height = gfx.glyph_height_hint(GlyphStyle::from(style)).expect("couldn't query glyph height from gfx");
|
||||
xous::return_scalar(msg.sender, height).expect("could not return QueryGlyphProps request");
|
||||
|
|
|
|||
Loading…
Reference in a new issue