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>
impl<T> EventSync<T>
Sourcepub fn is_paused(&self) -> bool
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());Sourcepub fn get_tickrate(&self) -> u32
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);Sourcepub fn wait_until(&self, tick_to_wait_for: u64) -> Result<(), TimeError>
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();Sourcepub fn wait_for_tick(&self) -> Result<(), TimeError>
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();Sourcepub fn wait_for_x_ticks(&self, ticks_to_wait: u32) -> Result<(), TimeError>
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);Sourcepub fn time_since_started(&self) -> Duration
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);Sourcepub fn ticks_since_started(&self) -> u64
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);Sourcepub fn time_since_last_tick(&self) -> Duration
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.Sourcepub fn time_until_next_tick(&self) -> Duration
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>
impl EventSync<Mutable>
Sourcepub fn new(tickrate_in_milliseconds: u32) -> Self
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();Sourcepub fn new_paused(tickrate_in_milliseconds: u32) -> Self
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());Sourcepub fn from_starting_time(
tickrate_in_milliseconds: u32,
elapsed_time: Duration,
start_paused: bool,
) -> Self
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);Sourcepub fn from_starting_tick(
tickrate_in_milliseconds: u32,
starting_tick: u32,
start_paused: bool,
) -> Self
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);Sourcepub fn clone_immutable(&self) -> EventSync<Immutable>
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.
Sourcepub fn restart(&mut self)
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.Sourcepub fn restart_paused(&mut self)
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());Sourcepub fn change_tickrate(&mut self, new_tickrate: u32)
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);Sourcepub fn unpause(&mut self) -> Result<(), TimeError>
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());Sourcepub fn pause(&mut self)
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());