base: Lock the event emitter option.

master
Damir Jelić 2020-05-06 14:47:58 +02:00
parent 3a30d53437
commit 3d03f77dba
2 changed files with 98 additions and 163 deletions

View File

@ -312,7 +312,11 @@ impl AsyncClient {
/// ///
/// The methods of `EventEmitter` are called when the respective `RoomEvents` occur. /// The methods of `EventEmitter` are called when the respective `RoomEvents` occur.
pub async fn add_event_emitter(&mut self, emitter: Box<dyn EventEmitter>) { pub async fn add_event_emitter(&mut self, emitter: Box<dyn EventEmitter>) {
self.base_client.write().await.event_emitter = Some(emitter); self.base_client
.read()
.await
.add_event_emitter(emitter)
.await;
} }
/// Returns an `Option` of the room name from a `RoomId`. /// Returns an `Option` of the room name from a `RoomId`.

View File

@ -77,7 +77,7 @@ pub struct Client {
pub push_ruleset: Arc<RwLock<Option<Ruleset>>>, pub push_ruleset: Arc<RwLock<Option<Ruleset>>>,
/// Any implementor of EventEmitter will act as the callbacks for various /// Any implementor of EventEmitter will act as the callbacks for various
/// events. /// events.
pub event_emitter: Option<Box<dyn EventEmitter>>, pub event_emitter: Arc<RwLock<Option<Box<dyn EventEmitter>>>>,
/// Any implementor of `StateStore` will be called to save `Room` and /// Any implementor of `StateStore` will be called to save `Room` and
/// some `BaseClient` state during `AsyncClient::sync` calls. /// some `BaseClient` state during `AsyncClient::sync` calls.
/// ///
@ -123,7 +123,7 @@ impl Client {
joined_rooms: Arc::new(RwLock::new(HashMap::new())), joined_rooms: Arc::new(RwLock::new(HashMap::new())),
ignored_users: Arc::new(RwLock::new(Vec::new())), ignored_users: Arc::new(RwLock::new(Vec::new())),
push_ruleset: Arc::new(RwLock::new(None)), push_ruleset: Arc::new(RwLock::new(None)),
event_emitter: None, event_emitter: Arc::new(RwLock::new(None)),
state_store: None, state_store: None,
needs_state_store_sync: Arc::new(AtomicBool::from(true)), needs_state_store_sync: Arc::new(AtomicBool::from(true)),
#[cfg(feature = "encryption")] #[cfg(feature = "encryption")]
@ -141,8 +141,8 @@ impl Client {
/// Add `EventEmitter` to `Client`. /// Add `EventEmitter` to `Client`.
/// ///
/// The methods of `EventEmitter` are called when the respective `RoomEvents` occur. /// The methods of `EventEmitter` are called when the respective `RoomEvents` occur.
pub async fn add_event_emitter(&mut self, emitter: Box<dyn EventEmitter>) { pub async fn add_event_emitter(&self, emitter: Box<dyn EventEmitter>) {
self.event_emitter = Some(emitter); *self.event_emitter.write().await = Some(emitter);
} }
/// Returns true if the state store has been loaded into the client. /// Returns true if the state store has been loaded into the client.
@ -725,220 +725,151 @@ impl Client {
} }
pub(crate) async fn emit_timeline_event(&self, room_id: &RoomId, event: &RoomEvent) { pub(crate) async fn emit_timeline_event(&self, room_id: &RoomId, event: &RoomEvent) {
let lock = self.event_emitter.read().await;
let event_emitter = if let Some(ee) = lock.as_ref() {
ee
} else {
return;
};
let room = if let Some(room) = self.get_room(&room_id).await {
Arc::clone(&room)
} else {
return;
};
match event { match event {
RoomEvent::RoomMember(mem) => { RoomEvent::RoomMember(mem) => event_emitter.on_room_member(room, &mem).await,
if let Some(ee) = &self.event_emitter { RoomEvent::RoomName(name) => event_emitter.on_room_name(room, &name).await,
if let Some(room) = self.get_room(&room_id).await {
ee.on_room_member(Arc::clone(&room), &mem).await;
}
}
}
RoomEvent::RoomName(name) => {
if let Some(ee) = &self.event_emitter {
if let Some(room) = self.get_room(&room_id).await {
ee.on_room_name(Arc::clone(&room), &name).await;
}
}
}
RoomEvent::RoomCanonicalAlias(canonical) => { RoomEvent::RoomCanonicalAlias(canonical) => {
if let Some(ee) = &self.event_emitter { event_emitter
if let Some(room) = self.get_room(&room_id).await { .on_room_canonical_alias(room, &canonical)
ee.on_room_canonical_alias(Arc::clone(&room), &canonical) .await
.await;
}
}
}
RoomEvent::RoomAliases(aliases) => {
if let Some(ee) = &self.event_emitter {
if let Some(room) = self.get_room(&room_id).await {
ee.on_room_aliases(Arc::clone(&room), &aliases).await;
}
}
}
RoomEvent::RoomAvatar(avatar) => {
if let Some(ee) = &self.event_emitter {
if let Some(room) = self.get_room(&room_id).await {
ee.on_room_avatar(Arc::clone(&room), &avatar).await;
}
}
}
RoomEvent::RoomMessage(msg) => {
if let Some(ee) = &self.event_emitter {
if let Some(room) = self.get_room(&room_id).await {
ee.on_room_message(Arc::clone(&room), &msg).await;
}
}
} }
RoomEvent::RoomAliases(aliases) => event_emitter.on_room_aliases(room, &aliases).await,
RoomEvent::RoomAvatar(avatar) => event_emitter.on_room_avatar(room, &avatar).await,
RoomEvent::RoomMessage(msg) => event_emitter.on_room_message(room, &msg).await,
RoomEvent::RoomMessageFeedback(msg_feedback) => { RoomEvent::RoomMessageFeedback(msg_feedback) => {
if let Some(ee) = &self.event_emitter { event_emitter
if let Some(room) = self.get_room(&room_id).await { .on_room_message_feedback(room, &msg_feedback)
ee.on_room_message_feedback(Arc::clone(&room), &msg_feedback) .await
.await;
}
}
} }
RoomEvent::RoomRedaction(redaction) => { RoomEvent::RoomRedaction(redaction) => {
if let Some(ee) = &self.event_emitter { event_emitter.on_room_redaction(room, &redaction).await
if let Some(room) = self.get_room(&room_id).await {
ee.on_room_redaction(Arc::clone(&room), &redaction).await;
}
}
} }
RoomEvent::RoomPowerLevels(power) => { RoomEvent::RoomPowerLevels(power) => {
if let Some(ee) = &self.event_emitter { event_emitter.on_room_power_levels(room, &power).await
if let Some(room) = self.get_room(&room_id).await {
ee.on_room_power_levels(Arc::clone(&room), &power).await;
}
}
}
RoomEvent::RoomTombstone(tomb) => {
if let Some(ee) = &self.event_emitter {
if let Some(room) = self.get_room(&room_id).await {
ee.on_room_tombstone(Arc::clone(&room), &tomb).await;
}
}
} }
RoomEvent::RoomTombstone(tomb) => event_emitter.on_room_tombstone(room, &tomb).await,
_ => {} _ => {}
} }
} }
pub(crate) async fn emit_state_event(&self, room_id: &RoomId, event: &StateEvent) { pub(crate) async fn emit_state_event(&self, room_id: &RoomId, event: &StateEvent) {
let lock = self.event_emitter.read().await;
let event_emitter = if let Some(ee) = lock.as_ref() {
ee
} else {
return;
};
let room = if let Some(room) = self.get_room(&room_id).await {
Arc::clone(&room)
} else {
return;
};
match event { match event {
StateEvent::RoomMember(member) => { StateEvent::RoomMember(member) => event_emitter.on_state_member(room, &member).await,
if let Some(ee) = &self.event_emitter { StateEvent::RoomName(name) => event_emitter.on_state_name(room, &name).await,
if let Some(room) = self.get_room(&room_id).await {
ee.on_state_member(Arc::clone(&room), &member).await;
}
}
}
StateEvent::RoomName(name) => {
if let Some(ee) = &self.event_emitter {
if let Some(room) = self.get_room(&room_id).await {
ee.on_state_name(Arc::clone(&room), &name).await;
}
}
}
StateEvent::RoomCanonicalAlias(canonical) => { StateEvent::RoomCanonicalAlias(canonical) => {
if let Some(ee) = &self.event_emitter { event_emitter
if let Some(room) = self.get_room(&room_id).await { .on_state_canonical_alias(room, &canonical)
ee.on_state_canonical_alias(Arc::clone(&room), &canonical) .await
.await;
}
}
} }
StateEvent::RoomAliases(aliases) => { StateEvent::RoomAliases(aliases) => {
if let Some(ee) = &self.event_emitter { event_emitter.on_state_aliases(room, &aliases).await
if let Some(room) = self.get_room(&room_id).await {
ee.on_state_aliases(Arc::clone(&room), &aliases).await;
}
}
}
StateEvent::RoomAvatar(avatar) => {
if let Some(ee) = &self.event_emitter {
if let Some(room) = self.get_room(&room_id).await {
ee.on_state_avatar(Arc::clone(&room), &avatar).await;
}
}
} }
StateEvent::RoomAvatar(avatar) => event_emitter.on_state_avatar(room, &avatar).await,
StateEvent::RoomPowerLevels(power) => { StateEvent::RoomPowerLevels(power) => {
if let Some(ee) = &self.event_emitter { event_emitter.on_state_power_levels(room, &power).await
if let Some(room) = self.get_room(&room_id).await {
ee.on_state_power_levels(Arc::clone(&room), &power).await;
}
}
} }
StateEvent::RoomJoinRules(rules) => { StateEvent::RoomJoinRules(rules) => {
if let Some(ee) = &self.event_emitter { event_emitter.on_state_join_rules(room, &rules).await
if let Some(room) = self.get_room(&room_id).await {
ee.on_state_join_rules(Arc::clone(&room), &rules).await;
}
}
}
StateEvent::RoomTombstone(tomb) => {
if let Some(ee) = &self.event_emitter {
if let Some(room) = self.get_room(&room_id).await {
ee.on_room_tombstone(Arc::clone(&room), &tomb).await;
}
}
} }
StateEvent::RoomTombstone(tomb) => event_emitter.on_room_tombstone(room, &tomb).await,
_ => {} _ => {}
} }
} }
pub(crate) async fn emit_account_data_event(&self, room_id: &RoomId, event: &NonRoomEvent) { pub(crate) async fn emit_account_data_event(&self, room_id: &RoomId, event: &NonRoomEvent) {
let lock = self.event_emitter.read().await;
let event_emitter = if let Some(ee) = lock.as_ref() {
ee
} else {
return;
};
let room = if let Some(room) = self.get_room(&room_id).await {
Arc::clone(&room)
} else {
return;
};
match event { match event {
NonRoomEvent::Presence(presence) => { NonRoomEvent::Presence(presence) => {
if let Some(ee) = &self.event_emitter { event_emitter.on_account_presence(room, &presence).await
if let Some(room) = self.get_room(&room_id).await {
ee.on_account_presence(Arc::clone(&room), &presence).await;
}
}
} }
NonRoomEvent::IgnoredUserList(ignored) => { NonRoomEvent::IgnoredUserList(ignored) => {
if let Some(ee) = &self.event_emitter { event_emitter.on_account_ignored_users(room, &ignored).await
if let Some(room) = self.get_room(&room_id).await {
ee.on_account_ignored_users(Arc::clone(&room), &ignored)
.await;
}
}
} }
NonRoomEvent::PushRules(rules) => { NonRoomEvent::PushRules(rules) => {
if let Some(ee) = &self.event_emitter { event_emitter.on_account_push_rules(room, &rules).await
if let Some(room) = self.get_room(&room_id).await {
ee.on_account_push_rules(Arc::clone(&room), &rules).await;
}
}
} }
NonRoomEvent::FullyRead(full_read) => { NonRoomEvent::FullyRead(full_read) => {
if let Some(ee) = &self.event_emitter { event_emitter
if let Some(room) = self.get_room(&room_id).await { .on_account_data_fully_read(room, &full_read)
ee.on_account_data_fully_read(Arc::clone(&room), &full_read) .await
.await;
}
}
} }
_ => {} _ => {}
} }
} }
pub(crate) async fn emit_ephemeral_event(&self, room_id: &RoomId, event: &NonRoomEvent) { pub(crate) async fn emit_ephemeral_event(&self, room_id: &RoomId, event: &NonRoomEvent) {
let lock = self.event_emitter.read().await;
let event_emitter = if let Some(ee) = lock.as_ref() {
ee
} else {
return;
};
let room = if let Some(room) = self.get_room(&room_id).await {
Arc::clone(&room)
} else {
return;
};
match event { match event {
NonRoomEvent::Presence(presence) => { NonRoomEvent::Presence(presence) => {
if let Some(ee) = &self.event_emitter { event_emitter.on_account_presence(room, &presence).await
if let Some(room) = self.get_room(&room_id).await {
ee.on_account_presence(Arc::clone(&room), &presence).await;
}
}
} }
NonRoomEvent::IgnoredUserList(ignored) => { NonRoomEvent::IgnoredUserList(ignored) => {
if let Some(ee) = &self.event_emitter { event_emitter.on_account_ignored_users(room, &ignored).await
if let Some(room) = self.get_room(&room_id).await {
ee.on_account_ignored_users(Arc::clone(&room), &ignored)
.await;
}
}
} }
NonRoomEvent::PushRules(rules) => { NonRoomEvent::PushRules(rules) => {
if let Some(ee) = &self.event_emitter { event_emitter.on_account_push_rules(room, &rules).await
if let Some(room) = self.get_room(&room_id).await {
ee.on_account_push_rules(Arc::clone(&room), &rules).await;
}
}
} }
NonRoomEvent::FullyRead(full_read) => { NonRoomEvent::FullyRead(full_read) => {
if let Some(ee) = &self.event_emitter { event_emitter
if let Some(room) = self.get_room(&room_id).await { .on_account_data_fully_read(room, &full_read)
ee.on_account_data_fully_read(Arc::clone(&room), &full_read) .await
.await;
}
}
} }
_ => {} _ => {}
} }
} }
pub(crate) async fn emit_presence_event(&self, room_id: &RoomId, event: &PresenceEvent) { pub(crate) async fn emit_presence_event(&self, room_id: &RoomId, event: &PresenceEvent) {
if let Some(ee) = &self.event_emitter { if let Some(ee) = &self.event_emitter.read().await.as_ref() {
if let Some(room) = self.get_room(&room_id).await { if let Some(room) = self.get_room(&room_id).await {
ee.on_presence_event(Arc::clone(&room), &event).await; ee.on_presence_event(Arc::clone(&room), &event).await;
} }