Skip to content

Commit

Permalink
Simplest implementation of lane subsection selection & dragging #20
Browse files Browse the repository at this point in the history
  • Loading branch information
aeplay committed Dec 8, 2016
1 parent ccf7296 commit 1ba210d
Show file tree
Hide file tree
Showing 7 changed files with 313 additions and 19 deletions.
4 changes: 4 additions & 0 deletions Cargo.toml
Expand Up @@ -22,6 +22,10 @@ path = "./lib/descartes/"
[dependencies.monet]
path = "./lib/monet/"

[profile.dev]
opt-level = 1
codegen-units = 4

[profile.release]
debug = true
codegen-units = 4
22 changes: 20 additions & 2 deletions src/game/lanes_and_cars/planning/current_plan_rendering.rs
@@ -1,8 +1,8 @@
use kay::{Recipient, Fate, ActorSystem};
use descartes::{Band, Path};
use descartes::{Band, Path, FiniteCurve};
use monet::{Thing, Instance};
use ::core::geometry::band_to_thing;
use super::{CurrentPlan, LaneStroke};
use super::{CurrentPlan, LaneStroke, DrawingStatus, SelectableStrokeRef};

use monet::SetupInScene;

Expand Down Expand Up @@ -61,6 +61,24 @@ impl Recipient<RenderToScene> for CurrentPlan {
};
self.ui_state.dirty = false;
}
if let DrawingStatus::WithSelection(SelectableStrokeRef::New(stroke_idx), start, end) = self.ui_state.drawing_status {
if let Some(subsection) = self.delta.new_strokes[stroke_idx].path().subsection(start, end) {
let selection_thing : Thing = band_to_thing(&Band::new(subsection, 2.5), 0.1);
renderer_id << UpdateThing{
scene_id: scene_id,
thing_id: 504,
thing: selection_thing,
instance: Instance::with_color([0.0, 0.0, 1.0])
};
}
} else {
renderer_id << UpdateThing{
scene_id: scene_id,
thing_id: 504,
thing: Thing::new(vec![], vec![]),
instance: Instance::with_color([0.0, 0.0, 1.0])
};
}
Fate::Live
}
}}
Expand Down
31 changes: 29 additions & 2 deletions src/game/lanes_and_cars/planning/lane_stroke.rs
@@ -1,4 +1,4 @@
use descartes::{P2, V2, Path, Segment, Band, FiniteCurve, N, RoughlyComparable};
use descartes::{P2, V2, Path, Segment, Band, Curve, FiniteCurve, N, RoughlyComparable};
use kay::{ID, CVec, Swarm, CreateWith};
use monet::{Thing};
use core::geometry::{CPath, band_to_thing};
Expand Down Expand Up @@ -49,7 +49,7 @@ impl LaneStroke {
}

pub fn preview_thing(&self) -> Thing {
band_to_thing(&Band::new(Band::new(self.path().clone(), 3.0).outline(), 0.3), 0.0)
band_to_thing(&Band::new(Band::new(self.path().clone(), 5.0).outline(), 0.3), 0.0)
}

// TODO: this is slightly ugly
Expand All @@ -71,6 +71,33 @@ impl LaneStroke {
} else {None}
}

pub fn with_subsection_moved(&self, start: N, end: N, delta: V2) -> Option<Self> {
let nodes_before = self.nodes.iter().take_while(|node|
self.path().project(node.position).unwrap() < start
);

let new_subsection = self.subsection(start, end).into_iter()
.flat_map(|subsection| subsection.nodes)
.map(|node| LaneStrokeNode{
position: node.position + delta,
direction: node.direction
});

let nodes_after = self.nodes.iter().skip_while(|node|
self.path().project(node.position).unwrap() < end
);

let new_segments = nodes_before.cloned()
.chain(new_subsection)
.chain(nodes_after.cloned()).collect::<CVec<_>>();

if new_segments.is_empty() {
None
} else {
Some(LaneStroke::new(new_segments))
}
}

pub fn build(&self, report_to: ID, report_as: BuildableRef) {
Swarm::<Lane>::all() << CreateWith(
Lane::new(self.path().clone(), match report_as {
Expand Down
77 changes: 77 additions & 0 deletions src/game/lanes_and_cars/planning/lane_stroke_draggable.rs
@@ -0,0 +1,77 @@
use kay::{ID, Recipient, Actor, Individual, Swarm, ActorSystem, Fate, CreateWith};
use descartes::{Band, Into2d};
use ::core::geometry::{CPath, AnyShape};

use super::{SelectableStrokeRef, CurrentPlan, PlanControl};

#[derive(Actor, Compact, Clone)]
pub struct LaneStrokeDraggable{
_id: ID,
stroke_ref: SelectableStrokeRef,
path: CPath
}

impl LaneStrokeDraggable{
pub fn new(stroke_ref: SelectableStrokeRef, path: CPath) -> Self {
LaneStrokeDraggable{
_id: ID::invalid(),
stroke_ref: stroke_ref,
path: path
}
}
}

use super::AddToUI;
use ::core::ui::Add;

impl Recipient<AddToUI> for LaneStrokeDraggable {
fn receive(&mut self, msg: &AddToUI) -> Fate {match *msg{
AddToUI => {
::core::ui::UserInterface::id() << Add::Interactable3d(
self.id(),
AnyShape::Band(Band::new(self.path.clone(), 2.5)),
2
);
Fate::Live
}
}}
}

use super::ClearDraggables;
use ::core::ui::Remove;

impl Recipient<ClearDraggables> for LaneStrokeDraggable {
fn receive(&mut self, msg: &ClearDraggables) -> Fate {match *msg{
ClearDraggables::One(stroke_ref_to_clear) => {
if self.stroke_ref == stroke_ref_to_clear {
::core::ui::UserInterface::id() << Remove::Interactable3d(self.id());
Fate::Die
} else {
Fate::Live
}
},
ClearDraggables::All(()) => {
::core::ui::UserInterface::id() << Remove::Interactable3d(self.id());
Fate::Die
}
}}
}

use ::core::ui::Event3d;

impl Recipient<Event3d> for LaneStrokeDraggable {
fn receive(&mut self, msg: &Event3d) -> Fate {match *msg{
Event3d::DragFinished{from, to} => {
CurrentPlan::id() << PlanControl::MoveSelection(self.stroke_ref, to.into_2d() - from.into_2d());
Fate::Live
},
_ => Fate::Live
}}
}

pub fn setup(system: &mut ActorSystem) {
system.add_individual(Swarm::<LaneStrokeDraggable>::new());
system.add_inbox::<CreateWith<LaneStrokeDraggable, AddToUI>, Swarm<LaneStrokeDraggable>>();
system.add_inbox::<ClearDraggables, Swarm<LaneStrokeDraggable>>();
system.add_inbox::<Event3d, Swarm<LaneStrokeDraggable>>();
}
81 changes: 81 additions & 0 deletions src/game/lanes_and_cars/planning/lane_stroke_selectable.rs
@@ -0,0 +1,81 @@
use kay::{ID, Recipient, Actor, Individual, Swarm, ActorSystem, Fate, CreateWith};
use descartes::{Band, Curve, Into2d};
use ::core::geometry::{CPath, AnyShape};

use super::{SelectableStrokeRef, CurrentPlan, PlanControl};

#[derive(Actor, Compact, Clone)]
pub struct LaneStrokeSelectable{
_id: ID,
stroke_ref: SelectableStrokeRef,
path: CPath
}

impl LaneStrokeSelectable{
pub fn new(stroke_ref: SelectableStrokeRef, path: CPath) -> Self {
LaneStrokeSelectable{
_id: ID::invalid(),
stroke_ref: stroke_ref,
path: path
}
}
}

use super::AddToUI;
use ::core::ui::Add;

impl Recipient<AddToUI> for LaneStrokeSelectable {
fn receive(&mut self, msg: &AddToUI) -> Fate {match *msg{
AddToUI => {
::core::ui::UserInterface::id() << Add::Interactable3d(
self.id(),
AnyShape::Band(Band::new(self.path.clone(), 2.5)),
1
);
Fate::Live
}
}}
}

use super::ClearSelectables;
use ::core::ui::Remove;

impl Recipient<ClearSelectables> for LaneStrokeSelectable {
fn receive(&mut self, msg: &ClearSelectables) -> Fate {match *msg{
ClearSelectables::One(stroke_ref_to_clear) => {
if self.stroke_ref == stroke_ref_to_clear {
::core::ui::UserInterface::id() << Remove::Interactable3d(self.id());
Fate::Die
} else {
Fate::Live
}
},
ClearSelectables::All(()) => {
::core::ui::UserInterface::id() << Remove::Interactable3d(self.id());
Fate::Die
}
}}
}

use ::core::ui::Event3d;

impl Recipient<Event3d> for LaneStrokeSelectable {
fn receive(&mut self, msg: &Event3d) -> Fate {match *msg{
Event3d::DragOngoing{from, to} => {
if let (Some(selection_start), Some(selection_end)) =
(self.path.project(from.into_2d()), self.path.project(to.into_2d())) {
CurrentPlan::id() << PlanControl::Select(self.stroke_ref, selection_start, selection_end);
}
Fate::Live
},
_ => Fate::Live
}}
}


pub fn setup(system: &mut ActorSystem) {
system.add_individual(Swarm::<LaneStrokeSelectable>::new());
system.add_inbox::<CreateWith<LaneStrokeSelectable, AddToUI>, Swarm<LaneStrokeSelectable>>();
system.add_inbox::<ClearSelectables, Swarm<LaneStrokeSelectable>>();
system.add_inbox::<Event3d, Swarm<LaneStrokeSelectable>>();
}
2 changes: 0 additions & 2 deletions src/game/lanes_and_cars/planning/materialized_reality.rs
Expand Up @@ -16,7 +16,6 @@ pub struct Simulate{pub requester: ID, pub delta: PlanDelta}
#[derive(Compact, Clone)]
pub struct SimulationResult{
pub remaining_old_strokes: RemainingOldStrokes,
pub result: PlanResult,
pub result_delta: PlanResultDelta
}

Expand All @@ -28,7 +27,6 @@ impl Recipient<Simulate> for MaterializedReality {
let result_delta = result.delta(&self.current_result);
requester << SimulationResult{
remaining_old_strokes: remaining_old_strokes,
result: result,
result_delta: result_delta,
};
Fate::Live
Expand Down

0 comments on commit 1ba210d

Please sign in to comment.