1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
use amethyst::{
    core::ArcThreadPool,
    ecs::{
        Dispatcher,
        DispatcherBuilder,
    },
    prelude::*,
};

use crate::{
    entities::character::CharacterAnimation,
    events::{EventExecutor, EventQueue},
    states::OverworldState,
    systems::{
        AnimationSystem,
        CharacterMovementSystem,
        MapChangeAnnouncementSystem,
        NpcInteractionSystem,
        TextSystem,
    },
};

use std::{
    cell::RefCell,
    ops::Deref,
    rc::Rc,
};

#[derive(Default)]
pub struct OverworldAnimationState<'a, 'b> {
    pub dispatcher: Option<Dispatcher<'a, 'b>>,
    pub event_executor: Rc<RefCell<EventExecutor>>,
}

impl<'a, 'b> OverworldAnimationState<'a, 'b> {
    pub fn new(event_executor: Rc<RefCell<EventExecutor>>) -> OverworldAnimationState<'a, 'b> {
        OverworldAnimationState {
            dispatcher: None,
            event_executor,
        }
    }
}

impl SimpleState for OverworldAnimationState<'_, '_> {
    fn on_start(&mut self, data: StateData<'_, GameData<'_, '_>>) {
        println!("Entering Animation State");

        let world = data.world;

        let mut dispatcher = DispatcherBuilder::new()
            .with(AnimationSystem::<CharacterAnimation>::new(), "animation_system", &[])
            .with(CharacterMovementSystem, "character_movement_system", &[])
            .with(NpcInteractionSystem, "npc_interaction_system", &[])
            .with(MapChangeAnnouncementSystem, "announcement_system", &[])
            .with(TextSystem::new(world), "text_system", &[])
            .with_pool(world.read_resource::<ArcThreadPool>().deref().clone())
            .build();

        dispatcher.setup(world);
        self.dispatcher = Some(dispatcher);
    }

    fn update(&mut self, data: &mut StateData<'_, GameData<'_, '_>>) -> SimpleTrans {
        let StateData { world, .. } = data;

        if let Some(dispatcher) = &mut self.dispatcher {
            dispatcher.dispatch(world);
        }

        {
            let mut event_queue = world.write_resource::<EventQueue>();

            while let Some(event) = event_queue.pop() {
                self.event_executor.borrow_mut().push(event);
            }
        }

        if self.event_executor.borrow().has_new_events() {
            self.event_executor.borrow_mut().start_new_events(world);
        }

        if !self.event_executor.borrow().requires_disabled_input() {
            return Trans::Switch(Box::new(OverworldState::new(self.event_executor.clone())));
        }

        self.event_executor.borrow_mut().tick(world, true);

        Trans::None
    }
}