Skip to content

Commit

Permalink
working partial refactor
Browse files Browse the repository at this point in the history
  • Loading branch information
dragazo committed Nov 11, 2023
1 parent e979cd6 commit 3faee30
Show file tree
Hide file tree
Showing 7 changed files with 84 additions and 88 deletions.
2 changes: 1 addition & 1 deletion src/bytecode.rs
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,7 @@ impl BasicType {
}
}

pub(crate) enum InternalInstruction<'a> {
enum InternalInstruction<'a> {
/// Triggers an error when encountered.
/// This is an internal value that is only used to denote incomplete linking results for better testing.
/// Properly-linked byte code should not contain this value.
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ extern crate std;
#[macro_use] extern crate alloc;
#[macro_use] extern crate num_derive;

pub(crate) use educe::Educe;
use educe::Educe;

/// Re-exports of relevant items from `gc_arena`.
pub mod gc {
Expand Down
9 changes: 4 additions & 5 deletions src/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ pub enum ProcessStep<'gc, C: CustomTypes<S>, S: System<C>> {
/// This contains information about the call origin and local variables defined in the called context.
#[derive(Collect)]
#[collect(no_drop, bound = "")]
pub struct CallStackEntry<'gc, C: CustomTypes<S>, S: System<C>> {
struct CallStackEntry<'gc, C: CustomTypes<S>, S: System<C>> {
#[collect(require_static)] called_from: usize,
#[collect(require_static)] return_to: usize,
entity: Gc<'gc, RefLock<Entity<'gc, C, S>>>,
Expand Down Expand Up @@ -212,8 +212,7 @@ pub struct Process<'gc, C: CustomTypes<S>, S: System<C>> {
last_message: Option<Value<'gc, C, S>>,
}
impl<'gc, C: CustomTypes<S>, S: System<C>> Process<'gc, C, S> {
/// Creates a new [`Process`] that is tied to a given `start_pos` (entry point) in the [`ByteCode`] and associated with the specified `entity` and `system`.
/// The created process is initialized to an idle (non-running) state; use [`Process::initialize`] to begin execution.
/// Creates a new [`Process`] with the given starting context.
pub fn new(context: ProcContext<'gc, C, S>) -> Self {
Self {
global_context: context.global_context,
Expand Down Expand Up @@ -460,9 +459,9 @@ impl<'gc, C: CustomTypes<S>, S: System<C>> Process<'gc, C, S> {
self.value_stack.push(lookup_var!(var).get().clone());
self.pos = aft_pos;
}
Instruction::PushEntity { name } => match global_context.entities.iter().find(|&x| x.borrow().name.as_str() == name) {
Instruction::PushEntity { name } => match global_context.entities.iter().find(|&x| x.0 == name) {
Some(x) => {
self.value_stack.push(Value::Entity(*x));
self.value_stack.push(Value::Entity(x.1));
self.pos = aft_pos;
}
None => return Err(ErrorCause::UndefinedEntity { name: name.into() }),
Expand Down
82 changes: 37 additions & 45 deletions src/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -95,39 +95,41 @@ pub enum ProjectStep<'gc, C: CustomTypes<S>, S: System<C>> {
Pause,
}

#[derive(Collect, Educe)]
#[collect(no_drop, bound = "")]
#[educe(Clone, Default)]
pub struct PartialProcContext<'gc, C: CustomTypes<S>, S: System<C>> {
pub locals: SymbolTable<'gc, C, S>,
#[collect(require_static)] pub barrier: Option<Barrier>,
#[collect(require_static)] pub reply_key: Option<S::InternReplyKey>,
#[collect(require_static)] pub local_message: Option<String>,
}

#[derive(Collect)]
#[collect(no_drop, bound = "")]
struct Script<'gc, C: CustomTypes<S>, S: System<C>> {
#[collect(require_static)] event: Rc<(Event, usize)>, // event and bytecode start pos
entity: Gc<'gc, RefLock<Entity<'gc, C, S>>>,
#[collect(require_static)] process: Option<ProcessKey>,
context_queue: VecDeque<ProcContext<'gc, C, S>>,
context_queue: VecDeque<PartialProcContext<'gc, C, S>>,
}
impl<'gc, C: CustomTypes<S>, S: System<C>> Script<'gc, C, S> {
fn consume_context(&mut self, state: &mut State<'gc, C, S>) {
let process = self.process.and_then(|key| Some((key, state.processes.get_mut(key)?)));
if process.as_ref().map(|x| x.1.is_running()).unwrap_or(false) { return }

let context = match self.context_queue.pop_front() {
Some(x) => x,
None => return,
};

match process {
Some((key, process)) => {
debug_assert!(!state.process_queue.contains(&key));
debug_assert_eq!(self.process, Some(key));

process.initialize(context);
state.process_queue.push_back(key);
}
None => {
let mut process = Process::new(state.global_context, self.entity, self.event.1);
process.initialize(context);
let key = state.processes.insert(process);
state.process_queue.push_back(key);
self.process = Some(key);
Some(proc) => match proc.1.is_running() {
true => return,
false => unreachable!(), // should have already been cleaned up by the scheduler
}
None => match self.context_queue.pop_front() {
None => return,
Some(context) => {
let process = Process::new(ProcContext { global_context: state.global_context, entity: self.entity, start_pos: self.event.1, locals: context.locals, barrier: context.barrier, reply_key: context.reply_key, local_message: context.local_message });
let key = state.processes.insert(process);
state.process_queue.push_back(key);
self.process = Some(key);
}
},
}
}
fn stop_all(&mut self, state: &mut State<'gc, C, S>) {
Expand All @@ -136,7 +138,7 @@ impl<'gc, C: CustomTypes<S>, S: System<C>> Script<'gc, C, S> {
}
self.context_queue.clear();
}
fn schedule(&mut self, state: &mut State<'gc, C, S>, context: ProcContext<'gc, C, S>, max_queue: usize) {
fn schedule(&mut self, state: &mut State<'gc, C, S>, context: PartialProcContext<'gc, C, S>, max_queue: usize) {
self.context_queue.push_back(context);
self.consume_context(state);
if self.context_queue.len() > max_queue {
Expand Down Expand Up @@ -180,9 +182,9 @@ impl<'gc, C: CustomTypes<S>, S: System<C>> Project<'gc, C, S> {
let mut project = Self::new(Gc::new(mc, RefLock::new(global_context)));

for entity_info in init_info.entities.iter() {
let entity = *project.state.global_context.borrow().entities.get(&entity_info.name).unwrap();
let entity = project.state.global_context.borrow().entities.iter().find(|&x| x.0 == entity_info.name).unwrap().1;
for (event, pos) in entity_info.scripts.iter() {
project.add_script(*pos, entity, Some(event.clone()));
project.add_script(*pos, entity, event.clone());
}
}

Expand All @@ -198,23 +200,13 @@ impl<'gc, C: CustomTypes<S>, S: System<C>> Project<'gc, C, S> {
scripts: Default::default(),
}
}
pub fn add_script(&mut self, start_pos: usize, entity: Gc<'gc, RefLock<Entity<'gc, C, S>>>, event: Option<Event>) {
let mut all_contexts_consumer = AllContextsConsumer::new();
match event {
Some(event) => self.scripts.push(Script {
event: Rc::new((event, start_pos)),
entity,
process: None,
context_queue: Default::default(),
}),
None => {
let process = Process::new(self.state.global_context, entity, start_pos);
let key = self.state.processes.insert(process);

all_contexts_consumer.do_once(self); // need to consume all contexts before scheduling things in the future
self.state.process_queue.push_back(key);
}
}
pub fn add_script(&mut self, start_pos: usize, entity: Gc<'gc, RefLock<Entity<'gc, C, S>>>, event: Event) {
self.scripts.push(Script {
event: Rc::new((event, start_pos)),
entity,
process: None,
context_queue: Default::default(),
});
}
pub fn input(&mut self, mc: &Mutation<'gc>, input: Input) {
let mut all_contexts_consumer = AllContextsConsumer::new();
Expand All @@ -241,7 +233,7 @@ impl<'gc, C: CustomTypes<S>, S: System<C>> Project<'gc, C, S> {

all_contexts_consumer.do_once(self); // need to consume all contexts before scheduling things in the future
if interrupt { self.scripts[i].stop_all(&mut self.state); }
self.scripts[i].schedule(&mut self.state, ProcContext { locals, ..Default::default() }, max_queue);
self.scripts[i].schedule(&mut self.state, PartialProcContext { locals, ..Default::default() }, max_queue);
}
}
}
Expand Down Expand Up @@ -282,7 +274,7 @@ impl<'gc, C: CustomTypes<S>, S: System<C>> Project<'gc, C, S> {
}

all_contexts_consumer.do_once(self); // need to consume all contexts before scheduling things in the future
self.scripts[i].schedule(&mut self.state, ProcContext { locals, barrier: None, reply_key: reply_key.clone(), local_message: None }, usize::MAX);
self.scripts[i].schedule(&mut self.state, PartialProcContext { locals, barrier: None, reply_key: reply_key.clone(), local_message: None }, usize::MAX);
}
}
}
Expand Down Expand Up @@ -341,7 +333,7 @@ impl<'gc, C: CustomTypes<S>, S: System<C>> Project<'gc, C, S> {
for script in new_scripts.iter_mut() {
if let Event::OnClone = &script.event.0 {
all_contexts_consumer.do_once(self); // need to consume all contexts before scheduling things in the future
script.schedule(&mut self.state, ProcContext::default(), 0);
script.schedule(&mut self.state, Default::default(), 0);
}
}
self.scripts.extend(new_scripts);
Expand All @@ -360,7 +352,7 @@ impl<'gc, C: CustomTypes<S>, S: System<C>> Project<'gc, C, S> {

all_contexts_consumer.do_once(self); // need to consume all contexts before scheduling things in the future
self.scripts[i].stop_all(&mut self.state);
self.scripts[i].schedule(&mut self.state, ProcContext { locals: Default::default(), barrier: barrier.clone(), reply_key: None, local_message: Some(msg_type.clone()) }, 0);
self.scripts[i].schedule(&mut self.state, PartialProcContext { locals: Default::default(), barrier: barrier.clone(), reply_key: None, local_message: Some(msg_type.clone()) }, 0);
}
}
}
Expand Down
20 changes: 10 additions & 10 deletions src/runtime.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1085,14 +1085,14 @@ pub enum EntityKind<'gc, 'a, C: CustomTypes<S>, S: System<C>> {
#[derive(Collect)]
#[collect(no_drop, bound = "")]
pub struct Entity<'gc, C: CustomTypes<S>, S: System<C>> {
#[collect(require_static)] pub(crate) name: Rc<String>,
#[collect(require_static)] pub(crate) sound_list: Rc<Vec<(String, Rc<Audio>)>>,
#[collect(require_static)] pub(crate) costume_list: Rc<Vec<(String, Rc<Image>)>>,
#[collect(require_static)] pub(crate) costume: Option<Rc<Image>>,
#[collect(require_static)] pub(crate) state: C::EntityState,
#[collect(require_static)] pub(crate) alive: bool,
pub(crate) original: Option<Gc<'gc, RefLock<Entity<'gc, C, S>>>>,
pub(crate) fields: SymbolTable<'gc, C, S>,
#[collect(require_static)] pub name: Rc<String>,
#[collect(require_static)] pub sound_list: Rc<Vec<(String, Rc<Audio>)>>,
#[collect(require_static)] pub costume_list: Rc<Vec<(String, Rc<Image>)>>,
#[collect(require_static)] pub costume: Option<Rc<Image>>,
#[collect(require_static)] pub state: C::EntityState,
#[collect(require_static)] pub alive: bool,
pub original: Option<Gc<'gc, RefLock<Entity<'gc, C, S>>>>,
pub fields: SymbolTable<'gc, C, S>,
}
impl<C: CustomTypes<S>, S: System<C>> fmt::Debug for Entity<'_, C, S> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
Expand Down Expand Up @@ -1341,7 +1341,7 @@ pub struct GlobalContext<'gc, C: CustomTypes<S>, S: System<C>> {
#[collect(require_static)] pub timer_start: u64,
#[collect(require_static)] pub proj_name: String,
pub globals: SymbolTable<'gc, C, S>,
pub entities: Vec<Gc<'gc, RefLock<Entity<'gc, C, S>>>>,
pub entities: Vec<(String, Gc<'gc, RefLock<Entity<'gc, C, S>>>)>,
}
impl<'gc, C: CustomTypes<S>, S: System<C>> GlobalContext<'gc, C, S> {
pub fn from_init(mc: &Mutation<'gc>, init_info: &InitInfo, bytecode: Rc<ByteCode>, settings: Settings, system: Rc<S>) -> Self {
Expand Down Expand Up @@ -1431,7 +1431,7 @@ impl<'gc, C: CustomTypes<S>, S: System<C>> GlobalContext<'gc, C, S> {
let name = Rc::new(entity_info.name.clone());
let state = kind.into();

entities.push(Gc::new(mc, RefLock::new(Entity { alive: true, original: None, name, fields, sound_list, costume_list, costume, state })));
entities.push(((*name).clone(), Gc::new(mc, RefLock::new(Entity { alive: true, original: None, name, fields, sound_list, costume_list, costume, state }))));
}

let proj_name = init_info.proj_name.clone();
Expand Down
4 changes: 2 additions & 2 deletions src/std_system.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ struct ReplyEntry {
/// A [`StdSystem`] key type for an asynchronous request.
pub struct RequestKey<C: CustomTypes<StdSystem<C>>>(Arc<Mutex<AsyncResult<Result<C::Intermediate, String>>>>);
impl<C: CustomTypes<StdSystem<C>>> RequestKey<C> {
pub(crate) fn poll(&self) -> AsyncResult<Result<C::Intermediate, String>> { self.0.lock().unwrap().poll() }
fn poll(&self) -> AsyncResult<Result<C::Intermediate, String>> { self.0.lock().unwrap().poll() }
}
impl<C: CustomTypes<StdSystem<C>>> Key<Result<C::Intermediate, String>> for RequestKey<C> {
/// Completes the request with the given result.
Expand All @@ -85,7 +85,7 @@ impl<C: CustomTypes<StdSystem<C>>> Key<Result<C::Intermediate, String>> for Requ
/// A [`StdSystem`] key type for an asynchronous command.
pub struct CommandKey(Arc<Mutex<AsyncResult<Result<(), String>>>>);
impl CommandKey {
pub(crate) fn poll(&self) -> AsyncResult<Result<(), String>> { self.0.lock().unwrap().poll() }
fn poll(&self) -> AsyncResult<Result<(), String>> { self.0.lock().unwrap().poll() }
}
impl Key<Result<(), String>> for CommandKey {
/// Completes the command.
Expand Down
Loading

0 comments on commit 3faee30

Please sign in to comment.