特殊な型、トレイト、属性
属性
属性はアイテムの直前に #[name] と書きます。Kagari の属性はちょうど 5 つで、どれも引数を取りません。ゲームが使うのはそのうち 4 つで、#[builtin] は標準ライブラリ専用です。
| 属性 | 付けられる場所 | 意味 | 誤用 |
|---|---|---|---|
#[scene] | pushdown fn | シーン:ステップの実行、シーンの呼び出し、乱数の取得ができる | E3018 |
#[entry] | #[scene] の関数 | エントリーシーン:システムがここから物語を開始できる | E3018、E3008、E3009 |
#[must_use] | struct、enum | その型の値は完了させなければならず、捨ててはいけない | E3018。使用箇所で警告 W3023 |
#[shader_arg] | struct | その型をシェーダーの引数にできる | E3018、E3025、E3026 |
#[builtin] | 標準ライブラリのみ:関数、構造体、トレイト | コンパイラとエンジンが実装する | E1008、E1009、E1013 |
構文
/// The first scene of the game.#[scene]#[entry]pub pushdown fn Main() { s!(t!["It was the last day of summer."]);}- 属性はアイテムの前に置きます。対象は関数(
implの中の関連関数を含む)、struct、enum、const、static、type、mod、use、impl、traitです。アイテムのドキュメントコメントの後、pubの前に書きます。 - 複数の属性を、1 行にでも別々の行にでも、任意の順序で重ねられます。
///のドキュメントコメントはコメントであり、属性ではありません。- 内部属性(
#![…])は存在せず、属性の後には必ずアイテムが続かなければなりません。どちらも構文エラーです(E0001)。文や式に属性は付けられません。 - 5 つ以外の名前は
E1006で、その属性は無視されます。 #[must_use("reason")]のように引数付きで書いた属性はE1007です。属性自体は適用されます。
暫定。 パーサーは構造体のフィールド、タプルのフィールド、列挙型のバリアントに付いた属性も受け付けますが、現在のコンパイラはそこでは属性を無視します。未知の名前も同様です。この挙動に頼らないでください。
#[scene]
#[scene] は pushdown fn をシーンにします。シーンだけが次のことをできます。
- ステップの実行:
s!(…)、choice!{…}、push_stepの呼び出し(それ以外ではE3002) - 他のシーン(自分自身を含む)の呼び出し(それ以外では
E3003) rng_chooseによる乱数の取得(それ以外ではE3024)
#[scene] のない pushdown fn は即時手続きです。シーンの中のすべてのループと呼び出しのすべての循環は、ステップを通らなければなりません(E5001、E5002)。シーンへのポインタの型は scene fn(…) -> R です。
#[scene]pushdown fn Greeting() { s!(who = "Mio", t!["Hello."]);}pushdown fn 以外への #[scene]、たとえば fn や const fn への #[scene] は E3018 です。
シーンと即時手続きを参照してください。
#[entry]
#[entry] はシーンをエントリーシーン、つまりゲームシステムが物語を開始できる場所にします。同じ関数に #[scene] が必要で、なければ #[entry] は E3018 です。二つの属性の順序は問いません。
- システムはエントリーシーンを
nav::start(Scene, args, on_exit)で開始します。第 1 引数は#[entry]シーンのパスでなければならず、他の式は書けません(E2027)。argsはその引数のタプルで、on_exitが戻り値を受け取ります。 - 他のシーンと同じく、引数型と戻り値型は有限型でなければなりません(
E3008)。さらに、fnのコードは実行時にテキストを作れるので、これらにTextを含めることはできません(E3009)。 - エントリーシーンが戻ると物語は終わります。その戻り値がエンディングです。
- コンパイラは各エントリーシーンから物語を解析します。エントリーシーンはジェネリックパラメータなしで書いてください。ジェネリックな
#[entry]シーンは開始点として使われません。
pub enum Ending { NormalEnd, AzusaEnd }
#[scene]#[entry]pub pushdown fn Main(cleared_azusa: bool) -> Ending { s!(t!["Morning."]); if cleared_azusa { Ending::AzusaEnd } else { Ending::NormalEnd }}エントリーシーンとエンディングを参照してください。
#[must_use]
struct または enum に付けた #[must_use] は、その型の値が未完了の操作であることを表します。それ以外のアイテムに付けると E3018 です。コンパイラは次の場合に警告します(W3023)。
- 式文がその型の値、またはその型への参照を生む場合
letがそのような値をローカル変数に束縛し、関数がそのローカル変数に対してその型のメソッドを一度も呼ばない場合
標準ライブラリは保留中の変更 Change<T>、Swap、ChannelChange にこの属性を付けています。画面の変更は apply_animation を通してのみ起きるので、apply_animation の書き忘れはコンパイル時に見つかります。
const fn roof(mut screen: Screen) -> Screen { screen.background().clear(); // W3023: nothing happens screen.background().clear().apply_animation(fade(ms(500))); // completed screen}ゲームが自分の型に付けることもできます。その場合、警告は値を完了させる手段としてその型のメソッドを列挙します。
#[shader_arg]
struct に付けた #[shader_arg] は、その型をシェーダーの引数型にします。型は ShaderArg を実装するので、ColorShader<Memory> のようなシェーダーアセットがその型を引数に取れ、エンジンがその値をシェーダーに渡します。それ以外のアイテムに付けると E3018 です。
use std::screen::shader::ColorShader;
#[shader_arg]struct Memory { strength: Decimal,}
const MEMORY: ColorShader<Memory> = asset("memory.wgsl");- 構造体は 1 つ以上の名前付きフィールドを持ち、型パラメータを持ちません。const パラメータは使えます(そうでなければ
E3025)。 - どのフィールドも、シェーダーが読める型を持ちます:
bool、i32、u32、Decimal、Rat、std の型Color、Point、Offset、Size、Anchor、Angle、Duration、フィールドのない列挙型、#[shader_arg]構造体、またはこれらの配列[T; N](N> 0)です。それ以外の型のフィールドや長さ 0 の配列は、そのフィールドでE3026になります。
各フィールドがどのようにシェーダーに渡るかは、STD リファレンスの シェーダーの書き方 で説明します。
#[builtin]
#[builtin] は、コンパイラとエンジンが実装するアイテムを表します。標準ライブラリでのみ使えます(E1008)。std の宣言を読むときに目にします。
#[builtin] pub struct Screen;#[builtin] pub const fn asset<A: Asset>(path: narrative::Text) -> A;#[builtin] pub trait Eq {}| 対象 | 規則 |
|---|---|
| 関数 | 本体を持ちません(E1009)。他の関数と同じように呼び出され、種別の規則も他の関数と同じく適用されます |
| 構造体 | フィールドを持ちません(E1009)。型は不透明です。不透明なビルトイン型を参照してください |
| トレイト | std のトレイトはすべて #[builtin] でなければなりません(E1013)。言語トレイトを参照してください |
#[builtin] でない本体のない関数は E1010 です。
診断
| コード | 条件 |
|---|---|
E0001 | 内部属性 #![…]、またはアイテムが続かない属性 |
E1006 | 未知の属性 |
E1007 | 引数付きの属性 |
E1008 | 標準ライブラリの外の #[builtin] |
E1009 | 本体を持つ #[builtin] 関数、またはフィールドを持つ #[builtin] 構造体 |
E1013 | #[builtin] のない標準ライブラリのトレイト |
E3018 | pushdown fn 以外への #[scene]、#[scene] のない #[entry]、構造体・列挙型以外への #[must_use]、構造体以外への #[shader_arg] |
E3008、E3009 | エントリーシーンの引数型または戻り値型が有限でない、または Text を含む |
E2027 | #[entry] シーンでないものに対する nav::start |
W3023 | 捨てられた、または完了されなかった #[must_use] の値 |
E3025 | 名前付きフィールドを持たない、または型パラメータを持つ #[shader_arg] 構造体 |
E3026 | シェーダーが読めない型の #[shader_arg] フィールド、または長さ 0 の配列 |