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"
|
||||
},
|
||||
// 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">
|
||||
<h1>Slides</h1>
|
||||
<p>Here you can find a list of all available slides:</p>
|
||||
<h1>Слайды</h1>
|
||||
<p>Список всех доступных слайдов:</p>
|
||||
{
|
||||
slides.map((slide) => (
|
||||
<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