Skip to content

Commit

Permalink
Don't always borrow plugin wrapper's internals mutalby
Browse files Browse the repository at this point in the history
  • Loading branch information
bugadani committed Oct 9, 2023
1 parent 999a768 commit af191e8
Showing 1 changed file with 22 additions and 13 deletions.
35 changes: 22 additions & 13 deletions src/plugin/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ where

#[derive(Clone, Debug)]
pub(crate) struct PluginInner<'a, M, C> {
pub(crate) plugin: M,
plugin: M,
state: ProcessingState,
peeked_token: Option<Token<'a, C>>,
}
Expand All @@ -87,7 +87,7 @@ pub(crate) struct PluginWrapper<'a, M, C> {
impl<'a, M: Clone, C: Clone> Clone for PluginWrapper<'a, M, C> {
fn clone(&self) -> Self {
Self {
inner: UnsafeCell::new(self.inner(|this| this.clone())),
inner: UnsafeCell::new(self.with(|this| this.clone())),
}
}
}
Expand All @@ -97,7 +97,7 @@ where
C: PixelColor,
{
fn hash<H: Hasher>(&self, state: &mut H) {
self.inner(|this| this.state.hash(state))
self.with(|this| this.state.hash(state))
}
}

Expand All @@ -116,7 +116,16 @@ impl<'a, M, C> PluginWrapper<'a, M, C> {
self.inner.into_inner().plugin
}

fn inner<R>(&self, cb: impl FnOnce(&mut PluginInner<'a, M, C>) -> R) -> R {
fn with<R>(&self, cb: impl FnOnce(&PluginInner<'a, M, C>) -> R) -> R {
let inner = unsafe {
// SAFETY: This is safe because we aren't exposing the reference.
self.inner.get().as_ref().unwrap_unchecked()
};

cb(inner)
}

fn with_mut<R>(&self, cb: impl FnOnce(&mut PluginInner<'a, M, C>) -> R) -> R {
let inner = unsafe {
// SAFETY: This is safe because we aren't exposing the reference.
self.inner.get().as_mut().unwrap_unchecked()
Expand All @@ -132,23 +141,23 @@ where
M: private::Plugin<'a, C>,
{
pub fn new_line(&self) {
self.inner(|this| this.plugin.new_line());
self.with_mut(|this| this.plugin.new_line());
}

pub fn set_state(&self, state: ProcessingState) {
self.inner(|this| this.state = state);
self.with_mut(|this| this.state = state);
}

#[inline]
pub fn render_token(&self, token: Token<'a, C>) -> Option<Token<'a, C>> {
self.inner(|this| match this.state {
self.with_mut(|this| match this.state {
ProcessingState::Measure => Some(token),
ProcessingState::Render => this.plugin.render_token(token),
})
}

pub fn peek_token(&self, source: &mut Parser<'a, C>) -> Option<Token<'a, C>> {
self.inner(|this| {
self.with_mut(|this| {
if this.peeked_token.is_none() {
this.peeked_token = this.plugin.next_token(|| source.next());
}
Expand All @@ -158,11 +167,11 @@ where
}

pub fn consume_peeked_token(&self) {
self.inner(|this| this.peeked_token = None);
self.with_mut(|this| this.peeked_token = None);
}

pub fn consume_partial(&self, len: usize) {
self.inner(|this| {
self.with_mut(|this| {
// Only string-like tokens can be partially consumed.
debug_assert!(matches!(
this.peeked_token,
Expand Down Expand Up @@ -196,15 +205,15 @@ where
cursor: &mut Cursor,
props: TextBoxProperties<'_, S>,
) {
self.inner(|this| {
self.with_mut(|this| {
this.peeked_token = None;

this.plugin.on_start_render(cursor, &props);
});
}

pub fn on_rendering_finished(&self) {
self.inner(|this| this.plugin.on_rendering_finished());
self.with_mut(|this| this.plugin.on_rendering_finished());
}

pub fn post_render<T, D>(
Expand All @@ -218,7 +227,7 @@ where
T: TextRenderer<Color = C>,
D: DrawTarget<Color = C>,
{
self.inner(|this| {
self.with_mut(|this| {
this.plugin
.post_render(draw_target, character_style, text, bounds)
})
Expand Down

0 comments on commit af191e8

Please sign in to comment.