Skip to content

Rc to arc #34

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Sep 15, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 16 additions & 21 deletions crates/riddle-audio/src/audio_system.rs
Original file line number Diff line number Diff line change
@@ -1,28 +1,29 @@
use crate::*;

use riddle_common::clone_handle::CloneHandle;
use rodio::{Device, Sink};
use std::{
cell::RefCell,
collections::HashMap,
rc::{Rc, Weak},
sync::Arc,
sync::Mutex,
time::{Duration, Instant},
};

pub struct AudioSystem {
weak_self: Weak<AudioSystem>,
weak_self: AudioSystemWeak,
pub(super) device: Device,

fades: RefCell<std::collections::HashMap<FadeKey, Fade>>,
fades: Mutex<HashMap<FadeKey, Fade>>,
}

define_handles!(<AudioSystem>::weak_self, pub AudioSystemHandle, pub AudioSystemWeak);

impl AudioSystem {
pub fn new() -> Result<Rc<AudioSystem>, AudioError> {
pub fn new() -> Result<AudioSystemHandle, AudioError> {
let device = rodio::default_output_device().ok_or(AudioError::UnknownError)?;
Ok(Rc::new_cyclic(|weak_self| AudioSystem {
weak_self: weak_self.clone(),
Ok(AudioSystemHandle::new(|weak_self| AudioSystem {
weak_self,
device,
fades: RefCell::new(HashMap::new()),
fades: Mutex::new(HashMap::new()),
}))
}

Expand All @@ -32,7 +33,7 @@ impl AudioSystem {
}

pub(crate) fn register_fade(&self, fade: Fade) {
let mut fades = self.fades.borrow_mut();
let mut fades = self.fades.lock().unwrap();
let existing = fades.remove(&fade.key());
match existing {
Some(old) => fades.insert(fade.key(), Fade::merge_pair(old, fade)),
Expand All @@ -41,13 +42,13 @@ impl AudioSystem {
}

pub fn tick_fades(&self, now: Instant) {
let mut fades = self.fades.borrow_mut();
let mut fades = self.fades.lock().unwrap();
fades.retain(|_, f| f.update(now));
}
}

struct FadeKey {
sink: Rc<Sink>,
sink: Arc<Sink>,
}

impl std::hash::Hash for FadeKey {
Expand All @@ -58,7 +59,7 @@ impl std::hash::Hash for FadeKey {

impl std::cmp::PartialEq for FadeKey {
fn eq(&self, other: &Self) -> bool {
Rc::ptr_eq(&self.sink, &other.sink)
Arc::ptr_eq(&self.sink, &other.sink)
}
}

Expand All @@ -71,7 +72,7 @@ pub(crate) enum FadeType {
}

pub(crate) struct Fade {
sink: Rc<Sink>,
sink: Arc<Sink>,
start_volume: f32,
dest_volume: f32,
start_time: Instant,
Expand All @@ -81,7 +82,7 @@ pub(crate) struct Fade {

impl Fade {
pub(crate) fn new(
sink: Rc<Sink>,
sink: Arc<Sink>,
dest_volume: f32,
duration: Duration,
fade_type: FadeType,
Expand Down Expand Up @@ -132,9 +133,3 @@ impl Fade {
}
}
}

impl CloneHandle for AudioSystem {
fn clone_weak_handle(&self) -> Weak<Self> {
self.weak_self.clone()
}
}
9 changes: 4 additions & 5 deletions crates/riddle-audio/src/clip_player.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
use crate::*;

use riddle_common::clone_handle::CloneHandle;
use rodio::{decoder::Decoder, source::Source, Sink};
use std::{io::Cursor, rc::Rc, time::Duration};
use std::{io::Cursor, sync::Arc, time::Duration};

const QUICK_FADE_DURATION_SECONDS: f32 = 0.2;

pub struct ClipPlayer {
audio: Rc<AudioSystem>,
audio: AudioSystemHandle,
clip: Clip,
sink: Option<Rc<Sink>>,
sink: Option<Arc<Sink>>,

volume: f32,
}
Expand All @@ -25,7 +24,7 @@ impl ClipPlayer {
}

fn play(&mut self, mode: PlayMode) -> Result<(), AudioError> {
let sink: Rc<Sink> = Sink::new(&self.audio.device).into();
let sink: Arc<Sink> = Sink::new(&self.audio.device).into();
sink.set_volume(self.volume);
let source = Decoder::new(Cursor::new(self.clip.data.clone()))
.map_err(|_| AudioError::UnknownError)?;
Expand Down
2 changes: 2 additions & 0 deletions crates/riddle-audio/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ mod clip;
mod clip_player;
mod error;

use riddle_common::*;

pub use audio_system::*;
pub use clip::*;
pub use clip_player::*;
Expand Down
81 changes: 74 additions & 7 deletions crates/riddle-common/src/clone_handle.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,77 @@
use std::rc::{Rc, Weak};

pub trait CloneHandle {
#[inline]
fn clone_handle(&self) -> Option<Rc<Self>> {
std::rc::Weak::upgrade(&self.clone_weak_handle())
}
type Handle;
type WeakHandle;

fn clone_handle(&self) -> Option<Self::Handle>;
fn clone_weak_handle(&self) -> Self::WeakHandle;
}

#[macro_export]
macro_rules! define_handles {
(< $t:ty > :: $i:ident , $sv:vis $s:ident , $wv:vis $w:ident) => {
impl riddle_common::CloneHandle for $t {
type Handle = $s;
type WeakHandle = $w;

#[inline]
fn clone_handle(&self) -> Option<$s> {
<$w>::upgrade(&self.$i)
}

#[inline]
fn clone_weak_handle(&self) -> $w {
self.$i.clone()
}
}

#[derive(Clone)]
$sv struct $s {
handle: std::sync::Arc<$t>,
}

impl $s {
#[inline]
pub fn downgrade(this: &$s) -> $w {
$w {
handle: std::sync::Arc::downgrade(&this.handle)
}
}

#[inline]
pub fn new<F: FnOnce($w) -> $t>(f: F) -> $s {
$s {
handle: std::sync::Arc::new_cyclic(|weak_sync| {
let weak_self = $w { handle: weak_sync.clone() };
f(weak_self)
})
}
}

#[inline]
pub fn eq(a: &$s, b: &$s) -> bool {
std::sync::Arc::ptr_eq(&a.handle, &b.handle)
}
}

impl std::ops::Deref for $s {
type Target = $t;

#[inline]
fn deref(&self) -> &$t {
std::ops::Deref::deref(&self.handle)
}
}

#[derive(Clone)]
$wv struct $w {
handle: std::sync::Weak<$t>,
}

fn clone_weak_handle(&self) -> Weak<Self>;
impl $w {
#[inline]
pub fn upgrade(this: &$w) -> Option<$s> {
std::sync::Weak::upgrade(&this.handle).map(|s| $s { handle: s.clone() })
}
}
};
}
40 changes: 21 additions & 19 deletions crates/riddle-common/src/eventpub.rs
Original file line number Diff line number Diff line change
@@ -1,35 +1,34 @@
use std::{
cell::RefCell,
rc::{Rc, Weak},
};
use std::sync::{Arc, Mutex, RwLock, Weak};

struct EventQueue<T> {
queue: RefCell<Vec<T>>,
filter: Box<dyn Fn(&T) -> bool>,
queue: Mutex<Vec<T>>,
filter: Box<dyn Fn(&T) -> bool + Sync + Send>,
}

pub struct EventPub<T> {
subs: RefCell<Vec<Weak<EventQueue<T>>>>,
subs: RwLock<Vec<Weak<EventQueue<T>>>>,
}

pub struct EventSub<T> {
events: Rc<EventQueue<T>>,
events: Arc<EventQueue<T>>,
}

impl<T: Clone> EventPub<T> {
pub fn new() -> Self {
Self {
subs: RefCell::new(vec![]),
subs: RwLock::new(vec![]),
}
}

pub fn attach(&self, sub: &EventSub<T>) {
self.subs.borrow_mut().push(Rc::downgrade(&sub.events));
let mut subs = self.subs.write().unwrap();
subs.push(Arc::downgrade(&sub.events));
}

pub fn dispatch(&self, event: &T) {
let mut dirty = false;
for sub in self.subs.borrow().iter() {

for sub in self.subs.read().unwrap().iter() {
match Weak::upgrade(sub) {
Some(strong_sub) => strong_sub.deliver(event.clone()),
None => dirty = true,
Expand All @@ -42,9 +41,8 @@ impl<T: Clone> EventPub<T> {
}

fn clean(&self) {
self.subs
.borrow_mut()
.retain(|w| Weak::upgrade(w).is_some())
let mut subs = self.subs.write().unwrap();
subs.retain(|w| Weak::upgrade(w).is_some())
}
}

Expand All @@ -57,7 +55,7 @@ impl<T> EventSub<T> {

pub fn new_with_filter<F>(filter: F) -> Self
where
F: Fn(&T) -> bool + 'static,
F: Fn(&T) -> bool + Send + Sync + 'static,
{
Self {
events: EventQueue::new_with_filter(filter).into(),
Expand All @@ -76,21 +74,25 @@ impl<T> EventQueue<T> {

fn new_with_filter<F>(filter: F) -> Self
where
F: Fn(&T) -> bool + 'static,
F: Fn(&T) -> bool + Send + Sync + 'static,
{
Self {
queue: RefCell::new(vec![]),
queue: Mutex::new(vec![]),
filter: Box::new(filter),
}
}

fn deliver(&self, event: T) {
if (*self.filter)(&event) {
self.queue.borrow_mut().push(event);
let mut queue = self.queue.lock().unwrap();
queue.push(event);
}
}

fn collect(&self) -> Vec<T> {
self.queue.replace(vec![])
let mut queue = self.queue.lock().unwrap();
let mut res = vec![];
res.append(&mut queue);
res
}
}
3 changes: 2 additions & 1 deletion crates/riddle-common/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
use thiserror::Error;

mod clone_handle;
mod color;

pub mod clone_handle;
pub mod eventpub;

pub use clone_handle::*;
pub use color::*;

#[derive(Debug, Error)]
Expand Down
62 changes: 62 additions & 0 deletions crates/riddle-input/src/gamepad_state.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
use crate::*;

use std::collections::{HashMap, HashSet};

pub(crate) struct GamePadState {
buttons: HashSet<GamePadButton>,
}

impl GamePadState {
pub fn new() -> Self {
Self {
buttons: HashSet::new(),
}
}

fn is_button_down(&self, button: GamePadButton) -> bool {
self.buttons.contains(&button)
}

fn button_down(&mut self, button: GamePadButton) {
self.buttons.insert(button);
}

fn button_up(&mut self, button: GamePadButton) {
self.buttons.remove(&button);
}
}

pub(crate) struct GamePadStateMap {
gamepads: HashMap<GamePadId, GamePadState>,
}

impl GamePadStateMap {
pub fn new() -> Self {
Self {
gamepads: HashMap::new(),
}
}

pub fn is_button_down(&self, pad: GamePadId, button: GamePadButton) -> bool {
if let Some(pad_state) = self.gamepads.get(&pad) {
pad_state.is_button_down(button)
} else {
false
}
}

pub fn button_down(&mut self, pad: GamePadId, button: GamePadButton) {
self.get_pad_mut(pad).button_down(button);
}

pub fn button_up(&mut self, pad: GamePadId, button: GamePadButton) {
self.get_pad_mut(pad).button_up(button);
}

fn get_pad_mut(&mut self, pad: GamePadId) -> &mut GamePadState {
if !self.gamepads.contains_key(&pad) {
self.gamepads.insert(pad.clone(), GamePadState::new());
}
self.gamepads.get_mut(&pad).unwrap()
}
}
Loading