Commit 018b2ab6 authored by Dan Sheppard's avatar Dan Sheppard
Browse files

Refactor source module to avoid unnecessary clones.

(Speeds up FF by about 10%).
parent 95971f14
......@@ -5,7 +5,7 @@ const MAX_PENDING : i32 = 0;
const CACHE_SIZE : usize = 10;
use composit::{
ActiveSource, Leaf, Carriage
ActiveSource, Leaf, Carriage, AllSourceResponseBuilder
};
pub struct ComponentManager {
......@@ -32,11 +32,14 @@ impl ComponentManager {
pub fn make_comp_carriages(&mut self, c: &ActiveSource, leaf: &Leaf) -> Vec<Carriage> {
let mut lcomps = Vec::<Carriage>::new();
lcomps.push(c.make_carriage(&None,&leaf));
let asrb = AllSourceResponseBuilder::new(&c.list_parts());
let mut source = c.get_source().clone();
lcomps.push(c.make_carriage(&asrb,&None,&leaf));
for part in c.list_parts() {
debug!("redraw","make_carriages {:?} for {}",leaf,part);
lcomps.push(c.make_carriage(&Some(part),&leaf));
lcomps.push(c.make_carriage(&asrb,&Some(part),&leaf));
}
source.populate(c,asrb,leaf);
lcomps
}
......
......@@ -16,8 +16,9 @@ mod position;
mod wrapping;
pub use self::source::{
CombinedSource, Source, SourceResponse, ActiveSource,
DrawnResponse, SourceManager, SourceManagerList, CombinedSourceManager
CombinedSource, Source, SourceResponseBuilder, ActiveSource,
DrawnResponse, SourceManager, SourceManagerList, CombinedSourceManager,
AllSourceResponseBuilder, SourceResponseResult
};
pub use self::combinedstickmanager::CombinedStickManager;
pub use self::componentset::ComponentSet;
......
......@@ -7,7 +7,7 @@ use std::rc::Rc;
use composit::state::StateExpr;
use composit::{
AllLandscapes, Landscape, Source,
Carriage, Leaf, SourceResponse, StateManager,
Carriage, Leaf, AllSourceResponseBuilder, StateManager,
StateValue
};
......@@ -33,6 +33,8 @@ impl ActiveSource {
out
}
pub fn get_source(&self) -> &Rc<Source> { &self.source }
pub fn new_part(&mut self, part: Option<&str>, ooe: Rc<StateExpr>) {
self.parts.insert(part.map(|x| x.to_string()),SourcePart::new(part,&ooe));
}
......@@ -41,16 +43,12 @@ impl ActiveSource {
self.parts.keys().filter(|x| x.is_some()).map(|x| x.as_ref().unwrap().clone()).collect()
}
pub fn make_carriage(&self, part: &Option<String>, leaf: &Leaf) -> Carriage {
let mut c = Carriage::new(self.clone(),part,leaf);
let mut source = c.get_source().clone();
let mut resp = SourceResponse::new(source.get_name(),&source.list_parts());
source.populate(&mut resp,c.get_leaf());
c.set_response(resp);
c
pub fn make_carriage(&self, asrb: &AllSourceResponseBuilder, part: &Option<String>, leaf: &Leaf) -> Carriage {
let srr = asrb.get_srr(part);
Carriage::new(self.clone(),part,leaf,srr)
}
pub fn populate(&mut self, resp: &mut SourceResponse, leaf: &Leaf) {
pub fn populate(&mut self, resp: AllSourceResponseBuilder, leaf: &Leaf) {
let twin = self.source.clone();
twin.populate(self,resp,leaf);
}
......
use std::collections::HashMap;
use super::{ SourceResponseBuilder, SourceResponseResult };
pub struct AllSourceResponseBuilder {
parts: HashMap<Option<String>,(SourceResponseBuilder,SourceResponseResult)>,
done: bool
}
fn new_entry() -> (SourceResponseBuilder,SourceResponseResult) {
(SourceResponseBuilder::new(),SourceResponseResult::new())
}
impl AllSourceResponseBuilder {
pub fn new(parts: &Vec<String>) -> AllSourceResponseBuilder {
let mut out = AllSourceResponseBuilder {
parts: HashMap::<Option<String>,(SourceResponseBuilder,SourceResponseResult)>::new(),
done: false
};
for p in parts {
out.parts.insert(Some(p.to_string()),new_entry());
}
out.parts.insert(None,new_entry());
out
}
pub fn get_srr(&self, part: &Option<String>) -> SourceResponseResult {
self.parts.get(part).map(|x| x.1.clone()).unwrap()
}
pub fn get_mut(&mut self, part: &Option<String>) -> Option<&mut SourceResponseBuilder> {
self.parts.get_mut(part).map(|x| &mut x.0)
}
pub fn remove(&mut self, part: &Option<String>) -> Option<SourceResponseBuilder> {
self.parts.remove(part).map(|x| x.0)
}
pub fn done(&mut self) {
console!("DONE");
self.done = true;
for (_,(srb,mut srr)) in self.parts.drain() {
srr.set(srb);
}
}
pub fn is_done(&mut self) -> bool {
self.done
}
}
......@@ -2,7 +2,7 @@ use std::collections::HashMap;
use std::rc::Rc;
use composit::{
ActiveSource, Landscape, Leaf, Plot, Source, SourceResponse,
ActiveSource, Landscape, Leaf, Plot, Source, AllSourceResponseBuilder,
StateAtom, AllLandscapes, StateExpr
};
use data::{ BackendConfig, HttpXferClerk };
......@@ -37,7 +37,7 @@ impl CombinedSource {
}
impl Source for CombinedSource {
fn populate(&self, acs: &ActiveSource, lc: &mut SourceResponse, leaf: &Leaf) {
fn populate(&self, acs: &ActiveSource, lc: AllSourceResponseBuilder, leaf: &Leaf) {
let stick_name = leaf.get_stick().get_name();
if let Some(source) = self.per_stick_sources.get(&stick_name) {
source.populate(acs,lc,leaf);
......
use composit::SourceResponse;
use composit::SourceResponseBuilder;
use composit::Source;
use drawing::Drawing;
use drawing::DrawingSession;
......@@ -8,53 +8,41 @@ use shape::{ ShapeSpec, Shape };
pub struct DrawnResponse {
drawings: Vec<Option<Drawing>>,
sr: SourceResponse,
part: Option<String>
sr: SourceResponseBuilder,
}
impl DrawnResponse {
pub fn new(sr: SourceResponse, part: &Option<String>) -> DrawnResponse {
pub fn new(sr: SourceResponseBuilder) -> DrawnResponse {
DrawnResponse {
sr,
drawings: Vec::<Option<Drawing>>::new(),
part: part.clone()
}
}
fn shapes(&self) -> Vec<ShapeSpec> {
self.sr.get_shapes(&self.part)
}
#[allow(unused)]
pub fn size(&self) -> usize { self.shapes().len() }
pub fn is_done(&self) -> bool { self.sr.is_done() }
pub fn size(&self) -> usize { self.sr.get_shapes().len() }
pub fn redraw(&mut self, ds: &mut DrawingSession) {
if self.sr.is_done() {
self.drawings.clear();
for mut s in self.shapes() {
if let Some(a) = s.get_artist() {
let ocm = a.select_canvas(ds);
self.drawings.push(Some(ocm.add_request(a)));
} else {
self.drawings.push(None);
}
self.drawings.clear();
for mut s in self.sr.get_shapes() {
if let Some(a) = s.get_artist() {
let ocm = a.select_canvas(ds);
self.drawings.push(Some(ocm.add_request(a)));
} else {
self.drawings.push(None);
}
}
}
pub fn into_objects(&mut self, progs: &mut Programs,
ds: &mut DrawingSession, e: &mut PrintEdition) {
if self.sr.is_done() {
let mut di = self.drawings.iter();
for mut s in self.shapes().iter() {
let d = di.next();
let geom_name = s.get_geometry();
if let Some(geom) = progs.map.get_mut(&geom_name) {
let artwork = d.unwrap().as_ref().map(|r| r.artwork(ds));
s.into_objects(&mut geom.data,artwork,e);
}
let mut di = self.drawings.iter();
for mut s in self.sr.get_shapes().iter() {
let d = di.next();
let geom_name = s.get_geometry();
if let Some(geom) = progs.map.get_mut(&geom_name) {
let artwork = d.unwrap().as_ref().map(|r| r.artwork(ds));
s.into_objects(&mut geom.data,artwork,e);
}
}
}
......
mod activesource;
mod allsourceresponsebuilder;
mod combinedsource;
mod combinedsourcemanager;
mod drawnresponse;
......@@ -6,14 +7,15 @@ mod source;
mod sourcemanager;
mod sourcemanagerlist;
mod sourcepart;
mod sourceresponse;
mod sourceresponsebuilder;
pub use self::activesource::ActiveSource;
pub use self::allsourceresponsebuilder::AllSourceResponseBuilder;
pub use self::combinedsource::{ CombinedSource, build_combined_source };
pub use self::combinedsourcemanager::CombinedSourceManager;
pub use self::source::Source;
pub use self::sourcemanager::SourceManager;
pub use self::sourcemanagerlist::SourceManagerList;
pub use self::sourcepart::SourcePart;
pub use self::sourceresponse::SourceResponse;
pub use self::sourceresponsebuilder::{ SourceResponseBuilder, SourceResponseResult };
pub use self::drawnresponse::DrawnResponse;
use composit::{ Leaf, SourceResponse, ActiveSource };
use composit::{ Leaf, AllSourceResponseBuilder, ActiveSource };
pub trait Source {
fn populate(&self, acs: &ActiveSource, lc: &mut SourceResponse, leaf: &Leaf);
fn populate(&self, acs: &ActiveSource, lc: AllSourceResponseBuilder, leaf: &Leaf);
}
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
use shape::ShapeSpec;
pub struct SourceResponseImpl {
source_name: String,
shapes: HashMap<Option<String>,Vec<ShapeSpec>>,
max_y: Option<i32>,
done: bool
}
impl SourceResponseImpl {
fn new(source_name: &str, parts: &[String]) -> SourceResponseImpl {
let mut out = SourceResponseImpl {
shapes: HashMap::<Option<String>,Vec<ShapeSpec>>::new(),
max_y: None,
done: false,
source_name: source_name.to_string()
};
out.shapes.insert(None,Vec::<ShapeSpec>::new());
for p in parts {
out.shapes.insert(Some(p.to_string()),Vec::<ShapeSpec>::new());
}
out
}
pub fn expect(&mut self, amt: usize) {
for (k,v) in &mut self.shapes {
v.reserve(amt);
}
}
pub fn get_source_name(&self) -> &str { &self.source_name }
fn add_shape(&mut self, part: &Option<String>, item: ShapeSpec) {
if let Some(ref mut list) = self.shapes.get_mut(part) {
list.push(item);
}
}
fn done(&mut self, max_y: i32) {
self.max_y = Some(max_y);
self.done = true;
}
fn get_max_y(&self) -> i32 { self.max_y.unwrap_or(0) }
fn is_done(&self) -> bool { self.done }
fn get_shapes(&self, part: &Option<String>) -> &Vec<ShapeSpec> {
&self.shapes[part]
}
pub fn size(&self) -> usize {
self.shapes.len()
}
}
#[derive(Clone)]
pub struct SourceResponse(Rc<RefCell<SourceResponseImpl>>);
impl SourceResponse {
pub fn new(source_name: &str, parts: &[String]) -> SourceResponse {
SourceResponse(Rc::new(RefCell::new(SourceResponseImpl::new(source_name,parts))))
}
pub fn expect(&self, amt: usize) {
self.0.borrow_mut().expect(amt);
}
pub fn add_shape(&mut self, part: &Option<String>, item: ShapeSpec) {
self.0.borrow_mut().add_shape(part,item);
}
pub fn get_source_name(&self) -> String {
self.0.borrow().get_source_name().to_string()
}
pub fn done(&mut self, max_y: i32) {
self.0.borrow_mut().done(max_y);
}
pub fn is_done(&self) -> bool { self.0.borrow().is_done() }
pub fn get_max_y(&self) -> i32 { self.0.borrow().get_max_y() }
pub fn size(&self) -> usize { self.0.borrow_mut().size() }
pub fn get_shapes(&self, part: &Option<String>) -> Vec<ShapeSpec> {
self.0.borrow_mut().get_shapes(part).clone()
}
}
use std::cell::RefCell;
use std::collections::HashMap;
use std::rc::Rc;
use composit::DrawnResponse;
use shape::ShapeSpec;
#[derive(Clone)]
pub struct SourceResponseResult(Rc<RefCell<Option<DrawnResponse>>>);
impl SourceResponseResult {
pub fn new() -> SourceResponseResult {
SourceResponseResult(Rc::new(RefCell::new(None)))
}
pub fn set(&mut self, result: SourceResponseBuilder) {
*self.0.borrow_mut() = Some(DrawnResponse::new(result));
}
pub fn take(&mut self) -> Option<DrawnResponse> {
self.0.borrow_mut().take()
}
pub fn check(&self) -> bool {
self.0.borrow().is_some()
}
}
pub struct SourceResponseBuilder {
shapes: Vec<ShapeSpec>
}
impl SourceResponseBuilder {
pub fn new() -> SourceResponseBuilder {
SourceResponseBuilder {
shapes: Vec::<ShapeSpec>::new()
}
}
pub fn expect(&mut self, amt: usize) {
self.shapes.reserve(amt);
}
pub fn add_shape(&mut self, item: ShapeSpec) {
self.shapes.push(item);
}
pub fn get_shapes(&self) -> &Vec<ShapeSpec> {
&self.shapes
}
pub fn size(&self) -> usize {
self.shapes.len()
}
}
use std::fmt;
use print::{ Programs, PrintEdition };
use composit::{ SourceResponse, Leaf, ActiveSource, DrawnResponse };
use composit::{
SourceResponseBuilder, Leaf, ActiveSource, DrawnResponse,
SourceResponseResult
};
use composit::state::{ StateManager, StateValue, ComponentRedo };
use drawing::DrawingSession;
......@@ -9,20 +12,21 @@ pub struct Carriage {
comp: ActiveSource,
prev_value: StateValue,
cur_value: StateValue,
srr: SourceResponseResult,
response: Option<DrawnResponse>,
part: Option<String>,
leaf: Leaf
}
impl Carriage {
pub fn new(comp: ActiveSource, part: &Option<String>, leaf: &Leaf) -> Carriage {
pub fn new(comp: ActiveSource, part: &Option<String>, leaf: &Leaf, srr: SourceResponseResult) -> Carriage {
Carriage {
response: None,
prev_value: StateValue::OffCold(),
cur_value: StateValue::OffCold(),
leaf: leaf.clone(),
part: part.clone(),
comp
comp, srr
}
}
......@@ -42,12 +46,20 @@ impl Carriage {
ComponentRedo::Minor // was/is off-warm, is/was on => Minor
}
}
pub(in super) fn is_done(&self) -> bool {
self.response.as_ref().map(|x| x.is_done()).unwrap_or(false)
if self.srr.check() { return true; }
return self.response.is_some();
}
fn promote(&mut self) {
if self.response.is_none() {
self.response = Some(self.srr.take().unwrap());
}
}
pub fn draw_drawings(&mut self, ds: &mut DrawingSession) {
self.promote();
if let Some(ref mut response) = self.response {
response.redraw(ds);
}
......@@ -56,6 +68,7 @@ impl Carriage {
pub fn into_objects(&mut self,
progs: &mut Programs,
ds: &mut DrawingSession, e: &mut PrintEdition) {
self.promote();
if let Some(ref mut response) = self.response {
response.into_objects(progs,ds,e);
}
......@@ -65,8 +78,8 @@ impl Carriage {
pub fn get_source(&self) -> &ActiveSource { &self.comp }
pub(in super) fn get_part(&self) -> &Option<String> { &self.part }
pub fn set_response(&mut self, r: SourceResponse) {
self.response = Some(DrawnResponse::new(r,&self.part));
pub fn set_response(&mut self, r: SourceResponseBuilder) {
self.response = Some(DrawnResponse::new(r));
}
}
......
......@@ -3,11 +3,11 @@ use std::rc::Rc;
use stdweb::web::window;
use stdweb::web::IWindowOrWorker;
use composit::{ Source, SourceResponse, Leaf, ActiveSource };
use composit::{ Source, AllSourceResponseBuilder, Leaf, ActiveSource };
use shape::ShapeSpec;
pub struct ClosureSourceImpl {
f: Box<Fn(&mut SourceResponse,&Leaf)>,
f: Box<Fn(&mut AllSourceResponseBuilder,&Leaf)>,
delay: f32
}
......@@ -16,31 +16,29 @@ pub struct ClosureSource(Rc<ClosureSourceImpl>);
impl ClosureSource {
pub fn new<F>(delay: f32, f: F) -> ClosureSource
where F: Fn(&mut SourceResponse,&Leaf) + 'static {
where F: Fn(&mut AllSourceResponseBuilder,&Leaf) + 'static {
ClosureSource(Rc::new(ClosureSourceImpl{ f: Box::new(f), delay }))
}
}
impl Source for ClosureSource {
fn populate(&self, acs: &ActiveSource, lc: &mut SourceResponse, leaf: &Leaf) {
fn populate(&self, acs: &ActiveSource, mut lc: AllSourceResponseBuilder, leaf: &Leaf) {
let cs = self.clone();
let mut lc = lc.clone();
let leaf = leaf.clone();
window().set_timeout(move || {
(cs.0.f)(&mut lc,&leaf);
},(self.0.delay * 1000.) as u32);
(cs.0.f)(&mut lc,&leaf);
}
}
pub fn closure_add_opt(lcb: &mut SourceResponse, s: &Option<ShapeSpec>) {
pub fn closure_add_opt(lcb: &mut AllSourceResponseBuilder, s: &Option<ShapeSpec>) {
if let Some(s) = s {
closure_add(lcb,s);
}
}
pub fn closure_add(lcb: &mut SourceResponse, s: &ShapeSpec) {
lcb.add_shape(&None,s.clone());
pub fn closure_add(lcb: &mut AllSourceResponseBuilder, s: &ShapeSpec) {
let mut srb = lcb.get_mut(&None).unwrap();
srb.add_shape(s.clone());
}
pub fn closure_done(lcb: &mut SourceResponse, max_y: i32) {
lcb.done(max_y);
pub fn closure_done(lcb: &mut AllSourceResponseBuilder) {
lcb.done();
}
......@@ -2,7 +2,7 @@ use std::collections::HashMap;
use std::rc::Rc;
use composit::{
ActiveSource, Landscape, Leaf, Plot, Source, SourceResponse,
ActiveSource, Landscape, Leaf, Plot, Source, SourceResponseBuilder,
StateAtom, AllLandscapes, CombinedSource
};
......
......@@ -11,7 +11,7 @@ use rand::SeedableRng;
use composit::{
StateFixed, StateValue, StateAtom, Leaf, Carriage,
SourceResponse, Stick
AllSourceResponseBuilder, Stick
};
use debug::support::closuresource::{ ClosureSource, closure_add, closure_add_opt, closure_done };
......@@ -54,7 +54,7 @@ fn battenberg() -> DrawingSpec {
255,255,0,255 },cpixel(2,2),false,None)
}
fn measure(lc: &mut SourceResponse, leaf: &Leaf, cs: &ColourSpec, cs2: &ColourSpec) {
fn measure(lc: &mut AllSourceResponseBuilder, leaf: &Leaf, cs: &ColourSpec, cs2: &ColourSpec) {
for x in -10..10 {
let prts = PinRectTypeSpec {
sea_x: None,
......@@ -182,7 +182,7 @@ fn source_odd() -> ClosureSource {
}
}