Struct netsblox_vm::std_system::StdSystem
source · pub struct StdSystem<C: CustomTypes<StdSystem<C>>> { /* private fields */ }Expand description
A type implementing the System trait which supports all features.
Implementations§
source§impl<C: CustomTypes<StdSystem<C>>> StdSystem<C>
impl<C: CustomTypes<StdSystem<C>>> StdSystem<C>
sourcepub fn new_sync(
base_url: String,
project_name: Option<&str>,
config: Config<C, Self>,
clock: Arc<Clock>
) -> Self
pub fn new_sync( base_url: String, project_name: Option<&str>, config: Config<C, Self>, clock: Arc<Clock> ) -> Self
Equivalent to StdSystem::new_async except that it can be executed outside of async context.
Note that using this from within async context will result in a panic from tokio trying to create a runtime within a runtime.
Examples found in repository?
examples/basic.rs (line 125)
92 93 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
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(BASE_URL.to_owned(), 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;
}
}
}sourcepub async fn new_async(
base_url: String,
project_name: Option<&str>,
config: Config<C, Self>,
clock: Arc<Clock>
) -> Self
pub async fn new_async( base_url: String, project_name: Option<&str>, config: Config<C, Self>, clock: Arc<Clock> ) -> Self
Initializes a new instance of StdSystem targeting the given NetsBlox server base url (e.g., https://cloud.netsblox.org).
sourcepub async fn call_rpc_async(
&self,
service: &str,
rpc: &str,
args: &[(&str, &Json)]
) -> Result<SimpleValue, String>
pub async fn call_rpc_async( &self, service: &str, rpc: &str, args: &[(&str, &Json)] ) -> Result<SimpleValue, String>
Asynchronously calls an RPC and returns the result.
This function directly makes requests to NetsBlox, bypassing any RPC hook defined by Config.
sourcepub fn get_public_id(&self) -> String
pub fn get_public_id(&self) -> String
Gets the public id of the running system that can be used to send messages to this client.
sourcepub fn inject_message(
&self,
msg_type: String,
values: Vec<(String, SimpleValue)>
)
pub fn inject_message( &self, msg_type: String, values: Vec<(String, SimpleValue)> )
Injects a message into the receiving queue as if received over the network.
Trait Implementations§
source§impl<C: CustomTypes<StdSystem<C>>> System<C> for StdSystem<C>
impl<C: CustomTypes<StdSystem<C>>> System<C> for StdSystem<C>
§type RequestKey = RequestKey<C>
type RequestKey = RequestKey<C>
Key type used to await the result of an asynchronous request.
§type CommandKey = CommandKey
type CommandKey = CommandKey
Key type used to await the completion of an asynchronous command.
§type ExternReplyKey = ExternReplyKey
type ExternReplyKey = ExternReplyKey
Key type used to await the result of a “send message and wait” block (response from target).
§type InternReplyKey = InternReplyKey
type InternReplyKey = InternReplyKey
Key type used to reply to a message that was sent to this client with the expectation of receiving a response.
This type is required to be
Clone because there can be multiple message handlers for the same message type.source§fn rand<T: SampleUniform, R: SampleRange<T>>(&self, range: R) -> T
fn rand<T: SampleUniform, R: SampleRange<T>>(&self, range: R) -> T
Gets a random value sampled from the given
range, which is assumed to be non-empty.
The input for this generic function is such that it is compatible with rand::Rng::gen_range,
which makes it possible to implement this function with any random provider under the rand crate standard.source§fn perform_request<'gc>(
&self,
mc: &Mutation<'gc>,
request: Request<'gc, C, Self>,
proc: &mut Process<'gc, C, Self>
) -> Result<Self::RequestKey, ErrorCause<C, Self>>
fn perform_request<'gc>( &self, mc: &Mutation<'gc>, request: Request<'gc, C, Self>, proc: &mut Process<'gc, C, Self> ) -> Result<Self::RequestKey, ErrorCause<C, Self>>
Performs a general request which returns a value to the system.
Ideally, this function should be non-blocking, and the requestor will await the result asynchronously.
The
Entity that made the request is provided for context.source§fn poll_request<'gc>(
&self,
mc: &Mutation<'gc>,
key: &Self::RequestKey,
proc: &mut Process<'gc, C, Self>
) -> Result<AsyncResult<Result<Value<'gc, C, Self>, String>>, ErrorCause<C, Self>>
fn poll_request<'gc>( &self, mc: &Mutation<'gc>, key: &Self::RequestKey, proc: &mut Process<'gc, C, Self> ) -> Result<AsyncResult<Result<Value<'gc, C, Self>, String>>, ErrorCause<C, Self>>
Poll for the completion of an asynchronous request.
The
Entity that made the request is provided for context.source§fn perform_command<'gc>(
&self,
mc: &Mutation<'gc>,
command: Command<'gc, '_, C, Self>,
proc: &mut Process<'gc, C, Self>
) -> Result<Self::CommandKey, ErrorCause<C, Self>>
fn perform_command<'gc>( &self, mc: &Mutation<'gc>, command: Command<'gc, '_, C, Self>, proc: &mut Process<'gc, C, Self> ) -> Result<Self::CommandKey, ErrorCause<C, Self>>
Performs a general command which does not return a value to the system.
Ideally, this function should be non-blocking, and the commander will await the task’s completion asynchronously.
The
Entity that issued the command is provided for context.source§fn poll_command<'gc>(
&self,
mc: &Mutation<'gc>,
key: &Self::CommandKey,
proc: &mut Process<'gc, C, Self>
) -> Result<AsyncResult<Result<(), String>>, ErrorCause<C, Self>>
fn poll_command<'gc>( &self, mc: &Mutation<'gc>, key: &Self::CommandKey, proc: &mut Process<'gc, C, Self> ) -> Result<AsyncResult<Result<(), String>>, ErrorCause<C, Self>>
Poll for the completion of an asynchronous command.
The
Entity that issued the command is provided for context.source§fn send_message(
&self,
msg_type: String,
values: Vec<(String, Json)>,
targets: Vec<String>,
expect_reply: bool
) -> Result<Option<Self::ExternReplyKey>, ErrorCause<C, StdSystem<C>>>
fn send_message( &self, msg_type: String, values: Vec<(String, Json)>, targets: Vec<String>, expect_reply: bool ) -> Result<Option<Self::ExternReplyKey>, ErrorCause<C, StdSystem<C>>>
Sends a message containing a set of named
values to each of the specified targets.
The expect_reply value controls whether or not to use a reply mechanism to asynchronously receive a response from the target(s).
In the case that there are multiple targets, only the first reply (if any) should be used.source§fn poll_reply(&self, key: &Self::ExternReplyKey) -> AsyncResult<Option<Json>>
fn poll_reply(&self, key: &Self::ExternReplyKey) -> AsyncResult<Option<Json>>
Polls for a response from a client initiated by
System::send_message.
If the client responds, a value of [Some(x)] is returned.
The system may elect to impose a timeout for reply results, in which case None is returned instead.source§fn send_reply(
&self,
key: Self::InternReplyKey,
value: Json
) -> Result<(), ErrorCause<C, Self>>
fn send_reply( &self, key: Self::InternReplyKey, value: Json ) -> Result<(), ErrorCause<C, Self>>
Sends a reply to the sender of a blocking message this client received.
source§fn receive_message(&self) -> Option<IncomingMessage<C, Self>>
fn receive_message(&self) -> Option<IncomingMessage<C, Self>>
Attempts to receive a message from the message buffer.
This operation is always non-blocking and returns
None if there are no messages in the buffer.
If a message is received, a tuple of form (msg_type, values, reply_key) is returned.Auto Trait Implementations§
impl<C> !RefUnwindSafe for StdSystem<C>
impl<C> !Send for StdSystem<C>
impl<C> !Sync for StdSystem<C>
impl<C> Unpin for StdSystem<C>
impl<C> !UnwindSafe for StdSystem<C>
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