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>

source

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 }
    })
}
source

pub fn new(global_context: Gc<'gc, RefLock<GlobalContext<'gc, C, S>>>) -> Self

source

pub fn add_script( &mut self, start_pos: usize, entity: Gc<'gc, RefLock<Entity<'gc, C, S>>>, event: Event )

source

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 }
    })
}
source

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;
        }
    }
}
source

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>

source§

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)

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> Any for T
where T: 'static + ?Sized,

source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
source§

impl<T> Borrow<T> for T
where T: ?Sized,

source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
source§

impl<T> From<T> for T

source§

fn from(t: T) -> T

Returns the argument unchanged.

§

impl<T> Instrument for T

§

fn instrument(self, span: Span) -> Instrumented<Self>

Instruments this type with the provided [Span], returning an Instrumented wrapper. Read more
§

fn in_current_span(self) -> Instrumented<Self>

Instruments this type with the current Span, returning an Instrumented wrapper. Read more
source§

impl<T, U> Into<U> for T
where U: From<T>,

source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

source§

impl<T> Same for T

§

type Output = T

Should always be Self
source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

§

type Error = Infallible

The type returned in the event of a conversion error.
source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.
§

impl<V, T> VZip<V> for T
where V: MultiLane<T>,

§

fn vzip(self) -> V

§

impl<T> WithSubscriber for T

§

fn with_subscriber<S>(self, subscriber: S) -> WithDispatch<Self>
where S: Into<Dispatch>,

Attaches the provided Subscriber to this type, returning a [WithDispatch] wrapper. Read more
§

fn with_current_subscriber(self) -> WithDispatch<Self>

Attaches the current default Subscriber to this type, returning a [WithDispatch] wrapper. Read more