解析
どうやら、四号君は狭い箱の中が好きなようです。
わたくしが私室に入ると、四号君はオルゴールの小物入れに飛び込み、ぴったりと収まりました。「きゅみ」と満足そうです。スイボにも種類や個体によっていろいろな習性があるようですね。
わたくしは寝室横の半個室の書斎にオルゴールの小物入れを運び、机に向き合いました。
さっそく、スキルで生成された命令書の解読に取りかかります。お母様が使う以上は、しっかりと内容を把握しておくことに越したことはありません。
じっと命令書を眺めます。
``` csharp
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSwibo();
builder.Services.AddSkillDiscoveryMetadataGenerator();
var app = builder.Build();
app
.ExposeSkillDiscoveryMetadata("csharp.開いたらお手")
.WithSwiboEventHook("/");
app.MapPost("/", async ([FromBody]SwiboEventNotification notification, ISwiboContext context, CancellationToken cancellationToken) =>
{
if(notification.EventType == SwiboEvent.ChangeReport && notification.TryParseContextData<SwiboContactSensorEventData>(out var data) && data.OpenState == SwiboOpenState.Opened)
{
var swibo = context.Swibos.OfType<SwiboBot>().First();
await swibo.PressAsync(cancellationToken);
}
return Results.Ok();
});
app.Run();
```
眺めるだけで目眩がしてきます。頭痛の足音が、パレードで行進する憲兵隊のように押し寄せてきました。ああ、癒やしが必要です。
「ぽふぃ?」
頭を傾げるスイ。
微笑んでスイの頭を撫でると、スイはわたくしの手にスリスリと身体を擦り付けて、甘えるようにくぐもった声で応じました。
「ぽふぃ~♪」
スイは世界一愛らしい生物です。ぷにぷにとして、ひんやりとしたさわり心地。乳白色で半透明の身体に、つぶらな瞳。ふっくらとしたフォルムは、まるでボールのようです。そして、この短くてフリルのような可愛い口腕――。
ああ、可愛すぎて、胸が張り裂けそうです。
さて、癒やされたところで、再び古代語の羅列に視線を戻します。辞書を片手に、一つ一つ読み解いてゆくしかありません。
「おそらく、この波括弧`{ }`というのが、章や節のようなひとまとまりなのでしょうね。数式のような形式的な書式で構造化されているようです」
「ぽふぃ~」
スイもわたくしと顔を並べて、一緒に解読に付き合ってくれます。もしかすると、スイのほうが古代語には詳しいのかもしれません。
「命令の塊だから、仮にコードブロックと名付けるのはどうでしょう」
「ぽふぃ♪」
スイはくるりと宙返りをしました。
``` csharp
app
.ExposeSkillDiscoveryMetadata("csharp.開いたらお手")
.WithSwiboEventHook("/");
```
「そして、これはサブスキル名のようですね」
この『開いたらお手』というのは、わたくしが付けた名前です。
「ぽふ」
``` csharp
app.MapPost("/", async ([FromBody]SwiboEventNotification notification, ISwiboContext context, CancellationToken cancellationToken) =>
```
「……ふふっ。ふふふふ」
「ぽふぃ?」
「……さっぱりわかりません」
「ぽふぅ」
スイはごろんと机に転がりました。
地図の里程標が斜線……。意味が分かりません。
「ただ、多分、一番重要なのは、この中身の部分なのでしょうね」
「ぽふぃ~」
```
if(notification.EventType == SwiboEvent.ChangeReport && notification.TryParseContextData<SwiboContactSensorEventData>(out var data) && data.OpenState == SwiboOpenState.Opened)
{
var swibo = context.Swibos.OfType<SwiboBot>().First();
await swibo.PressAsync(cancellationToken);
}
```
このくだりは『お手』と殆ど変わりません。
「『お手』との違いは……この`if`というブロックですね」
わたくしはifの部分を指さすと、スイもその部分を覗き込みました。
ifといえば、古代語の『もし』です。
「ここだけは何か複雑な事が書かれていそうです。もしかすると、単語だけを拾って読めば意味が掴めるかもしれません。逐語訳です」
「ぽふぃ!」
```
if(notification.EventType == SwiboEvent.ChangeReport && notification.TryParseContextData<SwiboContactSensorEventData>(out var data) && data.OpenState == SwiboOpenState.Opened)
```
「もし、通知の事象種別が、スイボ事象の変化報告で、通知の文脈データ?の解析を試行し、スイボ開閉センサー事象データ?の開閉ステータスが『開』なら……。なるほど、これはは『開いたら』の条件を厳密に述べているようですね。ふむふむ」
「ぽふぽふ」
スイはわたくしと一緒に頷きます。
そしてその直後の波括弧の囲みが、『お手』の内容です。
「つまり、ifから始まるこの一塊の部分が、まさに『開いたらお手』を意味するのでしょうね」
とすれば、です。
「では、条件はそのままに『開いたら点灯』とすれば、このifのブロックの中身が、『点灯』と同じになりそうですね」
「ぽふぃ~」
――点灯
``` csharp
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSwibo();
builder.Services.AddSkillDiscoveryMetadataGenerator();
var app = builder.Build();
app.ExposeSkillDiscoveryMetadata("csharp.点灯");
app.MapPost("/", async (ISwiboContext context, CancellationToken cancellationToken) =>
{
var swibo = context.Swibos.OfType<SwiboCeilingLight>().First();
await swibo.TurnOnAsync(cancellationToken);
return Results.Ok();
});
app.Run();
```
では、試してみましょう。
「スキル〝C#〟開いたら点灯」
――開いたら点灯
``` csharp
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSwibo();
builder.Services.AddSkillDiscoveryMetadataGenerator();
var app = builder.Build();
app
.ExposeSkillDiscoveryMetadata("csharp.開いたら点灯")
.WithSwiboEventHook("/");
app.MapPost("/", async ([FromBody]SwiboEventNotification notification, ISwiboContext context, CancellationToken cancellationToken) =>
{
if(notification.EventType == SwiboEvent.ChangeReport && notification.TryParseContextData<SwiboContactSensorEventData>(out var data) && data.OpenState == SwiboOpenState.Opened)
{
var swibo = context.Swibos.OfType<SwiboCeilingLight>().First();
await swibo.TurnOnAsync(cancellationToken);
}
return Results.Ok();
});
app.Run();
```
「やりました! 予想通りです」
```
var swibo = context.Swibos.OfType<SwiboCeilingLight>().First();
await swibo.TurnOnAsync(cancellationToken);
```
この部分は、『点灯』と、『開いたら点灯』とで全く同じです。
「ぽふぃ~♪」
スイも目を輝かせ、わたくしの周りをすいすいと泳ぎ回りました。
「ならば、『閉じたら消灯』なら、名前の他に、OpenedがClosedに、TurnOnがTurnOffに変わるはずです。スキル〝C#〟扉が閉じたら消灯」
``` csharp
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSwibo();
builder.Services.AddSkillDiscoveryMetadataGenerator();
var app = builder.Build();
app
.ExposeSkillDiscoveryMetadata("csharp.閉じたら消灯")
.WithSwiboEventHook("/");
app.MapPost("/", async ([FromBody]SwiboEventNotification notification, ISwiboContext context, CancellationToken cancellationToken) =>
{
if(notification.EventType == SwiboEvent.ChangeReport && notification.TryParseContextData<SwiboContactSensorEventData>(out var data) && data.OpenState == SwiboOpenState.Closed)
{
var swibo = context.Swibos.OfType<SwiboCeilingLight>().First();
await swibo.TurnOffAsync(cancellationToken);
}
return Results.Ok();
});
app.Run();
```
「これも予想通りです!」
「ぽふぃぽふぃ♪」
「では、さっそく試してみましょう。スイちゃん、三号君、四号君、よろしくお願いします」
「ぽふぃ」
「きゅい!」
「きゅみ」
小物入れの蓋を閉めます。
「きゅむ」
「ぽふ!」
「きゅい!」
部屋が暗くなります。三号君が消灯したのです。
小物入れの蓋を開きます。
「きゅみ」
「ぽふ!」
「きゅい!」
部屋が明るくなりました。三号君は天井に頭をくっつけて、明るく光る口腕をゆらゆらとゆらめかせていました。
「お母様に気に入ってもらえるといいですね」
「ぽふぃ~」