特殊な型、トレイト、属性
ビルトイン型
ゲームが使う型の大半は std の普通の宣言で、皆さんの型と同じく Kagari で書かれています。ただし一部の型はコンパイラが名前で知っています。専用の構文や専用の検査があるか、あるいは見える表現をまったく持ちません。この章ではそれらを列挙し、それぞれの何が特別なのかを説明します。不透明かどうか、有限型かどうか、Eq かどうか、どの関数種別で役立つか、コピーが何を意味するか、です。メソッドは STD Reference にあります。
Kagari のすべての型は値セマンティクスを持ちます。代入、引数渡し、戻り値は値をコピーします(値、参照、クロージャを参照)。以下のハンドル型ではコピーされる値がハンドルなので、両方のコピーは同じ保存先を指します。
概要
| 型 | 定義 | 有限 | Eq | 主な種別 | STD のページ |
|---|---|---|---|---|---|
bool、() | 言語 | はい | はい | すべて | — |
Int<lo, hi> | 言語 | はい | はい | すべて | — |
u8 … u128、i8 … i128、usize、isize | 言語 | いいえ | はい | fn、const fn | — |
Rat、Decimal | #[builtin] 構造体 | いいえ | はい | fn、const fn | std |
String | #[builtin] 構造体 | いいえ | はい | fn、const fn | std |
Text | #[builtin] 構造体 | はい | はい | すべて | std::narrative::text |
ImageAsset、AudioAsset、VoiceAsset、VideoAsset、FontAsset | #[builtin] 構造体 | はい | はい | すべて | std |
ColorShader<A>、MixShader<A>、TextureShader<A>、MaskShader<A>、LocalMotionShader<A>、TransitionalMotionShader<A> | #[builtin] 構造体 | いいえ | はい | const fn | std::screen::shader |
Vec<T> | #[builtin] 構造体 | いいえ | T: Eq なら | fn、const fn | std |
Range<T> | 構造体 | T が有限なら | T: Eq なら | すべて | std |
Option<T>、Result<T, E> | 列挙型 | 型引数が有限なら | 型引数が Eq なら | すべて | std |
Setting<T>、Meta<T> | #[builtin] 構造体 | いいえ | いいえ | fn(後述) | std::system、std::narrative |
Narrative | #[builtin] 構造体 | いいえ | いいえ | fn | std::narrative |
Screen | #[builtin] 構造体 | いいえ | はい | const fn | std::screen |
Entity、Prop<T>、ImageLayer、LabelLayer、MovieLayer、Hud、ChoiceMenu、Camera、Channel | #[builtin] 構造体 | いいえ | いいえ | const fn | std::screen、std::screen::audio |
Change<T>、Swap、ChannelChange | #[must_use] #[builtin] 構造体 | いいえ | いいえ | const fn | std::screen、std::screen::audio |
Element、Placed | #[builtin] 構造体 | いいえ | いいえ | fn | std::ui |
Arm、Divergence | #[builtin] 構造体 | いいえ | いいえ | fn | std::narrative、std::system::saves |
Render | const fn(Screen) -> Screen の型エイリアス | はい | はい | すべて | std::screen |
Duration | 構造体 | いいえ | はい | すべて(物語では定数として) | std::time |
| 関数ポインタ | 言語 | fn 以外の種別なら | はい | すべて | — |
クロージャ Fn(…) | 言語 | いいえ | いいえ | すべて(物語では第二級) | — |
「有限」は、pushdown fn がその型の値を実行時に保持できるかどうかを決めます(E3008)。どの型の定数式も、コンパイル時に畳み込まれるので物語の中に書けます。
不透明なビルトイン型
#[builtin] 付きで宣言された構造体は、コンパイラとエンジンが実装します。見えるフィールドはありません。
- 構造体リテラルを書くことも、フィールドを読むことも、パターンで分解することもできません。値は
stdの関数とメソッド、リテラル(Text、Decimal)、またはエンジン(Narrative)からのみ得られます。 Eqになるのはstdがimpl Eqでそう宣言した場合だけです。構造的なEqの規則は中を見ません(言語トレイトを参照)。- 有限型になるのは
Textとアセット型だけです。その他のビルトイン型はすべて無限として扱われます。 - 表現は
.kagariファイルに含まれないため、ゲームを壊さずにエンジンのバージョン間で変えられます。
ビルトイン型を宣言できるのは std だけです(E1008)。大半はプレリュードに入っていますが、画面状態の型(Entity、Prop<T>、各レイヤーなど)は入っていません。これらは Screen のメソッドから &mut 参照として受け取るもので、名前を書くことはまれだからです。
Text
Text は定数テキストです。プレーン("Mio")またはリッチ(ルビ、テキスト効果、埋め込みを含む t![…] で作るもの)です。文字列リテラルの型は String ではなく Text です。
const NAME: Text = "Mio";- 有限。 物語の中の
Textの値はプログラムの定数テキストなので、物語変数やpushdown fnの引数・戻り値をTextにできます。 - エントリーシーンでは不可。
fnのコードはto_textで実行時に新しいテキストを作れるため、エントリーシーンの引数型と戻り値型にTextを含めることはできません(E3009)。 - 埋め込み。
t![…]の中の{expr}はto_text(expr)の呼び出しで、expr: TにT: ToTextを要求します。pushdown fnの中では、有限な実行時の値に対するto_textは他のconst fn呼び出しと同じく表化されるので、台詞は物語の状態の有限な関数のままです。 Eq:はい。
String
String は fn のコード向けの実行時文字列です。有限型ではなく、Eq と ToText を実装します。
暫定。 現在の std には String を作る関数も変更する関数もありません。ゲームが表示するテキストは Text です。
アセット型
ImageAsset、AudioAsset、VoiceAsset、VideoAsset、FontAsset は、ゲームと一緒にパックされるファイルを指します。6 つのシェーダー型(ColorShader<A> など)も同様で、引数の型が A である 1 つのロールの WGSL ファイル(.wgsl)を指します。値は asset または system_font の定数呼び出しでのみ作られます。
const CG_001: ImageAsset = asset("cg_001.png");const THEME: AudioAsset = asset("bgm/theme.ogg");const GOTHIC: FontAsset = system_font("msgothic.ttc");asset::<A>の型引数は定数の型から推論され、Assetを実装していなければなりません。- 引数は文字列リテラルで(
E2028)、空でなく(E1028)、アセットディレクトリの中で(E1029)その予約されたディレクトリsystem-fontsとstdの外を指す必要があります(E1032)。ファイルがなければE1027です。system_fontには独自の規則があります(E1030、E1031)。STD Reference のstdを参照してください。 - 有限。 ファイルのアセット型の値はちょうどプログラムのアセット定数なので、物語はそれを保持でき、アセット名の綴り間違いは実行時の失敗ではなく名前解決のエラーになります。シェーダー型は有限型ではありません。シェーダーを使うのはレンダーで、物語ではありません。
Eq:はい。- 効果値が保持する、ロールを持たないシェーダーファイルの識別子
ShaderAssetは、Assetではなく、プレリュードにもありません。ゲームが名前で書くことはありません。std::screen::shaderを参照してください。
Setting<T> と Meta<T>
設定とメタフィールドは、セーブの外に保存される永続的なグローバル値です。それぞれハンドルを保持する不変の static で宣言します。
static MUSIC: Setting<Volume> = setting(volume(60));static CLEARED_AZUSA: Meta<bool> = meta(false);- 不変の
staticはSetting<T>かMeta<T>を保持しなければならず(E3011)、setting(…)とmeta(…)はstaticの初期化子としてのみ呼べます(E4007)。初期化子は、保存ファイルに値がないときに使われる値です。 - ハンドル自体は値です。関数に渡したり、
Settingsのようなレコードに格納したりできます。コピーするとハンドルがコピーされ、両方のコピーは同じ保存値を読み書きします。 - 種別。
getとsetはfnです。Meta::writeはpushdown fnで、物語はメタを書くだけで読みません。const fnはSettingのハンドルを値としてのみ使えます(Entity::gateに渡す場合など)。そこでgetを呼ぶとE3001です。constのコードはメタフィールドにまったく言及できません(E3013)。 - 有限型ではなく、
Eqでもありません。
Narrative
Narrative は、実行中の物語をシステムから見る唯一の窓です。エンジンはこれをゲームビュー(System::game、fn(Narrative) -> Element)とゲームオーバーレイ(fn(Narrative) -> GameOverlay)にだけ渡します。表現は隠されているので、システムのコードは物語変数を読めません。メソッドはすべて fn で、読み取りはリアクティブです。コピーは同じ実行中のゲームを指します。有限型ではなく、Eq でもありません。
Screen とその部品
Screen は、ステップが表示する画面とそのステップのタイムラインです。すべてのレンダーの入力であり出力です。メソッドはすべて const fn です。
- 値。 レンダーは直前の画面のコピーを受け取り、新しい画面を返します。コピーを変えても呼び出し元の画面は変わりません。
- 部品。
Entity、Prop<T>、ImageLayer、LabelLayer、MovieLayer、Hud、ChoiceMenu、Camera、Channelは画面の部品です。screen.entity(id)やscreen.music()などのメソッドから&mut参照として受け取り、その参照を通した変更はその画面を変えます。 - 保留中の変更。
Change<T>、Swap、ChannelChangeはchange、clear、stopが返す保留中の変更です。これらは#[must_use]で、apply_animationを呼ぶまで何も起きません。捨てられた保留中の変更は警告W3023になります。 ScreenはEqなので、コンパイラは一貫性のために画面を比較できます。部品はEqではありません。いずれも有限型ではありません。
Element と Placed
Element はエンジンがレイアウトする UI 要素ツリーで、Placed は layer![…] の中に配置された要素です。どちらも UI フォームと std::ui の関数で作られ、それらはすべて fn です。有限型ではなく、Eq でもありません。
Arm と Divergence
Arm は現在の選択肢の選べるアームで、Narrative::menu から読み、Narrative::select に渡し返します。Divergence は、セーブがもうプログラムに合わないときの nav::load のエラーです。どちらも fn のコードにしか現れません。有限型ではなく、Eq でもありません。
数値
| 型 | 定義 | 有限 | 備考 |
|---|---|---|---|
Int<lo, hi> | 言語のプリミティブ | はい | 整数 lo..=hi。lo と hi は lo <= hi を満たす定数の i64 値です(E2004)。物語が実行時に保持できる唯一の整数型です |
u8 … u128、i8 … i128、usize、isize | 言語のプリミティブ | いいえ | Rust の演算子を持つ Rust の整数 |
Decimal | std の #[builtin] 構造体 | いいえ | 正確な十進数。小数点を含むリテラル(0.5)は Decimal です。浮動小数点数の代わりです |
Rat | std の #[builtin] 構造体 | いいえ | 正確な有理数。リテラルはなく、Rat::new(num, den) と書きます |
いずれも Eq で、整数、Rat、Decimal には順序があります(<、<= など)。整数型どうしは算術で混ぜられず(E2014)、変換は Integer のメソッド into と saturate だけで行います。as キャストはありません(E2019)。算術、リテラルの型付け、飽和、オーバーフローは数値で説明します。
Vec<T>
Vec<T> は fn と const fn のコード向けの可変長リストです。他のすべての型と同じく値です。push と set は呼び出した場所を変え、コピーには影響しません。
v[i]で任意の整数型の添字を使ってアクセスでき、for x in vで反復できます。どちらもVec<T>と配列に対して言語に組み込まれています。- 範囲外の
getはNoneを返し、範囲外のsetは評価エラーです(コンパイル時評価ではE4005)。 - 有限型ではありません。
T: EqならEqです。
Range<T>
Range<T> は公開フィールド start、end、inclusive を持つ std の普通の構造体です。コンパイラは二つの場所でこれを知っています。
- 範囲式。
a..bとa..=bはRange<T>を作ります。Tは両端がともに変換できる型で、0..7はRange<Int<0, 7>>です。範囲の値になるのはa..bとa..=bだけで、a..、..b、..などの他の形はE2030です。パターンには独自の範囲の形(a..、..=b、a..b、a..=b)があります。範囲パターンを参照してください。 forループ。forはTが整数型のRange<T>を反復します(そうでなければE2031)。pushdown fnの中では両端が定数式でなければなりません(E3006)。
Option<T> と Result<T, E>
どちらも std の普通のジェネリックな列挙型で、プレリュードはそのバリアント None、Some、Ok、Err をインポートします。コンパイラは ? 演算子のためにこれらを知っています。Option に対しては Option を返す関数が、Result に対しては同じエラー型の Result を返す関数が必要です(E2034)。エラーの変換はありません。型引数が有限なら有限で、型引数が Eq なら Eq です。
関数ポインタ型とクロージャ型
関数の型は呼び出すコードの種別を持つので、呼び出し規則はポインタとクロージャを通しても成り立ちます。
| 型 | 保持するもの | 有限 | 対応するクロージャ型 |
|---|---|---|---|
fn(A) -> B | 名前付きの fn | いいえ | Fn(A) -> B |
const fn(A) -> B | 名前付きの const fn、または何もキャプチャしないクロージャ | はい | const Fn(A) -> B |
pushdown fn(A) -> B | 名前付きの即時手続き | はい | pushdown Fn(A) -> B |
scene fn(A) -> B | 名前付きのシーン | はい | なし |
Fn(A) -> B、const Fn(A) -> B、pushdown Fn(A) -> B | その種別のクロージャまたは関数 | いいえ | — |
- 名前付きの関数は、ちょうど自分の種別のポインタ型またはクロージャ型に型強制されます。何もキャプチャしないクロージャは自分の種別のポインタに型強制されますが、キャプチャするクロージャはできません(
E2036)。ポインタは同じ種別のクロージャ型に型強制されます。 pushdownとsceneがキーワードになるのはfnの直前(およびFnの直前のpushdown)だけです。- 有限。 物語の種別または
constのポインタは有限です。その値はプログラムの有限個の名前付き関数だからです。クロージャは決して有限型ではなく、物語の中では第二級です。 Eq。 関数ポインタは同一性で比較されます。クロージャは決してEqではありません(E2017)。
Render
pub type Render = const fn(Screen) -> Screen;std::screen とプレリュードにある Render は新しい型ではなくエイリアスです。レンダーはステップ前の画面からステップ後の画面への const fn で、ステップはこれを render 属性として受け取ります。const fn のポインタなので Render は有限で Eq であり、Render が期待される場所には何もキャプチャしないクロージャをその場で書けます。レンダー関数を参照してください。
const fn clear_background(mut screen: Screen) -> Screen { screen.background().clear().apply_animation(fade(ms(500))); screen}
const CLEAR: Render = clear_background;Duration
pub struct Duration { pub ms: u32 }Duration は std::time の普通の構造体で、ビルトイン型ではありません。ここに載せるのは、std のあらゆる時間が整数ミリ秒の Duration だからです。単位付き文字列やフレーム数はありません。プレリュードには Duration、ms(n)、secs(n) があります。
u32を保持するので有限型ではありません。物語は持続時間を、レンダーの中のfade(ms(500))のような定数式でのみ使います。Eq:はい(構造的に)。divは切り捨てます。ms(1000).div(3)はms(333)です。u32ミリ秒に収まらない持続時間は、secs、plus、timesで作られた場合も画面のタイムラインで到達した場合も、コンパイル時評価でE4013になります。