Use Rust project templates as basis for current tutorial (#4488)

Uses the Rust project template to refactor the tutorial and numerous grammar and language changes.
This commit is contained in:
Chris Chinchilla 2024-02-02 16:55:11 +01:00 committed by GitHub
parent 858ed639ec
commit ba98a89e9b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
12 changed files with 169 additions and 139 deletions

View file

@ -1,44 +1,48 @@
<!-- Copyright © SixtyFPS GmbH <info@slint.dev> ; SPDX-License-Identifier: MIT -->
# Game Logic In Rust
We'll implement the rules of the game in Rust as well. The general philosophy of Slint is that merely the user
interface is implemented in the `.slint` language and the business logic in your favorite programming
language. The game rules shall enforce that at most two tiles have their curtain open. If the tiles match, then we
consider them solved and they remain open. Otherwise we wait for a little while, so the player can memorize
the location of the icons, and then close them again.
This step implements the rules of the game in Rust as well.
We'll modify the `.slint` markup inside the `slint!` macro to signal to the Rust code when the user clicks on a tile.
Two changes to <span class="hljs-title">MainWindow</span> are needed: We need to add a way for the MainWindow to call to the Rust code that it should
check if a pair of tiles has been solved. And we need to add a property that Rust code can toggle to disable further
tile interaction, to prevent the player from opening more tiles than allowed. No cheating allowed! First, we paste
the callback and property declarations into <span class="hljs-title">MainWindow</span>:
Slint's general philosophy is that you implement the user interface in Slint and the business logic in your favorite programming
language.
The game rules enforce that at most two tiles have their curtain open. If the tiles match, then the game
considers them solved and they remain open. Otherwise, the game waits briefly so the player can memorize
the location of the icons, and then closes the curtains again.
Add the following code inside the <span class="hljs-title">MainWindow</span> component to signal to the Rust code when the user clicks on a tile.
```slint
{{#include main_game_logic_in_rust.rs:mainwindow_interface}}
```
The last change to the `.slint` markup is to act when the <span class="hljs-title">MemoryTile</span> signals that it was clicked on.
We add the following handler in <span class="hljs-title">MainWindow</span>:
This change adds a way for the <span class="hljs-title">MainWindow</span> to call to the Rust code that it should
check if a player has solved a pair of tiles. The Rust code needs an additional property to toggle to disable further
tile interaction, to prevent the player from opening more tiles than allowed. No cheating allowed!
The last change to the code is to act when the <span class="hljs-title">MemoryTile</span> signals that a player clicked it.
Add the following handler in <span class="hljs-title">MainWindow</span>:
```slint
{{#include main_game_logic_in_rust.rs:tile_click_logic}}
```
On the Rust side, we can now add an handler to the `check_if_pair_solved` callback, that will check if
two tiles are opened. If they match, the `solved` property is set to true in the model. If they don't
match, start a timer that will close them after one second. While the timer is running, we disable every tile so
one can't click anything during this time.
On the Rust side, you can now add a handler to the `check_if_pair_solved` callback, that checks if a player opened two tiles.
If they match, the code sets the `solved` property to true in the model. If they don't
match, start a timer that closes the tiles after one second. While the timer is running, disable every tile so
a player can't click anything during this time.
Insert this code before the `main_window.run()` call:
Add this code before the `main_window.run().unwrap();` call:
```rust,noplayground
{{#include main_game_logic_in_rust.rs:game_logic}}
```
Notice that we take a [Weak](https://slint.dev/docs/rust/slint/struct.Weak) pointer of our `main_window`. This is very
important because capturing a copy of the `main_window` itself within the callback handler would result in a circular ownership.
The code uses a [Weak](https://slint.dev/docs/rust/slint/struct.Weak) pointer of the `main_window`. This is
important because capturing a copy of the `main_window` itself within the callback handler would result in circular ownership.
The `MainWindow` owns the callback handler, which itself owns a reference to the `MainWindow`, which must be weak
instead of strong to avoid a memory leak.
These were the last changes and running the result gives us a window on the screen that allows us
to play the game by the rules.
These were the last changes and running the code opens a window that allows a player to play the game by the rules.