---
description: A simple guide through the concepts behind solstack.
---

# Cheatsheet

## Core Concepts

There's really only three things you should care about in `solstack`: `State`s, `Tran`s and the `Stack`.



A `State` represents what your program should run at that moment. A `MainMenu` state does not render the player in a game; it renders options and pushes other relevant states on top of itself if the correct inputs are provided, or even quits the application entirely.

> Take a look at the previous chapter **Use Case** for understanding a typical application flow in `solstack`.

A `Stack` is a type that holds a list of `State`s. When the stack's `tick` method is called, it looks for the topmost state it holds and executes its methods (namely `on_tick` and `on_shadow_tick`). This way, only the topmost state in a stack is run at a time; while the others are effectively `paused`.

> In v0.3.0 we introduced the concept of a `shadow_tick`. The `Stack` now, when ticked, will execute the method `on_shadow_tick` of **every single state it holds**. It can simply be ignored, of course.

A `Trans` represents a transition between `State`s on a `Stack`. You can perform this **directly** through the `Stack`s methods (namely `push`, `pop`, `quit`, `none`, etc.). But the most useful way is through **returning** a `Trans` on the `State`s `on_update` and/or `on_shadow_update`. Returning allows you to easily code conditional transitions, like _if the player presses `Esc`, push the `PauseMenu` state_.



## Modeling an Application

* Bring the important stuff into scope.

```rust
// State, Trans and Stack
use solstack::prelude::*;
// optional macros for cleaner code (i'll use both ways so you can choose)
use solstack::macros::*;  
```

* Create an **application data type** that will hold important information. This will be shared mutably by all of your states.

```rust
#[derive(Default)] // optional
struct AppData {
    // important data for your app
    name: String,
    age: i32,
}
```

* Create some states.

```rust
struct Menu;        // the main menu.
struct PromptName;  // prompts the user for their name (stores in AppData).
struct PromptAge;   // prompts the user for their age (stores in AppData).
struct Greet;       // prints a greeting to the user and their age (reads from AppData).
```

* Implement `State` for your states.

```rust
impl State<AppData> for Menu {
    fn on_start(&mut self, _data: &mut AppData) {}
    fn on_stop(&mut self, _data: &mut AppData) {}
    fn on_pause(&mut self, _data: &mut AppData) {}
    fn on_resume(&mut self, _data: &mut AppData) {}

    fn on_tick(&mut self, _data: &mut AppData) -> Trans<AppData> { 
        Trans::None
    }

    fn on_shadow_tick(&mut self, _data: &mut AppData) -> Trans<AppData> {
        Trans::None
    }
}
```

> Your IDE might bring the `data` parameter on the methods as `_data`. This tells rust it's not currently being used. If you're going to use it, change it do `data`.

> All of the methods are documented below in **Callbacks** and in the crate's docs.
>
> All of the `Trans`itions are documented below in **Transition** and in the crate's docs.

* Instatiate your data and a new stack; set up a loop.

```rust
fn main() {
    let data = AppData::default();
    let stack = Stack::<AppData>::new();
    
    // push at least one state directly, otherwise `is_running` will immediately 
    // return false.
    stack.push(&mut data, Box::new(Menu));
    // or stack_push!(stack, data, Menu);
    
    while stack.is_running() { // keeps going until there are no states inside.
        stack.tick(&mut data);
        // or stack_tick!(stack, data);
    }

```

> If you are goin to use `is_running`, make sure that eventually at least one of your states requests for a `Trans::Quit`. Otherwise you'll have an infinite loop. If you need your ticks to be called, for instance, 60 times/frames per second, you'd do that logic here. The `solstack` lib won't opinate on how or how often to `tick`, though `feature`s are planned for that.

### Callbacks

<table><thead><tr><th width="214">METHOD</th><th width="389.33333333333326">DESCRIPTION</th><th>TRANS</th></tr></thead><tbody><tr><td><code>on_start</code></td><td>Called when this <a href="https://docs.rs/solstack/latest/solstack/state/trait.State.html"><code>State</code></a> first enters the stack.</td><td>no</td></tr><tr><td><code>on_stop</code></td><td>Called when this <a href="https://docs.rs/solstack/latest/solstack/state/trait.State.html"><code>State</code></a> is popped from the stack.</td><td>no</td></tr><tr><td><code>on_pause</code></td><td>Called when this <a href="https://docs.rs/solstack/latest/solstack/state/trait.State.html"><code>State</code></a> loses its topmost position in the stack to another <a href="https://docs.rs/solstack/latest/solstack/state/trait.State.html"><code>State</code></a> that has been pushed on top of it.</td><td>no</td></tr><tr><td><code>on_resume</code></td><td>Called when this <a href="https://docs.rs/solstack/latest/solstack/state/trait.State.html"><code>State</code></a> regains the first position in the stack. Id est, when other <a href="https://docs.rs/solstack/latest/solstack/state/trait.State.html"><code>State</code></a>s above it are popped.</td><td>no</td></tr><tr><td><code>on_tick</code></td><td>Represents a single tick/update. It’s called when the <a href="https://docs.rs/solstack/latest/solstack/stack/struct.Stack.html"><code>Stack</code></a>’s <code>.tick()</code> is called. Your loop logic should call your stack’s tick, not this directly.</td><td>yes</td></tr><tr><td><code>on_shadow_tick</code></td><td><p>Represents a single tick/update independent of this <a href="https://docs.rs/solstack/latest/solstack/state/trait.State.html"><code>State</code></a> position in the stack. It’s called when the <a href="https://docs.rs/solstack/latest/solstack/stack/struct.Stack.html"><code>Stack</code></a>’s <code>.tick()</code> is called.</p><p></p><p><em>NOTE: <code>on_shadow_tick</code> is called BEFORE <code>on_tick</code>.</em></p></td><td>yes</td></tr></tbody></table>

> The methods marked as `TRANS` **requires** returning a `Trans` (see how at the chapter below **Transitions**.

## Transitions

<table><thead><tr><th width="258">TRANSITION</th><th width="196.33333333333331">CALLS</th><th>DESCRIPTION</th></tr></thead><tbody><tr><td><code>Push(Box&#x3C;State&#x3C;D>>)</code></td><td><code>stack.push</code><br><code>stack_push!</code><br><code>trans_push!</code><br><code>Trans::Push</code></td><td>Pushes a new state above the current one. Effectively pauses the current state until everything above it is popped.</td></tr><tr><td><code>Pop</code></td><td><code>stack.pop</code><br><code>stack_pop!</code><br><code>trans_pop!</code><br><code>Trans::Pop</code></td><td>Pops the current state from the stack.</td></tr><tr><td><code>Replace&#x3C;Box&#x3C;State&#x3C;D>></code></td><td><code>stack.replace</code><br><code>stack_replace!</code><br><code>trans_replace!</code><br><code>Trans::Replace</code></td><td>Pops and pushes a new state. Effectively replaces the current state with a new one.</td></tr><tr><td><code>Isolate&#x3C;Box&#x3C;State&#x3C;D>></code></td><td><code>stack.isolate</code><br><code>stack_isolate!</code><br><code>trans_isolate!</code><br><code>Trans::Isolate</code></td><td>Pops every state from the stack and pushes a new one. Effectively isolates it as the only state on the stack.</td></tr><tr><td><code>Quit</code></td><td><code>stack.quit</code><br><code>stack_quit!</code><br><code>trans_quit!</code><br><code>Trans::Quit</code></td><td>Pops everything from the stack. Effectively ends the state stack machine.</td></tr><tr><td><code>None</code></td><td><code>trans_none!</code><br><code>Trans::None</code></td><td>Does nothing to the stack. Effectively keeps the current state and the stack the way it is.</td></tr><tr><td><em>Stack Ticking</em><br><em>(Not a Transition)</em></td><td><code>stack.tick</code><br><code>stack_tick!</code></td><td>Ticks the current (topmost at the stack) state once and performs any necessary transitions. Also ticks every state's shadow tick and performs their transitions.</td></tr></tbody></table>

