Struct netsblox_vm::project::Project
source · pub struct Project<'gc, C: CustomTypes<S>, S: System<C>> { /* private fields */ }
Implementations§
source§impl<'gc, C: CustomTypes<S>, S: System<C>> Project<'gc, C, S>
impl<'gc, C: CustomTypes<S>, S: System<C>> Project<'gc, C, S>
sourcepub fn from_init(
mc: &Mutation<'gc>,
init_info: &InitInfo,
bytecode: Rc<ByteCode>,
settings: Settings,
system: Rc<S>
) -> Self
pub fn from_init( mc: &Mutation<'gc>, init_info: &InitInfo, bytecode: Rc<ByteCode>, settings: Settings, system: Rc<S> ) -> Self
Examples found in repository?
examples/basic.rs (line 87)
79 80 81 82 83 84 85 86 87 88 89 90 91 92
fn get_running_project(xml: &str, system: Rc<StdSystem<C>>) -> EnvArena {
EnvArena::new(|mc| {
let parser = ast::Parser::default();
let ast = parser.parse(xml).unwrap();
assert_eq!(ast.roles.len(), 1); // this should be handled more elegantly in practice - for the sake of this example, we only allow one role
let (bytecode, init_info, locs, _) = ByteCode::compile(&ast.roles[0]).unwrap();
let mut proj = Project::from_init(mc, &init_info, Rc::new(bytecode), Settings::default(), system);
proj.input(mc, Input::Start); // this is equivalent to clicking the green flag button
Env { proj: Gc::new(mc, RefLock::new(proj)), locs }
})
}
pub fn new(global_context: Gc<'gc, RefLock<GlobalContext<'gc, C, S>>>) -> Self
pub fn add_script( &mut self, start_pos: usize, entity: Gc<'gc, RefLock<Entity<'gc, C, S>>>, event: Event )
sourcepub fn input(&mut self, mc: &Mutation<'gc>, input: Input)
pub fn input(&mut self, mc: &Mutation<'gc>, input: Input)
Examples found in repository?
examples/basic.rs (line 88)
79 80 81 82 83 84 85 86 87 88 89 90 91 92
fn get_running_project(xml: &str, system: Rc<StdSystem<C>>) -> EnvArena {
EnvArena::new(|mc| {
let parser = ast::Parser::default();
let ast = parser.parse(xml).unwrap();
assert_eq!(ast.roles.len(), 1); // this should be handled more elegantly in practice - for the sake of this example, we only allow one role
let (bytecode, init_info, locs, _) = ByteCode::compile(&ast.roles[0]).unwrap();
let mut proj = Project::from_init(mc, &init_info, Rc::new(bytecode), Settings::default(), system);
proj.input(mc, Input::Start); // this is equivalent to clicking the green flag button
Env { proj: Gc::new(mc, RefLock::new(proj)), locs }
})
}
sourcepub fn step(&mut self, mc: &Mutation<'gc>) -> ProjectStep<'gc, C, S>
pub fn step(&mut self, mc: &Mutation<'gc>) -> ProjectStep<'gc, C, S>
Examples found in repository?
examples/basic.rs (line 138)
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
fn main() {
// read in an xml file whose path is given as a command line argument
let args = std::env::args().collect::<Vec<_>>();
if args.len() != 2 {
panic!("usage: {} [xml file]", &args[0]);
}
let mut xml = String::new();
std::fs::File::open(&args[1]).expect("failed to open file").read_to_string(&mut xml).expect("failed to read file");
// create a new shared clock and start a thread that updates it at our desired interval
let clock = Arc::new(Clock::new(UtcOffset::UTC, Some(Precision::Medium)));
let clock_clone = clock.clone();
std::thread::spawn(move || loop {
std::thread::sleep(CLOCK_INTERVAL);
clock_clone.update();
});
// create a custom config for the system - in this simple example we just implement the say/think blocks to print to stdout
let config = Config::<C, StdSystem<C>> {
request: None,
command: Some(Rc::new(|_mc, key, command, _proc| match command {
Command::Print { style: _, value } => {
if let Some(value) = value {
println!("{value:?}");
}
key.complete(Ok(())); // any request that you handle must be completed - otherwise the calling process will hang forever
CommandStatus::Handled
}
_ => CommandStatus::UseDefault { key, command }, // anything you don't handle should return the key and command to invoke the default behavior instead
})),
};
// initialize our system with all the info we've put together
let system = Rc::new(StdSystem::new_sync(CompactString::new(BASE_URL), None, config, clock.clone()));
let mut env = get_running_project(&xml, system);
// begin running the code - these are some helpers to make things more efficient in terms of memory and cpu resources
let mut idle_sleeper = IdleAction::new(YIELDS_BEFORE_SLEEP, Box::new(|| std::thread::sleep(IDLE_SLEEP_TIME)));
let mut next_collect = clock.read(Precision::Medium) + COLLECT_INTERVAL;
loop {
env.mutate(|mc, env| {
let mut proj = env.proj.borrow_mut(mc);
for _ in 0..1024 {
// step the virtual machine forward by one bytecode instruction
let res = proj.step(mc);
if let ProjectStep::Error { error, proc } = &res {
// if we get an error, we can generate an error summary including a stack trace - here we just print out the result
let trace = ErrorSummary::extract(error, proc, &env.locs);
println!("error: {error:?}\ntrace: {trace:?}");
}
// this takes care of performing thread sleep if we get a bunch of no-ops from proj.step back to back
idle_sleeper.consume(&res);
}
});
// if it's time for us to do garbage collection, do it and reset the next collection time
if clock.read(Precision::Low) >= next_collect {
env.collect_all();
next_collect = clock.read(Precision::Medium) + COLLECT_INTERVAL;
}
}
}
pub fn get_global_context(&self) -> Gc<'gc, RefLock<GlobalContext<'gc, C, S>>>
Trait Implementations§
source§impl<'gc, C: CustomTypes<S>, S: System<C>> Collect for Project<'gc, C, S>
impl<'gc, C: CustomTypes<S>, S: System<C>> Collect for Project<'gc, C, S>
source§fn needs_trace() -> bool
fn needs_trace() -> bool
As an optimization, if this type can never hold a
Gc
pointer and trace
is unnecessary
to call, you may implement this method and return false. The default implementation returns
true, signaling that Collect::trace
must be called.source§fn trace(&self, cc: &Collection)
fn trace(&self, cc: &Collection)
Must call
Collect::trace
on all held Gc
pointers. If this type holds inner types that
implement Collect
, a valid implementation would simply call Collect::trace
on all the
held values to ensure this.Auto Trait Implementations§
impl<'gc, C, S> !RefUnwindSafe for Project<'gc, C, S>
impl<'gc, C, S> !Send for Project<'gc, C, S>
impl<'gc, C, S> !Sync for Project<'gc, C, S>
impl<'gc, C, S> Unpin for Project<'gc, C, S>where
<S as System<C>>::CommandKey: Unpin,
<C as CustomTypes<S>>::ProcessState: Unpin,
<S as System<C>>::RequestKey: Unpin,
impl<'gc, C, S> !UnwindSafe for Project<'gc, C, S>
Blanket Implementations§
source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Mutably borrows from an owned value. Read more