EventSync

Struct EventSync 

Source
pub struct EventSync<Access = Mutable> { /* private fields */ }
Expand description

A way to synchronize a dynamic number of threads through sleeping. Achieved through cloning and passing around an instance of EventSync to other threads.

EventSync can be used if you want events between threads to happen at close to the same time. It can also be used if you want to regulate the time in which events occur.

§Usage

In order to use EventSync, you start by creating one with EventSync::new(). You then pass in the desired tickrate for the EventSync to know how long 1 tick should last.

The tickrate will be an integer reflected as milliseconds, and cannot go below 1. If you pass in 0, 1 millisecond will be set as the tickrate.

use event_sync::*;

let tickrate = 10; // 10ms between every tick

// Create an EventSync with a 10ms tickrate.
let event_sync = EventSync::new(tickrate);

You can then use this EventSync for both time tracking and synchronizing threads.

§Time Tracking

use event_sync::*;
use std::time::Instant;

let tickrate = 10; // 10ms between every tick
let event_sync = EventSync::new(tickrate as u32);

let start = Instant::now();

// Wait for 5 ticks (5 * 10)ms.
event_sync.wait_for_x_ticks(5);

let finish = start.elapsed().as_millis();

// Check that the time it took for the operation was (waited_ticks * tickrate)ms
assert_eq!(finish, event_sync.time_since_started().as_millis());

§Thread Synchronization

use event_sync::*;
use std::thread;

let tickrate = 10; // 10ms between every tick
let event_sync = EventSync::new(tickrate);

// All cloned EventSyncs will share their data.
let passed_event_sync = event_sync.clone();

let handle = thread::spawn(move || {
  // waiting until 5 ticks have occurred since the creation of event_sync.
  passed_event_sync.wait_until(5);

  // do something
});

// waiting until 5 ticks have occurred since the creation of event_sync.
event_sync.wait_until(5);

// do something

handle.join().unwrap();

§Permissions

Of course, you don’t want just anyone to be able to change whatever they want on an EventSync. To prevent that, event_sync provides two states for an EventSync to be in. Those being Mutable, and Immutable.

By calling event_sync.clone_immutable(), you create a copy of the EventSync that cannot call any methods requiring &mut self.

§Example

use event_sync::*;

let tickrate = 10;
let event_sync = EventSync::new(tickrate);

let immutable_event_sync = event_sync.clone_immutable(); // Create an immutable EventSync.

assert_eq!(immutable_event_sync.get_tickrate(), tickrate);

The type for this Immutable EventSync would look like this:

use event_sync::{EventSync, Immutable};

struct TimeKeeper {
  event_sync: EventSync<Immutable>,
}

Implementations§

Source§

impl<T> EventSync<T>

Source

pub fn is_paused(&self) -> bool

Returns true if this instance of EventSyunc has been paused.

Call event_sync.unpause() to unpause the eventsync. The time that’s passed before pausing is retained.

§Examples
use event_sync::EventSync;

let tickrate = 10; // 10ms between every tick
let mut event_sync = EventSync::new(tickrate);

event_sync.pause();

assert!(event_sync.is_paused());
Source

pub fn get_tickrate(&self) -> u32

Returns the internal tickrate.

§Examples
use event_sync::*;

let tickrate = 10; // 10ms tickrate.
let event_sync = EventSync::new(tickrate);
let other_event_sync = event_sync.clone();

assert_eq!(event_sync.get_tickrate(), tickrate);
assert_eq!(other_event_sync.get_tickrate(), tickrate);
Source

pub fn wait_until(&self, tick_to_wait_for: u64) -> Result<(), TimeError>

Waits until an absolute tick has occurred since EventSync creation.

That means, if you created an instance of EventSync with a tickrate of 10ms, and you want to wait until 1 second has passed since creation. You would wait until the 100th tick, as 100 ticks would be 1 second since EventSync Creation.

§Errors
  • An error is returned when the given time to wait for has already occurred.
  • An error is returned if the EventSync is paused.
§Usage
use event_sync::EventSync;

let tickrate = 10; // 10ms between every tick
let event_sync = EventSync::new(tickrate);

// Wait 1 second from the creation of event_sync.
event_sync.wait_until(100).unwrap();
Source

pub fn wait_for_tick(&self) -> Result<(), TimeError>

Waits until the next tick relative to where now is between ticks.

Let’s say the tickrate is 10ms, and the last tick was 5ms ago. This method would sleep for 5ms to get to the next tick.

§Errors
  • An error is returned if the EventSync is paused.
§Usage
use event_sync::EventSync;

let tickrate = 10; // 10ms between every tick
let event_sync = EventSync::new(tickrate);

// wait until the next tick
event_sync.wait_for_tick();
Source

pub fn wait_for_x_ticks(&self, ticks_to_wait: u32) -> Result<(), TimeError>

Waits for the passed in amount of ticks relative to where now is between ticks.

Let’s say the tickrate is 10ms, and the last tick was 5ms ago. If you wanted to wait for 3 ticks, this method would sleep for 25ms, as that would be 3 ticks from now.

§Errors
  • An error is returned if the EventSync is paused.
§Usage
use event_sync::EventSync;

let tickrate = 10; // 10ms between every tick
let event_sync = EventSync::new(tickrate);

// wait for 3 ticks
event_sync.wait_for_x_ticks(3);
Source

pub fn time_since_started(&self) -> Duration

Returns the amount of time that has occurred since the creation of this instance of EventSync.

§Usage
use event_sync::*;
use std::time::Duration;

let tickrate = 10; // 10ms between every tick
let event_sync = EventSync::new(tickrate);

// Wait until 5 ticks have occurred since EventSync creation.
event_sync.wait_until(5);

let milliseconds_since_started = event_sync.time_since_started().as_millis();

assert_eq!(milliseconds_since_started, 50);
Source

pub fn ticks_since_started(&self) -> u64

Returns the amount of ticks that have occurred since the creation of this instance of EventSync.

§Usage
use event_sync::*;

let tickrate = 10; // 10ms between every tick
let event_sync = EventSync::new(tickrate);

event_sync.wait_until(5);

assert_eq!(event_sync.ticks_since_started(), 5);
Source

pub fn time_since_last_tick(&self) -> Duration

Returns the amount of time that has passed since the last tick

§Examples
use event_sync::EventSync;

let tickrate = 10; // 10ms between every tick.
let event_sync = EventSync::new(tickrate);

event_sync.wait_for_tick().unwrap();

assert!(event_sync.time_since_last_tick().as_micros() < 500); // Practically no time should have passed since the last tick.
Source

pub fn time_until_next_tick(&self) -> Duration

Returns the amount of time until the next tick will occur.

§Examples
use event_sync::EventSync;

let tickrate = 10; // 10ms between every tick.
let event_sync = EventSync::new(tickrate);

event_sync.wait_for_tick().unwrap();

assert!(event_sync.time_until_next_tick().as_micros() > 500); // Practically no time should have passed since the last tick.
Source§

impl EventSync<Mutable>

Source

pub fn new(tickrate_in_milliseconds: u32) -> Self

Creates a new instance of EventSync.

Takes the duration of a tick as milliseconds. If 0 is passed in, 1 will be the assigned tickrate for this instance of EventSync.

§Examples
use event_sync::*;

let tickrate = 10; // 10ms between every tick

// Create an EventSync with a 10ms tickrate.
let event_sync = EventSync::new(tickrate);

You can then use this EventSync for both time tracking and synchronizing threads.

§Time Tracking
use event_sync::*;
use std::time::Instant;

let tickrate = 10; // 10ms between every tick
let event_sync = EventSync::new(tickrate as u32);

let start = Instant::now();

// Wait for 5 ticks (5 * 10)ms.
event_sync.wait_for_x_ticks(5);

let finish = start.elapsed().as_millis();

// Check that the time it took for the operation was (waited_ticks * tickrate)ms
assert_eq!(finish, event_sync.time_since_started().as_millis());
§Thread Synchronization
use event_sync::*;
use std::thread;

let tickrate = 10; // 10ms between every tick
let event_sync = EventSync::new(tickrate);

// All cloned EventSyncs will share their data.
let passed_event_sync = event_sync.clone();

let handle = thread::spawn(move || {
  // waiting until 5 ticks have occurred since the creation of event_sync.
  passed_event_sync.wait_until(5);

  // do something
});

// waiting until 5 ticks have occurred since the creation of event_sync.
event_sync.wait_until(5);

// do something

handle.join().unwrap();
Source

pub fn new_paused(tickrate_in_milliseconds: u32) -> Self

Creates a new instance of EventSync that starts out paused.

§Examples
use event_sync::*;

let tickrate = 10; // 10ms between every tick.
let event_sync = EventSync::new_paused(tickrate); // Create an event_sync that starts out paused.

assert!(event_sync.is_paused());
assert!(event_sync.wait_for_tick().is_err());
Source

pub fn from_starting_time( tickrate_in_milliseconds: u32, elapsed_time: Duration, start_paused: bool, ) -> Self

Creates a new instance of EventSync with the given starting time.

Takes an extra arguement to determine if the EventSync should be paused upon creation or not.

§Example
use event_sync::*;
use std::time::Duration;

let tickrate = 10; // 10ms between every tick.
let starting_time = Duration::from_millis(30); // Start 30ms ahead.
let event_sync = EventSync::from_starting_time(tickrate, starting_time, false);

assert_eq!(event_sync.ticks_since_started(), 3);
§Starting Paused
use event_sync::*;
use std::time::Duration;

let tickrate = 10; // 10ms between every tick.
let starting_time = Duration::from_millis(30); // Start 30ms ahead.
let mut event_sync = EventSync::from_starting_time(tickrate, starting_time, true);

assert!(event_sync.is_paused());
event_sync.unpause().unwrap();

assert_eq!(event_sync.ticks_since_started(), 3);
Source

pub fn from_starting_tick( tickrate_in_milliseconds: u32, starting_tick: u32, start_paused: bool, ) -> Self

Creates a new instance of EventSync with the given starting tick.

Takes an extra arguement to determine if the EventSync should be paused upon creation or not.

§Example
use event_sync::*;
use std::time::Duration;

let tickrate = 10; // 10ms between every tick.
let starting_tick = 3; // Start 3 ticks ahead.
let event_sync = EventSync::from_starting_tick(tickrate, starting_tick, false);

assert_eq!(event_sync.ticks_since_started(), 3);
§Starting Paused
use event_sync::*;
use std::time::Duration;

let tickrate = 10; // 10ms between every tick.
let starting_tick = 3; // Start 3 ticks ahead.
let mut event_sync = EventSync::from_starting_tick(tickrate, starting_tick, true);

assert!(event_sync.is_paused());
event_sync.unpause().unwrap();

assert_eq!(event_sync.ticks_since_started(), 3);
Source

pub fn clone_immutable(&self) -> EventSync<Immutable>

This creates an Immutable instance of EventSync.

This version of EventSync cannot change any of the underlying data, only being able to use/read the data. Methods such a waiting for a certain tick are fine, however pausing, unpausing, changing tickrate, etc. are not possible through an Immutable EventSync.

Additionally, Immutable EventSync can only create other Immutable instances of itself.

Source

pub fn restart(&mut self)

Restarts the starting time. This will also restart the time for every EventSync cloned off of this one.

Unpauses if paused, resetting the time.

§Examples
use event_sync::EventSync;

let tickrate = 10; // 10ms between every tick
let mut event_sync = EventSync::new(tickrate);

event_sync.wait_for_tick().unwrap(); // Add some time.

event_sync.restart(); // Restart the EventSync.

assert_eq!(event_sync.ticks_since_started(), 0); // 0 ticks is returned because the EventSync was restarted.
Source

pub fn restart_paused(&mut self)

Restarts the startimg time, and changes self to paused. This will also restart and pause the time for every EventSync cloned off of this one.

§Examples
use event_sync::EventSync;

let tickrate = 10; // 10ms between every tick
let mut event_sync = EventSync::new(tickrate);

event_sync.wait_for_tick().unwrap(); // Add some time.

event_sync.restart_paused(); // Restart the EventSync.

assert!(event_sync.is_paused());
Source

pub fn change_tickrate(&mut self, new_tickrate: u32)

Changes how long a tick lasts internally. Retains the time that passed before method call. That means if 100ms have passed, 100ms will still have passed. The amount of ticks will be the only thing that’s changed.

Changes the tickrate for all connected EventSyncs.

§Examples
use event_sync::*;

let tickrate = 10; // 10ms tickrate.
let mut event_sync = EventSync::new(tickrate);

// Wait for 100ms (10 ticks).
event_sync.wait_for_x_ticks(10).unwrap();

// Change the tickrate to 100ms, 10x what it was before.
event_sync.change_tickrate(tickrate * 10);

// Ensure that 1 tick has passed, which is now 100ms.
assert_eq!(event_sync.ticks_since_started(), 1);
// Ensure that the tickrate is now 100ms instead of the prior 10ms.
assert_eq!(event_sync.get_tickrate(), 100);
§EventSyncs are connected
use event_sync::*;

let tickrate = 10; // 10ms tickrate.
let event_sync = EventSync::new(tickrate);
let mut other_event_sync = event_sync.clone();

// Change the tickrate. This will change it for both EventSyncs.
other_event_sync.change_tickrate(tickrate * 2);

// Ensure the original EventSync's tickrate is also changed.
assert_eq!(event_sync.get_tickrate(), tickrate * 2);
Source

pub fn unpause(&mut self) -> Result<(), TimeError>

Unpauses this instance of EventSync if it’s been paused. Any EventSync that was cloned off this one is also unpaused, as they are all connected.

If the time passed before pausing was 10.1 seconds, that time will be retained when unpaused.

Calling unpause when the EventSync is already running does nothing.

§Examples
use event_sync::EventSync;

let tickrate = 10; // 10ms between every tick
let mut event_sync = EventSync::new(tickrate);
let other_event_sync = EventSync::new(tickrate); // Create a second one to desync.

event_sync.wait_for_tick().unwrap(); // Add some time.
event_sync.pause();

other_event_sync.wait_for_tick().unwrap(); // Desync from the paused EventSync.

event_sync.unpause().unwrap();
assert_eq!(event_sync.ticks_since_started(), 1); // Only 1 tick has passed while this EventSync wasn't paused.
§EventSyncs are connected
use event_sync::EventSync;

let tickrate = 10; // 10ms between every tick
let mut event_sync = EventSync::new_paused(tickrate);
let other_event_sync = event_sync.clone();

assert!(other_event_sync.is_paused());

event_sync.unpause().unwrap();

assert!(!other_event_sync.is_paused());
Source

pub fn pause(&mut self)

Pauses this instance of EventSync. Any EventSync that was cloned off this one is also paused, as they are all connected.

When paused, the time that passed is retained. If 10.1 seconds have passed, that time will be retained after paused.

Calling pause when already paused does nothing.

§Examples
use event_sync::EventSync;

let tickrate = 10; // 10ms between every tick
let mut event_sync = EventSync::new(tickrate);
let other_event_sync = EventSync::new(tickrate); // Create a second one to desync.

event_sync.wait_for_tick().unwrap(); // Add some time.
event_sync.pause();

other_event_sync.wait_for_tick().unwrap(); // Desync from the paused EventSync.

event_sync.unpause().unwrap();
assert_eq!(event_sync.ticks_since_started(), 1); // Only 1 tick has passed while this EventSync wasn't paused.
§EventSyncs are connected
use event_sync::EventSync;

let tickrate = 10; // 10ms between every tick
let mut event_sync = EventSync::new(tickrate);
let other_event_sync = event_sync.clone();

event_sync.pause();

assert!(other_event_sync.is_paused());

Trait Implementations§

Source§

impl<Access: Clone> Clone for EventSync<Access>

Source§

fn clone(&self) -> EventSync<Access>

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<T> Debug for EventSync<T>

Source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl Default for EventSync

Source§

fn default() -> Self

Returns the “default value” for a type. Read more
Source§

impl<'de, Access> Deserialize<'de> for EventSync<Access>

Source§

fn deserialize<__D>(__deserializer: __D) -> Result<Self, __D::Error>
where __D: Deserializer<'de>,

Deserialize this value from the given Serde deserializer. Read more
Source§

impl<T> Display for EventSync<T>

Source§

fn fmt(&self, formatter: &mut Formatter<'_>) -> Result<(), Error>

Formats the value using the given formatter. Read more
Source§

impl<T> PartialEq for EventSync<T>

Source§

fn eq(&self, other: &Self) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<Access> Serialize for EventSync<Access>

Source§

fn serialize<__S>(&self, __serializer: __S) -> Result<__S::Ok, __S::Error>
where __S: Serializer,

Serialize this value into the given Serde serializer. Read more
Source§

impl<T> Eq for EventSync<T>

Auto Trait Implementations§

§

impl<Access> Freeze for EventSync<Access>

§

impl<Access> RefUnwindSafe for EventSync<Access>
where Access: RefUnwindSafe,

§

impl<Access> Send for EventSync<Access>
where Access: Send,

§

impl<Access> Sync for EventSync<Access>
where Access: Sync,

§

impl<Access> Unpin for EventSync<Access>
where Access: Unpin,

§

impl<Access> UnwindSafe for EventSync<Access>
where Access: UnwindSafe,

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
Source§

impl<T> ToString for T
where T: Display + ?Sized,

Source§

fn to_string(&self) -> String

Converts the given value to a String. Read more
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
Source§

impl<T> DeserializeOwned for T
where T: for<'de> Deserialize<'de>,