Skip to content

Commit

Permalink
Replace StewardData trait (completes #46)
Browse files Browse the repository at this point in the history
  • Loading branch information
elidupree committed Sep 7, 2017
1 parent 47e5fbe commit 4fe0780
Show file tree
Hide file tree
Showing 12 changed files with 58 additions and 110 deletions.
10 changes: 1 addition & 9 deletions dev-shared/bouncy_circles_rowless.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use time_steward::support::rounding_error_tolerant_math::right_shift_round_up;


use time_steward::{DeterministicRandomId};
use time_steward::rowless::api::{PersistentTypeId, ListedType, PersistentlyIdentifiedType, StewardData, DataHandleTrait, DataTimelineCellTrait, ExtendedTime, Basics as BasicsTrait};
use time_steward::rowless::api::{PersistentTypeId, ListedType, PersistentlyIdentifiedType, DataHandleTrait, DataTimelineCellTrait, ExtendedTime, Basics as BasicsTrait};
use time_steward::rowless::stewards::{simple_full as steward_module};
use steward_module::{TimeSteward, ConstructibleTimeSteward, Event, DataHandle, DataTimelineCell, Accessor, EventAccessor, FutureCleanupAccessor, SnapshotAccessor, simple_timeline};
use simple_timeline::{SimpleTimeline, GetVarying, IterateUniquelyOwnedPredictions, tracking_query, modify_simple_timeline, unmodify_simple_timeline};
Expand Down Expand Up @@ -49,8 +49,6 @@ pub struct CircleVarying {
pub boundary_induced_acceleration: Option <Vector2<SpaceCoordinate>>,
pub next_boundary_change: Option <<Steward as TimeSteward>::EventHandle>,
}
impl StewardData for Circle {}
impl StewardData for CircleVarying {}
impl PersistentlyIdentifiedType for Circle {
const ID: PersistentTypeId = PersistentTypeId(0xd711cc7240c71607);
}
Expand All @@ -73,8 +71,6 @@ pub struct RelationshipVarying {
pub induced_acceleration: Option <Vector2<SpaceCoordinate>>,
pub next_change: Option <<Steward as TimeSteward>::EventHandle>,
}
impl StewardData for Relationship {}
impl StewardData for RelationshipVarying {}
impl PersistentlyIdentifiedType for Relationship {
const ID: PersistentTypeId = PersistentTypeId(0xa1010b5e80c3465a);
}
Expand Down Expand Up @@ -133,7 +129,6 @@ pub fn update_relationship_change_prediction <Accessor: EventAccessor <Steward =

#[derive (Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
pub struct RelationshipChange {pub relationship_handle: RelationshipHandle} //, Basics, EventId (0x2312e29e341a2495),
impl StewardData for RelationshipChange {}
impl PersistentlyIdentifiedType for RelationshipChange {
const ID: PersistentTypeId = PersistentTypeId(0x08c4b60ad5d0ed08);
}
Expand Down Expand Up @@ -221,7 +216,6 @@ pub fn update_predictions <Accessor: EventAccessor <Steward = Steward>>(accessor

#[derive (Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
pub struct BoundaryChange {pub circle_handle: CircleHandle} //, Basics, EventId (0x59732d675b2329ad),
impl StewardData for BoundaryChange {}
impl PersistentlyIdentifiedType for BoundaryChange {
const ID: PersistentTypeId = PersistentTypeId(0x6fc5127ff6aeb50d);
}
Expand Down Expand Up @@ -255,7 +249,6 @@ impl Event for BoundaryChange {

#[derive (Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
pub struct Initialize {} //, Basics, EventId (0xa2a17317b84f96e5),
impl StewardData for Initialize {}
impl PersistentlyIdentifiedType for Initialize {
const ID: PersistentTypeId = PersistentTypeId(0xbf7ba1ff2ab76640);
}
Expand Down Expand Up @@ -316,7 +309,6 @@ impl Event for Initialize {

#[derive (Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
pub struct Disturb {pub coordinates: [SpaceCoordinate; 2]} //, Basics, EventId (0x058cb70d89116605),
impl StewardData for Disturb {}
impl PersistentlyIdentifiedType for Disturb {
const ID: PersistentTypeId = PersistentTypeId(0xb8bbf65eaaf08d0e);
}
Expand Down
2 changes: 1 addition & 1 deletion examples/bouncy_circles_rowless.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ use std::time::{Instant, Duration};
use glium::{DisplayBuild, Surface};

use time_steward::{DeterministicRandomId};
use time_steward::rowless::api::{PersistentTypeId, ListedType, PersistentlyIdentifiedType, StewardData, DataTimelineCellTrait, Basics as BasicsTrait};
use time_steward::rowless::api::{PersistentTypeId, ListedType, PersistentlyIdentifiedType, DataTimelineCellTrait, Basics as BasicsTrait};
use time_steward::rowless::stewards::{simple_full as steward_module};
use steward_module::{TimeSteward, ConstructibleTimeSteward, Event, DataTimelineCell, Accessor, EventAccessor, FutureCleanupAccessor, SnapshotAccessor, simple_timeline};
use simple_timeline::{SimpleTimeline, GetVarying, IterateUniquelyOwnedPredictions, tracking_query, modify_simple_timeline, unmodify_simple_timeline};
Expand Down
10 changes: 1 addition & 9 deletions examples/quadtree_diffusion.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ use std::cmp::{min, max};
use std::collections::HashSet;

use time_steward::{DeterministicRandomId};
use time_steward::rowless::api::{self, PersistentTypeId, PersistentlyIdentifiedType, ListedType, StewardData, DataHandleTrait, DataTimelineCellTrait, ExtendedTime, Basics as BasicsTrait};
use time_steward::rowless::api::{self, PersistentTypeId, PersistentlyIdentifiedType, ListedType, DataHandleTrait, DataTimelineCellTrait, ExtendedTime, Basics as BasicsTrait};
use time_steward::rowless::stewards::{simple_full as steward_module};
use steward_module::{TimeSteward, ConstructibleTimeSteward, IncrementalTimeSteward, Event, DataHandle, DataTimelineCell, EventHandle, Accessor, EventAccessor, FutureCleanupAccessor, SnapshotAccessor, simple_timeline};
use simple_timeline::{SimpleTimeline, GetVarying, IterateUniquelyOwnedPredictions, tracking_query, modify_simple_timeline, unmodify_simple_timeline};
Expand Down Expand Up @@ -95,8 +95,6 @@ struct NodeVarying {
slope: [Amount; 2],
}
type NodeHandle = DataHandle <NodeData>;
impl StewardData for NodeData {}
impl StewardData for NodeVarying {}
impl PersistentlyIdentifiedType for NodeData {
const ID: PersistentTypeId = PersistentTypeId(0x734528f6aefdc1b9);
}
Expand All @@ -116,8 +114,6 @@ struct BoundaryVarying {
next_change: Option <EventHandle <Basics>>,
}
type BoundaryHandle = DataHandle <BoundaryData>;
impl StewardData for BoundaryData {}
impl StewardData for BoundaryVarying {}
impl PersistentlyIdentifiedType for BoundaryData {
const ID: PersistentTypeId = PersistentTypeId(0x9d643214b58b24dc);
}
Expand Down Expand Up @@ -752,14 +748,12 @@ struct Globals {

root: NodeHandle,
}
impl StewardData for Globals {}



/// The TransferChange event, as used above.
#[derive (Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
struct TransferChange {boundary: BoundaryHandle}
impl StewardData for TransferChange {}
impl PersistentlyIdentifiedType for TransferChange {
const ID: PersistentTypeId = PersistentTypeId(0xd6621e9cfad1c765);
}
Expand Down Expand Up @@ -847,7 +841,6 @@ impl Event for TransferChange {
#[derive (Clone, PartialEq, Eq, Debug)]
struct AddInk {coordinates: [Distance; 2], amount: Amount, accumulation: Amount}
serialization_cheat!([][AddInk]);
impl StewardData for AddInk {}
impl PersistentlyIdentifiedType for AddInk {
const ID: PersistentTypeId = PersistentTypeId(0x3e6d029c3da8b9a2);
}
Expand Down Expand Up @@ -882,7 +875,6 @@ impl Event for AddInk {

#[derive (Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
struct Initialize {}
impl StewardData for Initialize {}
impl PersistentlyIdentifiedType for Initialize {
const ID: PersistentTypeId = PersistentTypeId(0xf0d2d9134cfe9b49);
}
Expand Down
9 changes: 1 addition & 8 deletions examples/simple_diffusion_rowless.rs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ macro_rules! printlnerr(

use std::cmp::{min, max};
use time_steward::{DeterministicRandomId};
use time_steward::rowless::api::{self, PersistentTypeId, PersistentlyIdentifiedType, ListedType, StewardData, DataHandleTrait, DataTimelineCellTrait, ExtendedTime, Basics as BasicsTrait};
use time_steward::rowless::api::{self, PersistentTypeId, PersistentlyIdentifiedType, ListedType, DataHandleTrait, DataTimelineCellTrait, ExtendedTime, Basics as BasicsTrait};
use time_steward::rowless::stewards::{simple_flat as steward_module};
use steward_module::{TimeSteward, ConstructibleTimeSteward, IncrementalTimeSteward, Event, DataHandle, DataTimelineCell, EventHandle, Accessor, EventAccessor, FutureCleanupAccessor, SnapshotAccessor, simple_timeline};
use simple_timeline::{SimpleTimeline, GetVarying, IterateUniquelyOwnedPredictions, tracking_query, modify_simple_timeline, unmodify_simple_timeline};
Expand Down Expand Up @@ -57,7 +57,6 @@ struct Globals {

cells: Vec<Cell>,
}
impl StewardData for Globals {}

// Derive all the traits required for field data types.
#[derive (Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
Expand Down Expand Up @@ -89,9 +88,6 @@ struct TransferVarying {
accumulated_error: i64,
next_change: Option <EventHandle <Basics>>,
}
impl StewardData for Cell {}
impl StewardData for CellVarying {}
impl StewardData for TransferVarying {}
impl IterateUniquelyOwnedPredictions <Steward> for CellVarying {}
impl IterateUniquelyOwnedPredictions <Steward> for TransferVarying {
fn iterate_predictions <F: FnMut (& <Steward as TimeSteward>::EventHandle)> (&self, callback: &mut F) {
Expand Down Expand Up @@ -414,7 +410,6 @@ fn get_cell <A: Accessor <Steward = Steward >> (accessor: &A, coordinates: [i32;
/// The TransferChange event, as used above.
#[derive (Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
struct TransferChange {coordinates: [i32; 2], dimension: usize}
impl StewardData for TransferChange {}
impl PersistentlyIdentifiedType for TransferChange {
const ID: PersistentTypeId = PersistentTypeId(0xd6621e9cfad1c765);
}
Expand Down Expand Up @@ -515,7 +510,6 @@ impl Event for TransferChange {
/// For these simple events, we lazily use the pseudo-closure syntax.
#[derive (Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
struct Initialize {}
impl StewardData for Initialize {}
impl PersistentlyIdentifiedType for Initialize {
const ID: PersistentTypeId = PersistentTypeId(0xf0d2d9134cfe9b49);
}
Expand Down Expand Up @@ -549,7 +543,6 @@ impl Event for Initialize {
}
#[derive (Clone, PartialEq, Eq, Serialize, Deserialize, Debug)]
struct AddInk {coordinates: [i32; 2], amount: i64, accumulation: i64}
impl StewardData for AddInk {}
impl PersistentlyIdentifiedType for AddInk {
const ID: PersistentTypeId = PersistentTypeId(0x3e6d029c3da8b9a2);
}
Expand Down
32 changes: 19 additions & 13 deletions src/rowless/api.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,16 @@ pub trait ListOfTypes {

/// Data used for a TimeSteward simulation, such as times, entities, and events.
///
/// TimeSteward has strong requirements for serializability. In addition to implementing these traits, a StewardData must have all its behavior be invariant under cloning and serialize-deserialize cycles, and identical to that of any other object that is == to it.
/// We used to require `Send + Sync` for this, but now that DataTimelineHandles can be part of StewardData, we have to omit that to support TimeSteward types that have !Send/!Sync handles (like Rc)
pub trait StewardData: Any + Clone + Eq + Serialize + DeserializeOwned + Debug {}
/// We used to require `Send + Sync` for SimulationStateData, but now that DataTimelineHandles can be part of SimulationStateData, we have to omit that to support TimeSteward types that have !Send/!Sync handles (like Rc)
pub trait SimulationStateData: Any + Debug + Serialize + DeserializeOwned {}
impl<T: Any + Debug + Serialize + DeserializeOwned> SimulationStateData for T {}

/// Queries need PersistentlyIdentifiedType in case I want to serialize them to compare with the same queries on other devices.
/// Results don't need it because they can be identified using the same id as the query.
pub trait Query: Any + Debug + Clone + Eq + Serialize + DeserializeOwned + PersistentlyIdentifiedType {}
impl<T: Any + Debug + Clone + Eq + Serialize + DeserializeOwned + PersistentlyIdentifiedType> Query for T {}
pub trait QueryResult: Any + Debug + Clone + Eq + Serialize + DeserializeOwned {}
impl<T: Any + Debug + Clone + Eq + Serialize + DeserializeOwned> QueryResult for T {}

// Model: events interact with the physics only through queries at their exact time (which are forbidden to query other timelines or have any side effects) and modifications at their exact time (which are forbidden to return any information). Those modifications, in practice, change the state *going forward from* that time, and the events must use invalidate() to collect future events that must be invalidated. (Although, for instance, modifications made for dependency tracking purposes might not change any results any queries, so they wouldn't create the need for any invalidation.)
//To audit, we record all of the queries and query results. Then after each event that modifies one or more DataTimelines, we rerun all queries to those timelines made by still-valid future events. If any query has a different result than before, it's an error.
Expand All @@ -57,13 +63,13 @@ pub trait DataTimeline: Any + Clone + Serialize + DeserializeOwned + Debug {
// audit: forget functions don't change any query results except those forgotten
fn forget_before (&mut self, time: &ExtendedTime <Self::Basics>);
}
pub trait DataTimelineQueriableWith<Query: StewardData>: DataTimeline {
type QueryResult: StewardData;
pub trait DataTimelineQueriableWith<Q: Query>: DataTimeline {
type QueryResult: QueryResult;

// audit: queries must not have side effects (do a separate action for manual dependency tracking)
// audit: queries don't return PredictionHandles that don't exist at the time
// TODO: allow queries to return references instead of values
fn query (&self, query: &Query, time: &ExtendedTime <Self::Basics>)->Self::QueryResult;
fn query (&self, query: &Q, time: &ExtendedTime <Self::Basics>)->Self::QueryResult;
}


Expand All @@ -73,8 +79,8 @@ This is intended to be implemented on an empty struct. Requiring Clone etc. is a
*/
pub trait Basics
: Any + Send + Sync + Copy + Clone + Ord + Hash + Serialize + DeserializeOwned + Debug + Default {
type Time: StewardData + Ord + Hash;
type Globals: StewardData;
type Time: SimulationStateData + Send + Sync + Clone + Ord + Hash;
type Globals: SimulationStateData;
type Types: ListOfTypes;
const MAX_ITERATION: IterationType = 65535;
}
Expand Down Expand Up @@ -102,16 +108,16 @@ pub enum FiatEventOperationError {
InvalidTime,
}

pub trait EventHandleTrait <B: Basics>: StewardData + Ord + Hash + Borrow<ExtendedTime <B>> {
pub trait EventHandleTrait <B: Basics>: SimulationStateData + Clone + Ord + Hash + Borrow<ExtendedTime <B>> {
fn extended_time (&self)->& ExtendedTime <B>;
fn time (&self)->& B::Time {& self.extended_time().base}
fn id (&self)->& DeterministicRandomId {& self.extended_time().id}
fn downcast_ref <T: Any> (&self)->Option<&T>;
}
pub trait DataHandleTrait <T: StewardData + PersistentlyIdentifiedType>: StewardData + Hash + Deref<Target = T> {
pub trait DataHandleTrait <T: SimulationStateData + PersistentlyIdentifiedType>: SimulationStateData + Clone + Hash + Deref<Target = T> {
fn new(data: T)->Self;
}
pub trait DataTimelineCellTrait <T: DataTimeline>: StewardData + Hash {
pub trait DataTimelineCellTrait <T: DataTimeline>: SimulationStateData + Hash {
fn new(data: T)->Self;
}

Expand Down Expand Up @@ -139,7 +145,7 @@ pub enum ValidSince<BaseTime> {
macro_rules! time_steward_steward_specific_api {
() => {

pub trait Event: StewardData + PersistentlyIdentifiedType {
pub trait Event: SimulationStateData + PersistentlyIdentifiedType {
type Steward: TimeSteward;
type ExecutionData;
// audit all functions: calls invalidate_event for everything whose queries would be changed
Expand All @@ -162,7 +168,7 @@ pub trait Accessor {
fn extended_now(&self) -> & ExtendedTime <<Self::Steward as TimeSteward>::Basics>;
fn now(&self) -> & <<Self::Steward as TimeSteward>::Basics as Basics>::Time {&self.extended_now().base}
fn id(&self) -> DeterministicRandomId {self.extended_now().id}
fn query <Query: StewardData, T: DataTimelineQueriableWith<Query, Basics = <Self::Steward as TimeSteward>::Basics>> (&self, timeline: & DataTimelineCell<T>, query: &Query)-> T::QueryResult;
fn query <Q: Query, T: DataTimelineQueriableWith<Q, Basics = <Self::Steward as TimeSteward>::Basics>> (&self, timeline: & DataTimelineCell<T>, query: &Q)-> T::QueryResult;
}

pub trait EventAccessor: Accessor {
Expand Down
27 changes: 0 additions & 27 deletions src/rowless/api_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,32 +4,6 @@ use std::collections::BTreeSet;
use super::api::*;


macro_rules! StewardData_array_impls {
() => {};
($num: expr $(, $rest: expr)*) => {
impl<T: StewardData + Copy> StewardData for [T; $num] {}
StewardData_array_impls! ($($rest),*);
};
}
StewardData_array_impls! (0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32);
macro_rules! StewardData_primitive_impls {
() => {};
($prim: ty $(, $rest: ty)*) => {
impl StewardData for $prim {}
StewardData_primitive_impls! ($($rest),*);
};
}
StewardData_primitive_impls!((), u8, i8, u16, i16, u32, i32, u64, i64, usize, isize);

impl <T: StewardData> StewardData for Option <T> {}
impl <T: StewardData> StewardData for Vec<T> {}
impl <T: StewardData + Ord> StewardData for BTreeSet<T> {}



impl <T: Basics> StewardData for ExtendedTime <T> {}


impl<T> ListOfTypes for ListedType <T> {
fn visit_all <Visitor: ListOfTypesVisitor>(visitor: &mut Visitor) {
visitor.visit::<T>();
Expand All @@ -45,7 +19,6 @@ macro_rules! tuple_impls {
}
)+) => {
$(
impl<$($T:StewardData),+> StewardData for ($($T,)+) {}
impl<$($T:ListOfTypes),+> ListOfTypes for ($($T,)+) {
fn visit_all <Visitor: ListOfTypesVisitor>(visitor: &mut Visitor) {
$($T::visit_all(visitor);)*
Expand Down
4 changes: 0 additions & 4 deletions src/rowless/implementation_support/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -102,10 +102,6 @@ macro_rules! time_steward_common_impls_for_handles {
() => {
time_steward_common_impls_for_event_handle! ([B: Basics] [EventHandle <B>] [B]);
time_steward_common_impls_for_uniquely_identified_handle! ([B: Basics] [EventHandle <B>] self => (self.extended_time().id): DeterministicRandomId);

impl <T: StewardData + PersistentlyIdentifiedType> StewardData for DataHandle <T> {}
impl <B: Basics> StewardData for EventHandle <B> {}
impl <T: DataTimeline> StewardData for DataTimelineCell <T> {}
};
}

Expand Down
10 changes: 5 additions & 5 deletions src/rowless/serialization.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,13 +120,13 @@ macro_rules! time_steward_serialization_impls {
trait SerializeInto {
fn serialize_into(&self, writer: &mut Write)->$crate::bincode::Result <()>;
}
impl<T: StewardData + PersistentlyIdentifiedType> SerializeTargetInto for DataHandle <T> {
impl<T: SimulationStateData + PersistentlyIdentifiedType> SerializeTargetInto for DataHandle <T> {
fn serialize_target_into(&self, writer: &mut Write, object_id: u64)->$crate::bincode::Result <()> {
$crate::bincode::serialize_into (writer, & SerializationElement::DataHandleData (object_id, T::ID), $crate::bincode::Infinite)?;
$crate::bincode::serialize_into (writer, &*self.data, $crate::bincode::Infinite)
}
}
fn data_handle_initialize_function <T: StewardData + PersistentlyIdentifiedType>(reader: &mut Read, object_id: u64)->$crate::bincode::Result <()> {
fn data_handle_initialize_function <T: SimulationStateData + PersistentlyIdentifiedType>(reader: &mut Read, object_id: u64)->$crate::bincode::Result <()> {
with_deserialization_context (| context | {
context.uninitialized_handles.remove(&object_id);
let mut handle = context.find_handle::<_, DataHandle <T>> (object_id, || {
Expand Down Expand Up @@ -260,7 +260,7 @@ macro_rules! time_steward_serialization_impls {
}
}

impl <T: StewardData + PersistentlyIdentifiedType> $crate::serde::Serialize for DataHandle <T> {
impl <T: SimulationStateData + PersistentlyIdentifiedType> $crate::serde::Serialize for DataHandle <T> {
fn serialize <S: $crate::serde::Serializer> (&self, serializer: S)->Result <S::Ok, S::Error> {
bincode_error_to_generic(with_serialization_context (| context | {
let object_identifier = context.find_handle::<_, DataHandle <T>> (&*self.data as *const _ as usize, || {
Expand All @@ -270,7 +270,7 @@ macro_rules! time_steward_serialization_impls {
}))
}
}
impl <'a, T: StewardData + PersistentlyIdentifiedType> $crate::serde::Deserialize <'a> for DataHandle <T> {
impl <'a, T: SimulationStateData + PersistentlyIdentifiedType> $crate::serde::Deserialize <'a> for DataHandle <T> {
fn deserialize <D: $crate::serde::Deserializer<'a>> (deserializer: D)->Result <Self, D::Error> {
bincode_error_to_generic(with_deserialization_context (| context | {
let object_identifier = generic_error_to_bincode(u64::deserialize (deserializer))?;
Expand Down Expand Up @@ -357,7 +357,7 @@ macro_rules! time_steward_serialization_impls {
context.event_handle_initialize_functions.insert (T::ID, event_handle_initialize_function::<B, T>);
}
}
impl <T: StewardData + PersistentlyIdentifiedType> MaybeData for T {
impl <T: SimulationStateData + PersistentlyIdentifiedType> MaybeData for T {
fn visit (context: &mut DeserializationContext) {
context.data_handle_initialize_functions.insert (T::ID, data_handle_initialize_function::<T>);
}
Expand Down
Loading

0 comments on commit 4fe0780

Please sign in to comment.