generated from rust-vmm/crate-template
-
Notifications
You must be signed in to change notification settings - Fork 32
/
Copy pathbasic_event_manager.rs
111 lines (94 loc) · 3.27 KB
/
basic_event_manager.rs
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
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
// Copyright 2020 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0 OR BSD-3-Clause
//
// A basic, single threaded application that only needs one type of
// subscriber: `CounterSubscriber`.
//
// The application has an `EventManager` and can register multiple subscribers
// of type `CounterSubscriber`.
use std::ops::Drop;
use event_manager::utilities::subscribers::CounterSubscriber;
use event_manager::{EventManager, SubscriberId, SubscriberOps};
struct App {
event_manager: EventManager<CounterSubscriber>,
subscribers_id: Vec<SubscriberId>,
}
impl App {
fn new() -> Self {
Self {
event_manager: EventManager::<CounterSubscriber>::new().unwrap(),
subscribers_id: vec![],
}
}
fn add_subscriber(&mut self) {
let counter_subscriber = CounterSubscriber::default();
let id = self.event_manager.add_subscriber(counter_subscriber);
self.subscribers_id.push(id);
}
fn run(&mut self) {
let _ = self.event_manager.run_with_timeout(100);
}
fn inject_events_for(&mut self, subscriber_index: &[usize]) {
for i in subscriber_index {
let subscriber = self
.event_manager
.subscriber_mut(self.subscribers_id[*i])
.unwrap();
subscriber.trigger_event();
}
}
fn clear_events_for(&mut self, subscriber_indices: &[usize]) {
for i in subscriber_indices {
let subscriber = self
.event_manager
.subscriber_mut(self.subscribers_id[*i])
.unwrap();
subscriber.clear_event();
}
}
fn get_counters(&mut self) -> Vec<u64> {
let mut result = Vec::<u64>::new();
for subscriber_id in &self.subscribers_id {
let subscriber = self.event_manager.subscriber_mut(*subscriber_id).unwrap();
result.push(subscriber.counter());
}
result
}
// Whenever the App does not need to monitor events anymore, it should explicitly call
// the `remove_subscriber` function.
fn cleanup(&mut self) {
for id in &self.subscribers_id {
let _ = self.event_manager.remove_subscriber(*id);
}
}
}
impl Drop for App {
fn drop(&mut self) {
self.cleanup();
}
}
#[test]
fn test_single_threaded() {
let mut app = App::new();
for _ in 0..100 {
app.add_subscriber();
}
// Random subscribers, in the sense that I randomly picked those numbers :)
let triggered_subscribers: Vec<usize> = vec![1, 3, 50, 97];
app.inject_events_for(&triggered_subscribers);
app.run();
let counters = app.get_counters();
for (i, &item) in counters.iter().enumerate() {
assert_eq!(item, 1 & (triggered_subscribers.contains(&i) as u64));
}
app.clear_events_for(&triggered_subscribers);
app.run();
let counters = app.get_counters();
for (i, &item) in counters.iter().enumerate() {
assert_eq!(item, 1 & (triggered_subscribers.contains(&i) as u64));
}
// Once the app does not need events anymore, the cleanup needs to be called.
// This is particularly important when the app continues the execution, but event monitoring
// is not necessary.
app.cleanup();
}