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 92)
84fn get_running_project(xml: &str, system: Rc<StdSystem<C>>) -> EnvArena {
85 EnvArena::new(|mc| {
86 let parser = ast::Parser::default();
87 let ast = parser.parse(xml).unwrap();
88 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
89
90 let (bytecode, init_info, locs, _) = ByteCode::compile(&ast.roles[0]).unwrap();
91
92 let mut proj = Project::from_init(mc, &init_info, Rc::new(bytecode), Settings::default(), system);
93 proj.input(mc, Input::Start); // this is equivalent to clicking the green flag button
94
95 Env { proj: Gc::new(mc, RefLock::new(proj)), locs }
96 })
97}
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 93)
84fn get_running_project(xml: &str, system: Rc<StdSystem<C>>) -> EnvArena {
85 EnvArena::new(|mc| {
86 let parser = ast::Parser::default();
87 let ast = parser.parse(xml).unwrap();
88 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
89
90 let (bytecode, init_info, locs, _) = ByteCode::compile(&ast.roles[0]).unwrap();
91
92 let mut proj = Project::from_init(mc, &init_info, Rc::new(bytecode), Settings::default(), system);
93 proj.input(mc, Input::Start); // this is equivalent to clicking the green flag button
94
95 Env { proj: Gc::new(mc, RefLock::new(proj)), locs }
96 })
97}
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 143)
99fn main() {
100 // read in an xml file whose path is given as a command line argument
101 let args = std::env::args().collect::<Vec<_>>();
102 if args.len() != 2 {
103 panic!("usage: {} [xml file]", &args[0]);
104 }
105 let mut xml = String::new();
106 std::fs::File::open(&args[1]).expect("failed to open file").read_to_string(&mut xml).expect("failed to read file");
107
108 // create a new shared clock and start a thread that updates it at our desired interval
109 let clock = Arc::new(Clock::new(UtcOffset::UTC, Some(Precision::Medium)));
110 let clock_clone = clock.clone();
111 std::thread::spawn(move || loop {
112 std::thread::sleep(CLOCK_INTERVAL);
113 clock_clone.update();
114 });
115
116 // create a custom config for the system - in this simple example we just implement the say/think blocks to print to stdout
117 let config = Config::<C, StdSystem<C>> {
118 request: None,
119 command: Some(Rc::new(|_mc, key, command, _proc| match command {
120 Command::Print { style: _, value } => {
121 if let Some(value) = value {
122 println!("{value:?}");
123 }
124 key.complete(Ok(())); // any request that you handle must be completed - otherwise the calling process will hang forever
125 CommandStatus::Handled
126 }
127 _ => CommandStatus::UseDefault { key, command }, // anything you don't handle should return the key and command to invoke the default behavior instead
128 })),
129 };
130
131 // initialize our system with all the info we've put together
132 let system = Rc::new(StdSystem::new_sync(CompactString::new(BASE_URL), None, config, clock.clone()));
133 let mut env = get_running_project(&xml, system);
134
135 // begin running the code - these are some helpers to make things more efficient in terms of memory and cpu resources
136 let mut idle_sleeper = IdleAction::new(YIELDS_BEFORE_SLEEP, Box::new(|| std::thread::sleep(IDLE_SLEEP_TIME)));
137 let mut next_collect = clock.read(Precision::Medium) + COLLECT_INTERVAL;
138 loop {
139 env.mutate(|mc, env| {
140 let mut proj = env.proj.borrow_mut(mc);
141 for _ in 0..1024 {
142 // step the virtual machine forward by one bytecode instruction
143 let res = proj.step(mc);
144 if let ProjectStep::Error { error, proc } = &res {
145 // if we get an error, we can generate an error summary including a stack trace - here we just print out the result
146 let trace = ErrorSummary::extract(error, proc, &env.locs);
147 println!("error: {error:?}\ntrace: {trace:?}");
148 }
149 // this takes care of performing thread sleep if we get a bunch of no-ops from proj.step back to back
150 idle_sleeper.consume(&res);
151 }
152 });
153 // if it's time for us to do garbage collection, do it and reset the next collection time
154 if clock.read(Precision::Low) >= next_collect {
155 env.collect_all();
156 next_collect = clock.read(Precision::Medium) + COLLECT_INTERVAL;
157 }
158 }
159}
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> Freeze for Project<'gc, C, S>
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
<C as CustomTypes<S>>::ProcessState: Unpin,
<S as System<C>>::RequestKey: Unpin,
<S as System<C>>::CommandKey: Unpin,
<<C as CustomTypes<S>>::ProcessState as Unwindable>::UnwindPoint: 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