chore(*): add all
This commit is contained in:
parent
8f90133e1e
commit
97977d44d8
7
.vscode/settings.json
vendored
7
.vscode/settings.json
vendored
@ -5,5 +5,10 @@
|
|||||||
"strings": "on"
|
"strings": "on"
|
||||||
},
|
},
|
||||||
// prioritize ArkType's "type" for autoimports
|
// prioritize ArkType's "type" for autoimports
|
||||||
"typescript.preferences.autoImportSpecifierExcludeRegexes": ["^(node:)?os$"]
|
"typescript.preferences.autoImportSpecifierExcludeRegexes": [
|
||||||
|
"^(node:)?os$"
|
||||||
|
],
|
||||||
|
"[astro]": {
|
||||||
|
"editor.defaultFormatter": "astro-build.astro-vscode"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
60
example/server.cjs
Executable file
60
example/server.cjs
Executable file
@ -0,0 +1,60 @@
|
|||||||
|
#!/usr/bin/env node
|
||||||
|
|
||||||
|
const http = require('http');
|
||||||
|
|
||||||
|
// Конфигурация приложения
|
||||||
|
let debugMode = false;
|
||||||
|
|
||||||
|
// Создаем HTTP-сервер
|
||||||
|
const server = http.createServer((req, res) => {
|
||||||
|
res.end(`Debug mode: ${debugMode ? 'ON' : 'OFF'}`);
|
||||||
|
});
|
||||||
|
|
||||||
|
// Graceful shutdown
|
||||||
|
const gracefulShutdown = (signal) => {
|
||||||
|
console.log(`\nReceived ${signal}. Closing server...`);
|
||||||
|
|
||||||
|
server.close(() => {
|
||||||
|
console.log('All connections closed. Exiting.');
|
||||||
|
process.exit(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
setTimeout(() => {
|
||||||
|
console.error('Forcing shutdown after 5 seconds!');
|
||||||
|
process.exit(1);
|
||||||
|
}, 5000);
|
||||||
|
};
|
||||||
|
|
||||||
|
// Обработчики сигналов
|
||||||
|
process.on('SIGINT', () => gracefulShutdown('SIGINT (Ctrl+C)')); // Terminal interrupt
|
||||||
|
process.on('SIGTERM', () => gracefulShutdown('SIGTERM')); // Default kill signal
|
||||||
|
process.on('SIGHUP', () => { // Hangup
|
||||||
|
console.log('\nReceived SIGHUP. Reloading configuration...');
|
||||||
|
// Здесь можно перечитать конфиги
|
||||||
|
});
|
||||||
|
|
||||||
|
// Пользовательские сигналы
|
||||||
|
// Выключен для демонстрации поведения встроенного дебаггера
|
||||||
|
// теперь при перехвате SIGUSR1, дебаггер не будет активирован
|
||||||
|
/*
|
||||||
|
process.on('SIGUSR1', () => { // User-defined 1
|
||||||
|
debugMode = true;
|
||||||
|
console.log('\nDebug mode activated (SIGUSR1)');
|
||||||
|
});
|
||||||
|
*/
|
||||||
|
|
||||||
|
process.on('SIGUSR2', () => { // User-defined 2
|
||||||
|
debugMode = false;
|
||||||
|
console.log('\nDebug mode deactivated (SIGUSR2)');
|
||||||
|
});
|
||||||
|
|
||||||
|
// Запуск сервера
|
||||||
|
server.listen(3003, () => {
|
||||||
|
const pid = process.pid;
|
||||||
|
console.log(`Server started. PID: ${pid}`);
|
||||||
|
console.log('Test commands:');
|
||||||
|
console.log(` Kill with SIGTERM: kill -TERM ${pid}`);
|
||||||
|
console.log(` Toggle debug mode: kill -USR1 ${pid} / kill -USR2 ${pid}`);
|
||||||
|
console.log(` Force kill: kill -9 ${pid}`);
|
||||||
|
console.log('Endpoint: curl http://localhost:3003');
|
||||||
|
});
|
||||||
3733
pnpm-lock.yaml
generated
3733
pnpm-lock.yaml
generated
File diff suppressed because it is too large
Load Diff
@ -8,8 +8,8 @@ const slides = getSlides()
|
|||||||
---
|
---
|
||||||
|
|
||||||
<Layout title="Home">
|
<Layout title="Home">
|
||||||
<h1>Slides</h1>
|
<h1>Слайды</h1>
|
||||||
<p>Here you can find a list of all available slides:</p>
|
<p>Список всех доступных слайдов:</p>
|
||||||
{
|
{
|
||||||
slides.map((slide) => (
|
slides.map((slide) => (
|
||||||
<a href={`/${slide.id}`}>
|
<a href={`/${slide.id}`}>
|
||||||
|
|||||||
@ -1,107 +0,0 @@
|
|||||||
<script lang="ts">
|
|
||||||
import type { Snippet } from "svelte";
|
|
||||||
|
|
||||||
type CSSPropertyDemoProps = {
|
|
||||||
property: string;
|
|
||||||
values: string[];
|
|
||||||
title?: string;
|
|
||||||
defaultValue?: string;
|
|
||||||
children?: Snippet<[]>;
|
|
||||||
};
|
|
||||||
|
|
||||||
const {
|
|
||||||
property,
|
|
||||||
values,
|
|
||||||
title = property,
|
|
||||||
defaultValue = values[0],
|
|
||||||
}: CSSPropertyDemoProps = $props();
|
|
||||||
|
|
||||||
let selected = $state(defaultValue);
|
|
||||||
|
|
||||||
const handleClick = (value: string) => {
|
|
||||||
selected = value;
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
|
|
||||||
<div class="flex-property-demo">
|
|
||||||
<h2 class="flex-property-demo__property">{title}</h2>
|
|
||||||
<div class="flex-property-demo__values">
|
|
||||||
{#if values.length > 1}
|
|
||||||
{#each values as value}
|
|
||||||
<button
|
|
||||||
class="flex-property-demo__value"
|
|
||||||
onclick={() => handleClick(value)}
|
|
||||||
class:selected={selected === value}
|
|
||||||
>
|
|
||||||
{value}
|
|
||||||
</button>
|
|
||||||
{/each}
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
<div class="flex-property-demo__children" style={`${property}: ${selected}`}>
|
|
||||||
{#each [1, 2, 3] as index}
|
|
||||||
<div class="flex-property-demo__box">{index}</div>
|
|
||||||
{/each}
|
|
||||||
</div>
|
|
||||||
<pre>
|
|
||||||
<code data-trim data-noescape>
|
|
||||||
.container {"{"}
|
|
||||||
{property}: {selected};
|
|
||||||
{"}"}
|
|
||||||
</code>
|
|
||||||
</pre>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<style>
|
|
||||||
.flex-property-demo {
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
align-items: stretch;
|
|
||||||
gap: var(--base-spacing);
|
|
||||||
}
|
|
||||||
|
|
||||||
.flex-property-demo__children {
|
|
||||||
display: flex;
|
|
||||||
margin: 20px;
|
|
||||||
padding: 20px;
|
|
||||||
border: 2px solid #fff;
|
|
||||||
min-height: 200px;
|
|
||||||
}
|
|
||||||
|
|
||||||
button {
|
|
||||||
color: white;
|
|
||||||
background-color: black;
|
|
||||||
border: 2px solid white;
|
|
||||||
font-weight: bold;
|
|
||||||
padding: 10px;
|
|
||||||
cursor: pointer;
|
|
||||||
transition: all 0.3s ease;
|
|
||||||
}
|
|
||||||
|
|
||||||
button.selected,
|
|
||||||
button:hover {
|
|
||||||
background-color: white;
|
|
||||||
color: black;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flex-property-demo__box {
|
|
||||||
width: 100px;
|
|
||||||
height: 100px;
|
|
||||||
background: #4a9eff;
|
|
||||||
margin: 10px;
|
|
||||||
display: flex;
|
|
||||||
align-items: center;
|
|
||||||
justify-content: center;
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.flex-property-demo__values {
|
|
||||||
display: flex;
|
|
||||||
gap: var(--base-spacing);
|
|
||||||
align-self: center;
|
|
||||||
}
|
|
||||||
|
|
||||||
pre {
|
|
||||||
margin: 0;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
@ -1,52 +0,0 @@
|
|||||||
---
|
|
||||||
import CSSPropertyDemo from "./components/CSSPropertyDemo.svelte";
|
|
||||||
|
|
||||||
export const title = "CSS Flexbox";
|
|
||||||
export const authors = ["Henrique Ramos"];
|
|
||||||
export const publishedAt = "2025-01-27";
|
|
||||||
export const description = "Do you even flex?";
|
|
||||||
export const draft = true;
|
|
||||||
---
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<h2>What is Flexbox?</h2>
|
|
||||||
<ul>
|
|
||||||
<li>One-dimensional layout model</li>
|
|
||||||
<li>Distributes space along a single direction</li>
|
|
||||||
<li>Powerful alignment capabilities</li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<CSSPropertyDemo
|
|
||||||
title="Simple Flexbox Container"
|
|
||||||
client:load
|
|
||||||
property="display"
|
|
||||||
values={["flex"]}
|
|
||||||
/>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<CSSPropertyDemo
|
|
||||||
client:load
|
|
||||||
property="justify-content"
|
|
||||||
values={["flex-start", "center", "flex-end", "space-between", "space-around", "space-evenly"]}
|
|
||||||
/>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<CSSPropertyDemo
|
|
||||||
client:load
|
|
||||||
property="align-items"
|
|
||||||
values={["flex-start", "center", "flex-end", "stretch"]}
|
|
||||||
/>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<CSSPropertyDemo
|
|
||||||
client:load
|
|
||||||
property="flex-direction"
|
|
||||||
values={["row", "row-reverse", "column", "column-reverse"]}
|
|
||||||
/>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
182
src/slides/signals/index.astro
Normal file
182
src/slides/signals/index.astro
Normal file
@ -0,0 +1,182 @@
|
|||||||
|
---
|
||||||
|
export const title = "Сигналы в Linux и их применение в Node.js";
|
||||||
|
export const authors = ["Карпич Дмитрий"];
|
||||||
|
export const publishedAt = "2025-05-28";
|
||||||
|
export const description =
|
||||||
|
"Cигналы, их типы и как они используются в Node.js для управления процессами и обработки событий.";
|
||||||
|
---
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<section>
|
||||||
|
<h2>Что такое сигналы?</h2>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<strong>Определение:</strong> сигналы в Unix-подобных системах - это асинхронные
|
||||||
|
события, которые могут быть отправлены процессу операционной системы или
|
||||||
|
другому процессу.
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<strong>Аналогия:</strong> сигналы можно сравнить с "уведомлениями" для процессов
|
||||||
|
(например, "завершись", "приостановись").
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<strong>Примеры ситуаций:</strong> приостановка процесса с помощью команды
|
||||||
|
Ctrl+Z, команда Ctrl+C, завершение процесса, ошибка сегментации и т.п.
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<section>
|
||||||
|
<h2>Типы сигналов</h2>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<strong>Сигналы по умолчанию:</strong> SIGINT, SIGTERM, SIGKILL, SIGSTOP
|
||||||
|
и т.д.
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<strong>Сигналы пользовательских действий:</strong> SIGUSR1, SIGUSR2.
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<strong>Сигналы от системных ошибок:</strong> SIGSEGV, SIGFPE, SIGPIPE и
|
||||||
|
т.д.
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<section>
|
||||||
|
<h2>Отправка сигналов процессам</h2>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h2>Команда kill</h2>
|
||||||
|
<p>используется для отправки сигналов процессу.</p>
|
||||||
|
<pre><code data-trim class="language-bash">kill -SIGINT 1234</code></pre>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<h2>Команда killall</h2>
|
||||||
|
<p>
|
||||||
|
используется для отправки сигналов всем процессам с определенным
|
||||||
|
именем.
|
||||||
|
</p>
|
||||||
|
<pre><code data-trim class="language-bash">killall -SIGTERM myprocess</code></pre>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>Команда pkill</h2>
|
||||||
|
<p>
|
||||||
|
используется для отправки сигналов процессам, соответствующим
|
||||||
|
определенному шаблону.
|
||||||
|
</p>
|
||||||
|
<pre><code data-trim class="language-bash">pkill -SIGKILL myprocess</code></pre>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<section>
|
||||||
|
<h2>Некоторые сигналы в Linux</h2>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<ul>
|
||||||
|
<li>
|
||||||
|
<strong>SIGHUP (1)</strong> — потеря соединения с управляющим терминалом
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>SIGINT (2)</strong> — прерывание процесса с клавиатуры (Ctrl+C)
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>SIGQUIT (3)</strong> — аварийное завершение
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>SIGABRT (6)</strong> — аварийная остановка процесса
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>SIGKILL (9)</strong> — немедленное завершение (не блокируется)
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>SIGTERM (15)</strong> — стандартный сигнал для завершения
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
<strong>SIGSTOP (17,19,23)</strong> — приостановка процесса до SIGCONT
|
||||||
|
</li>
|
||||||
|
</ul>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<section>
|
||||||
|
<h2>Обработка сигналов в node.js</h2>
|
||||||
|
</section>
|
||||||
|
<section>
|
||||||
|
<p>
|
||||||
|
В Node.js можно обрабатывать сигналы с помощью модуля <code
|
||||||
|
>process</code
|
||||||
|
>.
|
||||||
|
</p>
|
||||||
|
|
||||||
|
<pre><code data-trim class="language-javascript">
|
||||||
|
{`process.on('SIGINT', () => {
|
||||||
|
console.log('Received SIGINT. Exiting...');
|
||||||
|
process.exit(0);
|
||||||
|
});`}
|
||||||
|
</code></pre>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<section>
|
||||||
|
<h2>Зачем перехватывать сигналы в Node.js?</h2>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h3>Graceful Shutdown</h3>
|
||||||
|
<p>
|
||||||
|
Корректное завершение работы: закрытие соединений с БД, остановка
|
||||||
|
HTTP-сервера перед выходом.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h3>Кастомизация поведения</h3>
|
||||||
|
<p>
|
||||||
|
Выполнение кастомной логики перед завершением: логирование, отправка
|
||||||
|
метрик, уведомления.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h3>Игнорирование сигналов</h3>
|
||||||
|
<p>
|
||||||
|
Предотвращение завершения процесса по умолчанию (например, для
|
||||||
|
фоновых демонов).
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h3>Перезагрузка конфигурации</h3>
|
||||||
|
<p>
|
||||||
|
Обновление настроек приложения без перезапуска (по сигналу SIGHUP).
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h3>Обработка ошибок</h3>
|
||||||
|
<p>
|
||||||
|
Cleanup при аварийных ситуациях: освобождение ресурсов, сохранение
|
||||||
|
состояния.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h3>Интеграция с оркестраторами</h3>
|
||||||
|
<p>
|
||||||
|
Корректная реакция на сигналы от Docker/Kubernetes (например,
|
||||||
|
SIGTERM при остановке контейнера).
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
|
</section>
|
||||||
|
|
||||||
|
<section>
|
||||||
|
<h2>Демонстрация тестового кода с перехватом основных сигналов</h2>
|
||||||
|
<p>
|
||||||
|
Переходим к коду.
|
||||||
|
</p>
|
||||||
|
</section>
|
||||||
@ -1,150 +0,0 @@
|
|||||||
---
|
|
||||||
export const title =
|
|
||||||
"Finite State Machines with XState for Game Development using Three.js";
|
|
||||||
export const authors = ["Henrique Ramos"];
|
|
||||||
export const publishedAt = "2024-12-13";
|
|
||||||
export const description =
|
|
||||||
"Using XState Finite State Machines to coordinate character actions in a Three.js game";
|
|
||||||
---
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<section>
|
|
||||||
<h2>What is a Finite State Machine (FSM)?</h2>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
A mathematical model of computation that consists of a set of states and
|
|
||||||
transitions between those states.
|
|
||||||
</li>
|
|
||||||
<li>Used to represent systems with a finite number of states.</li>
|
|
||||||
<li>Well-suited for modeling complex game behaviors.</li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>Visualizing FSMs</h2>
|
|
||||||
<iframe
|
|
||||||
title="Stately.AI FSM visualization"
|
|
||||||
src="https://stately.ai/registry/editor/embed/f135a841-e83d-4bdc-8a86-9ebe0f8ff3cd?machineId=9e9d23aa-1c58-44a7-a20d-538fc7017e37"
|
|
||||||
width="1000"
|
|
||||||
height="600"
|
|
||||||
></iframe>
|
|
||||||
</section>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>Why use FSMs in Game Development?</h2>
|
|
||||||
<ul>
|
|
||||||
<li>Improve code organization and readability.</li>
|
|
||||||
<li>Facilitate easier testing and debugging.</li>
|
|
||||||
<li>Enable more flexible and reactive game behaviors.</li>
|
|
||||||
<li>Promote code reusability.</li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<h2>Introducing XState</h2>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
A powerful and flexible state chart library for building complex state
|
|
||||||
machines.
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Well-suited for game development due to its visual state charts and
|
|
||||||
hierarchical state machines.
|
|
||||||
</li>
|
|
||||||
<li>Provides a declarative approach to state machine design.</li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<h2>Key Features of XState</h2>
|
|
||||||
<ul>
|
|
||||||
<li>Visual state charts for intuitive design.</li>
|
|
||||||
<li>Hierarchical state machines for complex behaviors.</li>
|
|
||||||
<li>Context and actions for managing state data and side effects.</li>
|
|
||||||
<li>Guards and conditions for controlling transitions.</li>
|
|
||||||
<li>Parallel states for concurrent behaviors.</li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<h2>Integrating XState with Three.js</h2>
|
|
||||||
<ul>
|
|
||||||
<li>Create a Three.js scene and renderer.</li>
|
|
||||||
<li>Define game objects and their initial states.</li>
|
|
||||||
<li>Initialize an XState machine to manage the game's overall state.</li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<h2>Mapping XState States to Game Objects</h2>
|
|
||||||
<ul>
|
|
||||||
<li>Use XState's context to store references to game objects.</li>
|
|
||||||
<li>Define actions to update game object properties and behaviors.</li>
|
|
||||||
<li>Trigger state transitions based on game events or conditions.</li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<h2>Handling Game Events and Input</h2>
|
|
||||||
<ul>
|
|
||||||
<li>Listen for user input events (e.g., keyboard, mouse, gamepad).</li>
|
|
||||||
<li>
|
|
||||||
Use XState's
|
|
||||||
<code>send</code>
|
|
||||||
function to trigger state transitions based on input.
|
|
||||||
</li>
|
|
||||||
<li>Update game object states and behaviors accordingly.</li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<h2>Advanced Techniques</h2>
|
|
||||||
<ul>
|
|
||||||
<li>Parallel States</li>
|
|
||||||
<li>History States</li>
|
|
||||||
<li>Delay Transitions</li>
|
|
||||||
<li>Custom Guards and Conditions</li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<h2>Conclusion</h2>
|
|
||||||
|
|
||||||
By leveraging XState, you can create more robust, flexible, and maintainable
|
|
||||||
game behaviors. XState's powerful features and intuitive state chart design
|
|
||||||
make it an excellent choice for game development using Three.js.
|
|
||||||
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>Finite State Machine</h2>
|
|
||||||
<iframe
|
|
||||||
height="600"
|
|
||||||
width="1000"
|
|
||||||
title="HNRQ.dev character FSM"
|
|
||||||
src="https://stately.ai/registry/editor/embed/d947654c-2a61-4870-bc38-d34a5224ea00?machineId=b2a3771b-2530-4ce7-9f71-380eee380537"
|
|
||||||
></iframe>
|
|
||||||
</section>
|
|
||||||
<section>
|
|
||||||
<h2>FSM in action</h2>
|
|
||||||
<iframe src="https://hnrq.dev" title="HNRQ.dev" height="600" width="1000"></iframe>
|
|
||||||
<small>Available at <a href="https://hnrq.dev">hnrq.dev</a></small>
|
|
||||||
</section>
|
|
||||||
|
|
||||||
<section>
|
|
||||||
<h2>References</h2>
|
|
||||||
<ul>
|
|
||||||
<li>
|
|
||||||
XState Documentation:
|
|
||||||
<a href="https://xstate.js.org/">https://xstate.js.org/</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Three.js Documentation:
|
|
||||||
<a href="https://threejs.org/">https://threejs.org/</a>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
Finite State Machines:
|
|
||||||
<a href="https://en.wikipedia.org/wiki/Finite-state_machine"
|
|
||||||
>https://en.wikipedia.org/wiki/Finite-state_machine</a
|
|
||||||
>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</section>
|
|
||||||
Loading…
x
Reference in New Issue
Block a user