Closed TyOverby closed 9 years ago
This does seem much simpler. One question I had about the earlier PR was that it seems as if you'll need different contexts for rust/ares interactions modifying different types (Or perhaps just different values? Can the context be reloaded?). How will those contexts interact? Can they be layered?
The earlier PR (which I plan on adding things from iteratively) limited the context to being "loaded" with only one type. I think this will be reasonable for most applications because they can think of that type as the "public api" that Ares gets access to. That API struct could contain mutable borrows into whatever else you wanted to access.
The context can certainly be reloaded! The way the contexts work is that Context
lets you read/write global variables at will, but LoadedContext
will let you read/write AND do eval. (This is because doing an eval on an unloaded Context
could call a ForeignFunction that wants to modify a state, whereas reading and writing globals never requires the state to be filled).
LoadedContext
s are always temporary. They borrow their state by mutable reference so that when they go out of scope, they release the borrow on the rust state object and release the borrow on the unloaded Context
(which can be loaded again).
Here's another example (the state stuff is not finished yet):
// Our context will have a bool as the state
let mut context: Context<bool> = Context::new();
// So we can write functions that expect a boolean state
context.set("trigger", user_fn(|args, ctx| *ctx.state = true));
for _ in 0 .. 10 {
// A new state for each loop!
bool triggered = false;
// The context gets loaded once for every iteration in the loop
let mut loaded = context.load(&mut triggered);
// Cann the function that we loaded in the bare Context
loaded.eval_str("(trigger)");
// Our local state gets modified
assert!(triggered);
}
Oh. I should point out that if the user doesn't want to load a state 100% of the time, that person could just have their state be Option<T>
instead of just T
and then load a None
.
This is taking over the other context pull-request because it is way simpler and easier to make iterative improvements to.