Commit b8862214 authored by Imran Salam's avatar Imran Salam
Browse files
parents 35e8ca6a f9afcde6
......@@ -2,6 +2,7 @@ use composit::{
ActiveSource, Leaf, Train, ComponentManager, Stick, TrainManager
};
use controller::global::AppRunner;
use controller::output::Report;
use types::DOWN;
const MS_PER_UPDATE : f64 = 250.;
......@@ -46,6 +47,10 @@ impl Compositor {
}
}
pub fn update_report(&self, report: &Report) {
self.train_manager.update_report(report);
}
pub fn set_stick(&mut self, st: &Stick) {
self.train_manager.set_stick(st,self.bp_per_screen);
self.updated = true;
......
use std::collections::HashMap;
use composit::{ Leaf, Position, Wrapping };
use controller::output::Report;
use program::UniformValue;
use types::{CPixel, cpixel, Move, Dot, Direction, LEFT, RIGHT };
......@@ -26,6 +27,11 @@ impl Stage {
out
}
pub fn update_report(&self, report: &Report) {
report.set_status("start",&self.pos.get_edge(&LEFT).floor().to_string());
report.set_status("end",&self.pos.get_edge(&RIGHT).ceil().to_string());
}
pub fn set_wrapping(&mut self, w: &Wrapping) {
self.pos.set_bumper(&LEFT,w.get_bumper(&LEFT));
self.pos.set_bumper(&RIGHT,w.get_bumper(&RIGHT));
......
......@@ -12,6 +12,7 @@
*/
use composit::{ Leaf, Train, ComponentManager, ActiveSource, Stick, Scale };
use controller::output::Report;
const MS_FADE : f64 = 300.;
const OUTER_TRAINS : usize = 2;
......@@ -48,6 +49,12 @@ impl TrainManager {
out
}
pub fn update_report(&self, report: &Report) {
if let Some(ref stick) = self.stick {
report.set_status("stick",&stick.get_name());
}
}
fn reset_outers(&mut self) {
for _ in 0..OUTER_TRAINS { self.outer_train.push(None); }
}
......
......@@ -3,9 +3,10 @@ use std::sync::{ Arc, Mutex };
use stdweb::web::{ Element, HtmlElement };
use stdweb::unstable::TryInto;
use global::{ Global, GlobalWeak };
use composit::{ Compositor, StateManager, Stage };
use controller::input::{ Event, events_run, startup_events };
use controller::global::{ Global, GlobalWeak };
use controller::output::Report;
use dom::domutil;
use print::Printer;
......@@ -19,7 +20,8 @@ pub struct App {
pub stage: Arc<Mutex<Stage>>,
pub state: Arc<Mutex<StateManager>>,
pub compo: Arc<Mutex<Compositor>>,
last_boxsize: Option<f64>
last_boxsize: Option<f64>,
report: Option<Report>
}
impl App {
......@@ -35,11 +37,18 @@ impl App {
stage: Arc::new(Mutex::new(Stage::new())),
compo: Arc::new(Mutex::new(Compositor::new())),
state: Arc::new(Mutex::new(StateManager::new())),
last_boxsize: None
last_boxsize: None,
report: None
};
out.run_events(&startup_events());
out
}
pub fn get_report(&self) -> &Report { &self.report.as_ref().unwrap() }
pub fn set_report(&mut self, report: Report) {
self.report = Some(report);
}
pub fn with_global<F,G>(&mut self, cb:F) -> Option<G>
where F: FnOnce(&mut Global) -> G {
......@@ -62,8 +71,12 @@ impl App {
}
pub fn with_stage<F,G>(&self, cb: F) -> G where F: FnOnce(&mut Stage) -> G {
let a = &mut self.stage.lock().unwrap();
cb(a)
let s = &mut self.stage.lock().unwrap();
let out = cb(s);
if let Some(ref report) = self.report {
s.update_report(report);
}
out
}
pub fn with_state<F,G>(&self, cb: F) -> G where F: FnOnce(&mut StateManager) -> G {
......@@ -72,8 +85,12 @@ impl App {
}
pub fn with_compo<F,G>(&self, cb: F) -> G where F: FnOnce(&mut Compositor) -> G {
let a = &mut self.compo.lock().unwrap();
cb(a)
let c = &mut self.compo.lock().unwrap();
let out = cb(c);
if let Some(ref report) = self.report {
c.update_report(report);
}
out
}
pub fn run_events(self: &mut App, evs: &Vec<Event>) {
......
......@@ -8,7 +8,7 @@ use controller::input::{
register_direct_events, register_user_events, register_dom_events,
Timers, Timer
};
use controller::output::Projector;
use controller::output::{ Projector, Report };
use dom::Bling;
use dom::event::EventControl;
......@@ -46,9 +46,11 @@ impl AppRunner {
timers: Timers::new()
})));
out.init();
let report = Report::new(&mut out);
{
let mut imp = out.0.lock().unwrap();
let app = imp.app.clone();
app.lock().unwrap().set_report(report);
let el = imp.el.clone();
imp.bling.activate(&app,&el);
}
......@@ -61,16 +63,19 @@ impl AppRunner {
let mut imp = self.0.lock().unwrap();
imp.bling = bling;
let browser_el : HtmlElement = imp.bling.apply_bling(&imp.el);
let report = imp.app.lock().unwrap().get_report().clone();
imp.app = Arc::new(Mutex::new(App::new(&imp.g,&browser_el)));
imp.timers = Timers::new();
imp.projector = None;
imp.controls = Vec::<Box<EventControl<()>>>::new();
imp.timers = Timers::new();
}
self.init();
let report = Report::new(self);
{
let mut imp = self.0.lock().unwrap();
let el = imp.el.clone();
let app = imp.app.clone();
app.lock().unwrap().set_report(report);
imp.bling.activate(&app,&el);
}
}
......@@ -153,6 +158,7 @@ impl AppRunner {
}
pub fn activate_debug(&mut self) {
console!("activate_debug");
self.reset(Box::new(DebugBling::new(create_interactors())));
}
......
......@@ -39,7 +39,6 @@ fn exe_move_event(app: &App, v: Move<f64,f64>) {
}
fn exe_zoom_event(app: &App, mut z: f64, by: bool) {
debug!("bug","zoom z={} by={}",z,by);
let z = app.with_stage(|s| {
if by {
s.inc_zoom(z);
......
mod jank;
mod projector;
mod report;
pub use self::projector::Projector;
pub use self::report::Report;
use std::collections::HashMap;
use std::sync::{ Arc, Mutex };
use controller::global::{ App, AppRunner };
struct Status {
value: String,
last_value: Option<String>,
last_sent: Option<f64>,
send_every: Option<f64>
}
impl Status {
fn is_send_now(&self, key: &str, t: f64) -> bool {
if let Some(interval) = self.send_every {
if interval == 0. { return true; }
if let Some(last_sent) = self.last_sent {
if t - last_sent > interval { return true; }
} else {
return true;
}
}
return false;
}
fn send_now(&mut self, key: &str, t: f64) -> bool {
if let Some(ref last_value) = self.last_value {
if *last_value == self.value { return false; }
}
if self.is_send_now(key,t) {
self.last_sent = Some(t);
self.last_value = Some(self.value.clone());
return true;
}
return false;
}
fn set_interval(&mut self, interval: Option<f64>) {
self.send_every = interval;
}
}
const REPORT_CONFIG: &[(&str,Option<f64>)] = &[
("stick",Some(500.)),
("start",Some(500.)),
("end",Some(500.)),
];
pub struct ReportImpl {
statuses: HashMap<String,Status>
}
impl ReportImpl {
pub fn new() -> ReportImpl {
let out = ReportImpl {
statuses: HashMap::<String,Status>::new()
};
out
}
fn get_entry(&mut self, key: &str) -> &mut Status {
self.statuses.entry(key.to_string()).or_insert_with(||
Status {
value: "".to_string(),
last_value: None,
last_sent: None,
send_every: Some(0.)
}
)
}
pub fn set_status(&mut self, key: &str, value: &str) {
let s = self.get_entry(key);
if s.value == value { return; }
s.value = value.to_string();
}
pub fn set_interval(&mut self, key: &str, interval: Option<f64>) {
let s = self.get_entry(key);
s.set_interval(interval);
}
fn new_report(&mut self, t: f64) -> HashMap<String,String> {
let mut out = HashMap::<String,String>::new();
for (k,s) in &mut self.statuses {
if s.send_now(k,t) {
out.insert(k.to_string(),s.value.clone());
}
}
out
}
pub fn tick(&mut self, app: &App, t: f64) {
let out = self.new_report(t);
if out.len() > 0 {
debug!("status","{:?}",out);
}
}
}
#[derive(Clone)]
pub struct Report(Arc<Mutex<ReportImpl>>);
impl Report {
pub fn new(ar: &mut AppRunner) -> Report {
let mut out = Report(Arc::new(Mutex::new(ReportImpl::new())));
for (k,v) in REPORT_CONFIG {
out.set_interval(k,*v);
}
ar.add_timer(enclose! { (out) move |app,t| {
out.clone().tick(app,t)
}},None);
out
}
pub fn set_status(&self, key: &str, value: &str) {
let mut imp = self.0.lock().unwrap();
imp.set_status(key,value);
}
pub fn set_interval(&mut self, key: &str, interval: Option<f64>) {
let mut imp = self.0.lock().unwrap();
imp.set_interval(key,interval);
}
pub fn tick(&mut self, app: &mut App, t: f64) {
self.0.lock().unwrap().tick(app,t);
}
}
......@@ -4,7 +4,7 @@ use serde_json::Value as JSONValue;
use stdweb::web::html_element::SelectElement;
use stdweb::traits::IEvent;
use stdweb::unstable::TryInto;
use stdweb::web::{ Element, IEventTarget, HtmlElement };
use stdweb::web::{ Element, IEventTarget, HtmlElement, INode };
use stdweb::web::event::{ ChangeEvent, ClickEvent };
use controller::input::EggDetector;
......@@ -151,8 +151,14 @@ impl DebugBling {
impl Bling for DebugBling {
fn apply_bling(&self, el: &HtmlElement) -> HtmlElement {
let el : Element = el.clone().into();
if let Some(old) = domutil::query_selector_new("#bpane-css") {
console!("OLD");
domutil::remove(&old);
}
let css = domutil::append_element(&domutil::query_select("head"),"style");
domutil::inner_html(&css,DEBUGSTAGE_CSS);
domutil::add_attr(&css,"id","bpane-css");
domutil::inner_html(&el.clone().into(),DEBUGSTAGE);
domutil::query_selector(&el.clone().into(),".bpane-canv").clone().try_into().unwrap()
}
......
use std::sync::{ Arc, Mutex };
use stdweb::unstable::TryInto;
use stdweb::web::{ Element, HtmlElement };
use stdweb::web::{ Element, HtmlElement, INode };
use controller::global::App;
use dom::{ PLAINSTAGE, PLAINSTAGE_CSS };
......@@ -21,9 +21,13 @@ impl NoBling {
impl Bling for NoBling {
fn apply_bling(&self, el: &HtmlElement) -> HtmlElement {
let el = el.clone();
domutil::inner_html(&el.clone().into(),PLAINSTAGE);
let el = el.clone().into();
domutil::inner_html(&el,PLAINSTAGE);
if let Some(old) = domutil::query_selector2(&el,"#bpane-css") {
domutil::remove(&old);
}
let css = domutil::append_element(&domutil::query_select("head"),"style");
domutil::add_attr(&css,"id","bpane-css");
domutil::inner_html(&css,PLAINSTAGE_CSS);
domutil::query_selector(&el.clone().into(),".bpane-canv").clone().try_into().unwrap()
}
......
......@@ -27,7 +27,11 @@ pub fn query_selector_new(sel: &str) -> Option<Element> {
}
pub fn query_selector2(root: &Element, sel: &str) -> Option<Element> {
root.query_selector(sel).ok().map(|s| s.unwrap())
if let Ok(Some(el)) = root.query_selector(sel) {
Some(el)
} else {
None
}
}
pub fn query_selector(el: &Element, sel: &str) -> Element {
......@@ -100,6 +104,11 @@ pub fn append_element(el: &Element, name: &str) -> Element {
new
}
pub fn remove(el: &Element) {
let parent: Element = el.parent_node().unwrap().try_into().ok().unwrap();
parent.remove_child(el).unwrap_or(el.clone().into());
}
pub fn scroll_to_bottom(el: &Element) {
js! { @{el.as_ref()}.scrollTop = @{el.as_ref()}.scrollHeight; };
}
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment