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
91
92
93
94
95
/// Application driver traits.
///
/// Contains the specification for [AppDriver]. See that trait for more.
///
/// Also contains the minimal implementation of AppDriver; [MinimalAppDriver].
use thread;
use future;
use crateApplication;
use crate::;
use crateEvent;
/// Application logic driver.
///
/// An AppDriver represents how an [Application] is driven by the [Engine](crate::Engine). For
/// example, a [MinimalAppDriver] may contain the simple logic of driving [EngineStage] transitions,
/// whereas a [WinitDriver][winit] can contain the full logic of driving a window-based event loop.
///
/// The engine provides several useful [AppDriver] implementations, including the following:
/// * [MinimalAppDriver] - Minimal logic to drive an [Application]. No GUI.
/// * [WinitDriver][winit] - Full GUI support using a windowing event loop provided by
/// [Winit](https://docs.rs/winit/latest/winit/).
///
/// [winit]: crate::gui::window::winit::WinitDriver
///
/// # Implementation
///
/// If the engine provided implementations don't fit your use-case, you can also implement your own.
/// Certain patterns should be followed when implementing your own AppDriver.
///
/// ## Application lifecycle
///
/// Any implementation of AppDriver should adhere to the following lifecycle contraints:
/// * [Application::init()] should be executed once per engine [initialization](EngineStage::Init).
/// * [Application::resume()] should be executed once per [resume cycle](EngineStage::Resuming),
/// where the engine transitions from [Suspended](EngineStage::Suspended) to
/// [Running](EngineStage::Running).
/// * [Application::suspend()] should be executed once per [suspend cycle](EngineStage::Suspending),
/// where the engine transitions from [Running](EngineStage::Running) to
/// [Suspended](EngineStage::Suspended).
/// * [Application::terminate()] should be executed once per engine
/// [termination](EngineStage::Stopping), at the very end of an application's lifecycle.
///
/// The implementation is also responsible for transitioning engine [stages](EngineStage) as
/// appropriate, using [EngineState::set_stage()]. For example, if the [Engine](crate::Engine)
/// begins terminating, it will be put into [EngineStage::Stopping]. It is up to the AppDriver to
/// recognize this, perform the necessary actions (such as executing [Application::terminate()]),
/// and then set the [EngineStage] to [Stopped](EngineStage::Stopped).
/// Minimal implementation of [AppDriver].
///
/// This implementation performs the minimal logic required to execute an engine lifecycle. It will
/// call [Application::init()] when the engine starts, and [Application::terminate()] when the
/// engine stops, as well as transition the [EngineStage] as needed. It does *not* support engine
/// [suspension stages](EngineStage::Suspended), and as such will not execute the
/// [Application::suspend()] or [Application::resume()] hooks.