use brink_format::{DefinitionId, Value};
use crate::rng::StoryRng;
pub trait ContextAccess {
fn global(&self, idx: u32) -> &Value;
fn set_global(&mut self, idx: u32, value: Value);
fn visit_count(&self, id: DefinitionId) -> u32;
fn increment_visit(&mut self, id: DefinitionId);
fn set_visit_count(&mut self, id: DefinitionId, count: u32);
fn turn_count(&self, id: DefinitionId) -> Option<u32>;
fn set_turn_count(&mut self, id: DefinitionId, turn: u32);
fn turn_index(&self) -> u32;
fn increment_turn_index(&mut self);
fn set_turn_index(&mut self, index: u32);
fn rng_seed(&self) -> i32;
fn set_rng_seed(&mut self, seed: i32);
fn previous_random(&self) -> i32;
fn set_previous_random(&mut self, val: i32);
fn next_random<R: StoryRng>(&self, seed: i32) -> i32;
fn random_sequence<R: StoryRng>(&self, seed: i32, count: usize) -> Vec<i32>;
}
#[expect(unused_variables)]
pub trait WriteObserver {
fn on_set_global(&mut self, idx: u32, value: &Value) {}
fn on_increment_visit(&mut self, id: DefinitionId, new_count: u32) {}
fn on_set_visit_count(&mut self, id: DefinitionId, count: u32) {}
fn on_set_turn_count(&mut self, id: DefinitionId, turn: u32) {}
fn on_increment_turn_index(&mut self, new_value: u32) {}
fn on_set_turn_index(&mut self, index: u32) {}
fn on_set_rng_seed(&mut self, new_seed: i32) {}
fn on_set_previous_random(&mut self, new_val: i32) {}
}
pub struct ObservedContext<'a, 'o, C: ContextAccess> {
context: &'a mut C,
observer: &'o mut dyn WriteObserver,
}
impl<'a, 'o, C: ContextAccess> ObservedContext<'a, 'o, C> {
pub fn new(context: &'a mut C, observer: &'o mut dyn WriteObserver) -> Self {
Self { context, observer }
}
}
impl<C: ContextAccess> ContextAccess for ObservedContext<'_, '_, C> {
#[inline]
fn global(&self, idx: u32) -> &Value {
self.context.global(idx)
}
#[inline]
fn set_global(&mut self, idx: u32, value: Value) {
self.context.set_global(idx, value.clone());
self.observer.on_set_global(idx, &value);
}
#[inline]
fn visit_count(&self, id: DefinitionId) -> u32 {
self.context.visit_count(id)
}
#[inline]
fn increment_visit(&mut self, id: DefinitionId) {
self.context.increment_visit(id);
let new_count = self.context.visit_count(id);
self.observer.on_increment_visit(id, new_count);
}
#[inline]
fn set_visit_count(&mut self, id: DefinitionId, count: u32) {
self.context.set_visit_count(id, count);
self.observer.on_set_visit_count(id, count);
}
#[inline]
fn turn_count(&self, id: DefinitionId) -> Option<u32> {
self.context.turn_count(id)
}
#[inline]
fn set_turn_count(&mut self, id: DefinitionId, turn: u32) {
self.context.set_turn_count(id, turn);
self.observer.on_set_turn_count(id, turn);
}
#[inline]
fn turn_index(&self) -> u32 {
self.context.turn_index()
}
#[inline]
fn increment_turn_index(&mut self) {
self.context.increment_turn_index();
self.observer
.on_increment_turn_index(self.context.turn_index());
}
#[inline]
fn set_turn_index(&mut self, index: u32) {
self.context.set_turn_index(index);
self.observer.on_set_turn_index(index);
}
#[inline]
fn rng_seed(&self) -> i32 {
self.context.rng_seed()
}
#[inline]
fn set_rng_seed(&mut self, seed: i32) {
self.context.set_rng_seed(seed);
self.observer.on_set_rng_seed(seed);
}
#[inline]
fn previous_random(&self) -> i32 {
self.context.previous_random()
}
#[inline]
fn set_previous_random(&mut self, val: i32) {
self.context.set_previous_random(val);
self.observer.on_set_previous_random(val);
}
#[inline]
fn next_random<R: StoryRng>(&self, seed: i32) -> i32 {
self.context.next_random::<R>(seed)
}
fn random_sequence<R: StoryRng>(&self, seed: i32, count: usize) -> Vec<i32> {
self.context.random_sequence::<R>(seed, count)
}
}