Skip to content

Latest commit

 

History

History
175 lines (120 loc) · 10.7 KB

File metadata and controls

175 lines (120 loc) · 10.7 KB

Rust Laboratory: Signal Zero — API مرجع Tauri

وضعیت: API داخلیِ پایدار برای رابط فعلی دسکتاپ
مخاطب: توسعه‌دهندگان رابط، test harnessها و مشارکت‌کنندگان Rust/Tauri
ورود اصلی: src-tauri/src/main.rs

1. محدوده و شیوهٔ فراخوانی

رابط برنامه با فرمان‌های Rust که در tauri::generate_handler! ثبت شده‌اند ارتباط برقرار می‌کند. در Tauri، invoke() یک Promise برمی‌گرداند و داده‌های قابل‌سریال‌سازی را بین JavaScript و Rust ردوبدل می‌کند. 1 تمام فرمان‌های این پروژه به state درون‌پردازه‌ای GameState(Mutex<GameEngine>) دسترسی دارند؛ بنابراین فرمان‌های تغییردهندهٔ وضعیت باید به‌ترتیب منطقی بازی فراخوانی شوند.

import { invoke } from '@tauri-apps/api/core';

const initialState = await invoke('initialize_game');
const nextState = await invoke('send_command', { command: 'take keycard' });

نکتهٔ نام‌گذاری: نام فرمان‌ها همان نام ثبت‌شده در src-tauri/src/main.rs است. آرگومان‌ها در این API تک‌واژه و سازگار با JavaScript هستند: command، slot، config و partial. هنگام افزودن نام‌های چندکلمه‌ای، قرارداد camelCase را در frontend ثابت نگه دارید؛ Tauri به‌طور پیش‌فرض آرگومان‌های JavaScript را با کلید camelCase می‌پذیرد. 1

2. چرخهٔ عمر session

مرحله فرمان اثر کاربرد صحیح
شروع پروندهٔ جدید initialize_game Engine را reset می‌کند و متن آغازین را بازمی‌گرداند فقط زمانی که کاربر «New Game» را انتخاب کرده است
خواندن session فعلی get_game_state state فعلی را بدون reset و بدون متن آغازین جدید برمی‌گرداند پس از load یا refresh UI
اجرای اقدام send_command یک فرمان متنی را پردازش و state به‌روز را بازمی‌گرداند برای حرکت، برداشتن آیتم، حل معما و غیره
بارگذاری load_game سپس get_game_state state ذخیره‌شده را جایگزین می‌کند؛ فرمان دوم آن را نمایش‌پذیر می‌کند هیچ‌گاه پس از load، initialize_game را فراخوانی نکنید

3. مرجع فرمان‌ها

initialize_game() -> GameResponse

یک بازی تازه می‌سازد، جهان، آیتم‌ها، معماها و achievementها را مقداردهی می‌کند و state کامل با پیام‌های intro را بازمی‌گرداند.

const game = await invoke('initialize_game');
console.log(game.current_room.name);

get_game_state() -> GameResponse

تصویر فعلی بازی را بدون تغییر دادن پیشرفت بازمی‌گرداند. فیلد messages در این فراخوانی خالی است، مگر آنکه در نسخهٔ آینده قرارداد آن صریحاً تغییر کند.

const game = await invoke('get_game_state');
renderGameState(game);

send_command({ command: string }) -> GameResponse

یک فرمان بازی را پردازش و پیام‌های تولیدشده، نقشه، inventory و وضعیت بازیکن را برمی‌گرداند. فرمان‌های پشتیبانی‌شده شامل look، جهت‌ها مانند north، take، drop، use، inventory، examine، read، solve، map، status، hint و restart هستند.

const game = await invoke('send_command', { command: 'take keycard' });
const hasError = game.messages.some((message) => message.msg_type === 'Error');

save_game({ slot: number }) -> CommandResult

state فعلی را در slot ذخیره می‌کند. رابط استاندارد سه slot صفر، یک و دو را نمایش می‌دهد. consumer باید همیشه success را بررسی کند؛ خطای ذخیره در message بازگردانده می‌شود، نه به‌صورت exception قابل‌اتکا.

const result = await invoke('save_game', { slot: 0 });
if (!result.success) showNotification(result.message, true);

load_game({ slot: number }) -> CommandResult

یک slot را در Engine فعلی بارگذاری می‌کند. پس از پاسخ موفق، get_game_state() را فراخوانی کنید تا رابط از state جدید رسم شود.

const result = await invoke('load_game', { slot: 0 });
if (result.success) renderGameState(await invoke('get_game_state'));

get_save_slots() -> SaveSlotInfo[]

فهرست metadata slotها را برای صفحهٔ load/save برمی‌گرداند. این فرمان وضعیت بازی را تغییر نمی‌دهد.

delete_save({ slot: number }) -> CommandResult

فایل slot انتخاب‌شده را حذف می‌کند. پیش از فراخوانی، confirmation رابط کاربر لازم است زیرا عملیات بازگشت‌ناپذیر است.

get_config() -> GameConfig

تنظیمات درون session را بازمی‌گرداند. برای اعمال تم، اندازهٔ متن و minimap در UI از این فرمان استفاده کنید.

update_config({ config: GameConfig }) -> CommandResult

تنظیمات کامل را جایگزین می‌کند. consumer باید همهٔ فیلدهای GameConfig را بفرستد تا از ناخواسته‌شدن مقدارهای پیش‌فرض جلوگیری شود.

const current = await invoke('get_config');
const result = await invoke('update_config', {
  config: { ...current, theme: 'retro', font_size: 20 },
});

get_achievements() -> AchievementState[]

achievementهای فعلی را به آرایهٔ JSON سریال‌شده تبدیل می‌کند. UI می‌تواند از unlocked و hidden برای نمایش استفاده کند.

get_autocomplete({ partial: string }) -> string[]

پیشنهادهای متن را بر اساس پیشوند فرمان، جهت، آیتم‌های اتاق و inventory برمی‌گرداند.

const suggestions = await invoke('get_autocomplete', { partial: 'ta' });

4. مدل‌های داده

CommandResult

فیلد نوع JSON معنا
success boolean موفقیت یا شکست عملیات ذخیره/بارگذاری/حذف/تنظیمات
message string پیام انسان‌خوان برای نمایش در رابط

GameConfig

فیلد نوع دامنه/نمونه
text_speed number تأخیر تایپ بر حسب میلی‌ثانیه؛ نمونه 30
sound_volume number مقدار بین صفر و یک؛ نمونه 0.7
music_volume number مقدار بین صفر و یک؛ نمونه 0.5
font_size number اندازهٔ متن بر حسب پیکسل؛ نمونه 16
theme string cyberpunk، dark یا retro
show_minimap boolean نمایش یا پنهان‌کردن بخش نقشه
auto_save boolean ذخیرهٔ خودکار پس از تعداد مشخصی حرکت
confirm_actions boolean رزرو برای confirmationهای رابط

GameResponse

فیلد معنا
messages پیام‌های تازهٔ حاصل از فرمان؛ هر پیام دارای text، msg_type و timestamp است
current_room اتاق فعال، خروجی‌های قابل‌نمایش، آیتم‌های روی زمین، نور و صدای محیط
inventory آیتم‌های inventory شامل id، name، description، icon، category و usable
player health، حرکت‌ها، اتاق‌های کاوش‌شده، معماهای حل‌شده، آیتم‌های جمع‌آوری‌شده و زمان بازی
map_data اتاق‌ها، اتصال‌ها و current_room_id برای minimap
achievements وضعیت unlock و پنهان‌بودن achievementها
score، game_over، game_won شاخص‌های پایان و امتیاز session

SaveSlotInfo

هر آیتم شامل slot، exists، room_name، play_time و timestamp است. برای slot خالی، frontend باید ابتدا exists را بررسی کند و سپس metadata را نمایش دهد.

5. مدیریت خطا و سازگاری

فرمان‌های game معمولاً یک GameResponse با message از نوع Error یا Warning برمی‌گردانند. فرمان‌های فایل‌محور یک CommandResult با success: false برمی‌گردانند. برای خطاهای پیش‌بینی‌نشدهٔ invoke نیز try/catch نگه دارید؛ Tauri فرمان‌ها را به‌صورت Promise فراخوانی می‌کند و قابلیت بازگرداندن خطاهای سریال‌پذیر را دارد. 1

try {
  const result = await invoke('delete_save', { slot: 2 });
  if (!result.success) showNotification(result.message, true);
} catch (error) {
  showNotification(`Unexpected desktop API error: ${String(error)}`, true);
}

6. افزودن یک فرمان جدید

۱. تابع را در src-tauri/src/main.rs یا یک module مشخص تعریف و با #[tauri::command] علامت‌گذاری کنید.
۲. آن را دقیقاً یک‌بار به tauri::generate_handler![...] اضافه کنید. فرمان‌ها باید نام یکتا داشته باشند. 1
۳. ورودی را با typeهای serde::Deserialize و خروجی را با typeهای serde::Serialize طراحی کنید. 1
۴. برای behavior جدید، تست واحد در src-tauri/src/game/tests.rs اضافه کنید.
۵. contract این فایل و consumer JavaScript را در یک PR هماهنگ تغییر دهید.
۶. پیش از PR، cargo fmt --all -- --check، cargo test --workspace و cargo clippy --workspace --all-targets -- -D warnings را اجرا کنید.

قاعدهٔ سازگاری: تغییر نام فرمان، حذف فیلد پاسخ یا تغییر semantics initialize_game/get_game_state یک breaking change است. این تغییرها باید همراه با migration note در CHANGELOG و به‌روزرسانی frontend انجام شوند.

منابع