#How can I pass in additional parameters to a scheduled system?

1 messages · Page 1 of 1 (latest)

feral crag
#

I have a Schedule, and I've add_systemed one system. I'm going to run that schedule, but I need to pass an additional parameter (not part of the ECS) to that system. How can I do that?

torpid path
#

I think you'll have to go via a resource, unless it's some const parameter

feral crag
#

I'm having trouble initializing my resource with a reference. My parameter is a nontrivial struct that I don't want to copy. But when I try to use a reference I end up running into lifetime errors.

#
#[derive(Resource)]
struct Context(&BTerm);

fn draw_things(mut ctx: ResMut<Context>, query: Query<(&Position, &Renderable)>) {
    for (p, r) in &query {
        ctx.0.set(p.x, p.y, r.fg, r.bg, r.glyph);
    }
}

fn main() -> terminal::BError {
    let context = BTermBuilder::foo()
    let mut gs = State {
        ecs: World::new()
    };

    gs.ecs.insert_resource(Context(&context));
}

I think these are the relevant parts of my code.
This produces expected named lifetime parameter error on struct Context(&BTerm);, and my efforts to add such a parameter lead to other errors about the lifetime not being as long as 'static

#

I also tried making my Resource be a struct with a BTerm field, but still ran into effectively the same problems

feral crag
#

the folks on the Rust-lang discord server tell me there's no way to accomplish this directly

#

the ownership issues are insurmountable as long as bracket-lib's main_loop expects to own the BTerm that I also need to stick into a bevy_ecs Resource

torpid path
#

What about something like Arc? or is it possible to make it static?

feral crag
#

the function I'm passing the context to demands a BTerm, not an Arc<BTerm> 😦

#

I've tried making it static. That leads to the reference in the Context struct being acceptable if it has a named lifetime, but the mut ctx: ResMut<Context> parameter is then complaining:

`global` has an anonymous lifetime `'_` but it needs to satisfy a `'static` lifetime requirement
this data with an anonymous lifetime `'_`...
torpid path
#

Does it demand a BTerm or a &BTerm?

torpid path
feral crag
#
invalid lifetime parameter name: `'static`
'static is a reserved lifetime name
#

I can't find anywhere I'm allowed to give things that lifetime

torpid path
#

That means you tried to declare it

#

but you don't need to declare it

#

If your function needs ownership then I don't see a way out

#

Fundamentally if it needs ownership then it is essentially consuming it

#

which is not compatible with Bevy. but I can't understand why it would do that

feral crag
#
pub fn main_loop<GS: GameState>(bterm: BTerm, gamestate: GS) -> BResult<()> {
torpid path
#

What is the signature of the thing that takes BTerm? And I assume it's not your code that takes it?

feral crag
#

that's it

#

and no, it's part of bracket-lib

torpid path
#

oh I see

#

what is BResult?

feral crag
#

pub type BResult<T> = anyhow::Result<T, Box<dyn std::error::Error + Send + Sync>>;

torpid path
#

Damn, was exploring the possibility it yielded BTerm back somehow but it doesn't

#

I don't know what the data flow is on this library (or what it even does)

feral crag
#

it's a game engine targeting roguelikes with console/terminal interfaces

torpid path
#

What exactly is meant to be generating these BTerms?

feral crag
#

one of the few that does real terminals, gui fake terminals, and 2d tiles in a gui

#

there's only ever one BTerm

#

BTermBuilder generates it at the top of main()

torpid path
#

but you pass it into a function calls loop, does that function loop forever?

#

There has to be something possible here

#

How do you interact with the roguelike while it's running

feral crag
#

yes, main_loop loops forever

#

it's like bevy's App.run()

torpid path
#

How do you define its behaviour while it's running?

#

I wonder if there's a way to communicate between the two apps via message channels

#

I know you can do Bevy's loop manually

#

and that would let you mess with the world in between stuff or loop some other thing

feral crag
#
#[derive(Resource)]
struct Global {
    context: BTerm
}
impl GameState for State {
    fn tick(&mut self, ctx : &mut BTerm) {
        self.world.resource_mut::<Global>().context.clone_from(ctx);
        self.world.run_schedule(TickSchedule);
        ctx.clone_from(&self.world.resource_mut::<Global>().context)
    }
}
fn main() -> terminal::BError {
    let context = BTermBuilder::simple80x50()
    let mut gs = State {
        world: World::new()
    };
    gs.world.insert_resource(Global { context: context.clone() });
    main_loop(context, gs)
}

this works. the cloning feels dirty 😦

torpid path
#

I don't think cloning will ever make sense because surely if it takes ownership it needs to consume it? Like

#

won't the clones just be stale versions?

feral crag
#

I clone it back

#

the BTerm owned by main_loop is stale while tick is running, and the one in the resource is stale while tick is not running