土曜日, 5月 3, 2025
ホーム ブログ ページ 1757

Microsoftが50周年を記念して「Windowsの最も印象的な瞬間」をイメージした壁紙を無料公開



Microsoftが2025年4月4日(金)に50周年を迎えたことを記念して、Windowsの熱烈なファンだというMicrosoftのデザイナーによって作られた「Windowsの最も印象的な瞬間」の壁紙を配布しています。

続きを読む…

フラッグシティパートナーズ海外不動産投資セミナー 【DMM FX】入金

Source link

Views: 0

パタゴニアの「R1エア・フルジップ・フーディ」は温かい・軽い・速乾。いまの屋外レジャーに最適な一枚



パタゴニアの「R1エア・フルジップ・フーディ」は温かい・軽い・速乾。いまの屋外レジャーに最適な一枚

パタゴニアの名品「R1エア・フルジップ・フーディ」は寒暖差の激しいこの季節だけでなく、夏や冬の旅行時にも大活躍です。

フラッグシティパートナーズ海外不動産投資セミナー 【DMM FX】入金

Source link

Views: 0

残忍で現実的な第一次世界大戦fps地獄は緩んでいますが、今は汚れが安くなります



象徴的なマルチプレイヤーシューターの体験に関しては、バトルフィールド3のオペレーションメトロは常に私のリストの一番上にあります。弾丸や爆発物が頭上を飛ぶにつれてトンネルになりやすくなり、チームメイトが注文を叫ぶと、あなたは目標に向かってゆっくりとクロールします。私のように、あなたがまだその高さを追いかけているなら、 地獄は解放されます コールに答えるためにここにいます。何よりも、期間限定で大幅に割引でそれをつかむことができます。
ストーリーの残りの部分を読んでください…
関連リンク:
残忍なFPSゲームHell Let Loseは今まで以上にSteamで人気があります
悪質で現実的なww2シューティングゲーム地獄は、あなたが速いなら、完全に無料です
ハードコアWW2シューティングゲーム地獄Let Loose Teases brent新しい砂漠マップ
フラッグシティパートナーズ海外不動産投資セミナー 【DMM FX】入金

Source link

Views: 0

ニュース – 今すぐSteamで利用可能-LegionTD2


レギオンTD 2-マルチプレイヤータワー防衛 Steamで利用可能になりました!

無限に再生可能なマルチプレイヤーとシングルプレイヤータワーの防御。彼らがあなたのものを破壊する前に、敵の王を破壊し、敵の王を破壊します。 Legion TD 2は、戦術、チームワーク、予測のユニークなゲームです。 1-8プレイヤーとしてのパーティー。

フラッグシティパートナーズ海外不動産投資セミナー 【DMM FX】入金

Source link

Views: 0

itch.io autumn ttrpgで5つの素晴らしいゲームをピックアップしてくださいバンドルを選択してください!


素晴らしいテーブルトップRPGのパックで休日に向けて準備を整えてください!テーブルの周りに集まり、わずか12ドルでお気に入りのシステムの5つをピックアップし、開発者をサポートします。

しかし、すぐに行動します itch.io autumn ttrpgはバンドルを選択します 12月5日午前10時(PT)までのみです!

これがバンドルにあるものです:

Runecairn:Wardensaga

暗いものと北欧をお探しですか? Runecairn:Wardensagaは、大成功を収めた後、Soulsに触発されたRPGのベースゲーム、高度なルール、1つの完全なパッケージでの入門冒険を収集します。友達と遊ぶために必要なものをすべて手に入れるか、一人で行くことができます。

Dying、Respawning、およびRunecairnで思いつくことができる最も厄介なダンジョンのスリルを体験してください!

Slugblaster:Quantum Centipedeのキックフリップ

うん、あなたはそのタイトルを正しく読んだ。 Slugblaster:Quantum Centipede上のキックフリップは、このバンドルで最もワイルドなTTRPGだけでなく、ホバーボードが最も多いものでもあります。 10代の年に町の周りでスケートの感覚を再現することを目指して、このシュールレアリスムのルールセットには、非常にクールであるというSCIFIの夢を実現するために必要なものがすべて揃っています。

SCIFIの物語が、超常現象の実体に取り組む軍事戦闘機の不安定なバンドを巻き込むことを望むならどうでしょうか?拳はあなたの夢の戦術的なアクションゲームであるため、あなたが求めていることを正確にストラップしてください。 Fistの印象的で広大なルールセットのこの「最終」版で、戦いのノンストップの混乱で、これまでにプレイした中で最も創造的なmerc兵のいくつかを限界に抑えてください。

戦争バンワ

拳に行く準備はできていますか? Gubat Banwaは、最高のTTRPG戦略的戦闘で革新する結婚芸術にインスパイアされたルールセットです。ユニークなアクションと、クラスをフライに切り替える能力があります。グバットバンワは、最も機械的に柔軟なルールセットの1つであり、最もやりがいのあるルールの1つです。物事をさらに良くするために、Gubat Banwaセンターは、アジアの民間伝承と神話を中心にして、見逃せないロールプレイングの新鮮なテイクをしています。

アポテカリア

そして今、ソロTTRPGファンのために。 Apothecariaは、魔法のポーションを通して町を癒すことに関するジャーナリングゲームです。長いストレッチで毎日プレイするように設計されたこのゲームは、地元の魔女に降りかかる可能性のあるすべてのふざけた態度を描き、採餌し、一般的に想像するように求めています。 Stardew ValleyやHarvest Moonのようなゲームの居心地の良い村のダイナミクスが好きなら、これまでにジャーナルを埋めるための最良の方法で家にいるでしょう。

これらのゲームの5つすべてをitch.io autumn ttrpgでわずか12ドルでつかみます。ここでバンドルを選択します。

フラッグシティパートナーズ海外不動産投資セミナー 【DMM FX】入金

Source link

Views: 0

「Nintendo Switch 2」予約抽選受付スタート。4/16締切、4/24の一般予約開始日に当落を連絡



「Nintendo Switch 2」予約抽選受付スタート。4/16締切、4/24の一般予約開始日に当落を連絡

任天堂は、直販ウェブショップ「マイニンテンドーストア」での「Nintendo Switch 2」抽選販売について、申込み受付を開始した。

フラッグシティパートナーズ海外不動産投資セミナー 【DMM FX】入金

Source link

Views: 0

Xiaomi Store国内2号店が4月5日(土)イオンモール川口でグランドオープン : – ASCII STARTUP



Xiaomi Store国内2号店が4月5日(土)イオンモール川口でグランドオープン : - ASCII STARTUP

小米技術日本株式会社
小米技術日本株式会社(以下「シャオミ・ジャパン」、本社:東京都港区、取締役社長:大沼 彰)は、イオンモール川口に日本で2号店となる常設店「Xiaomi Storeイオンモール川口店」を4月5日(土)グランドオープンしました。このオープンを記念し、店頭にてオープンセレモニーが開催されました。

■Xiaomi Storeイオンモール川口店について
Xiaomi Storeイオンモール川口店は、先日オープンした日本第1号店のXiaomi Storeイオンモール浦和美園店に次ぐ2号店です。Xiaomi Storeイオンモール浦和美園店と同様にXiaomi Storeのデザインコンセプトを踏襲し、店内では160製品以上を販売、これまでオンラインのみで販売されていた製品も実際に体験・購入することができます。

同年3月13日(木)に発表したイオンモールとの協業における狙いである「スマートなくらしを、すべての人へ」というXiaomiのミッションの実現、スマートホームというコンセプトでお客様の生活をより豊かにできるような店舗づくりを目指していきます。
■オープンセレモニーの様子
オープンセレモニーは、MCによる開会の挨拶で幕を開けました。会場には多くのメディア関係者やファンの皆様にお集まりいただき、Xiaomi Store2号店のオープンを祝いました。

■イオンモール株式会社 イオンモール川口 ゼネラルマネージャー 東様のご挨拶 
イオンモール株式会社 イオンモール川口 ゼネラルマネージャー 東氏は、冒頭でXiaomi Storeイオンモール川口店のオープンを祝福するコメントを寄せ、さらに「イオンモールの魅力は、製品を直接見て、触れて、スタッフから話を聞けること。さらに一緒に来たご友人やご家族とともに楽しんでいただけることだと思っています。その体験がXiaomi Storeを通して一人でも多くの方に届くことを、大変嬉しく思います。」と期待を述べました。

■小米技術日本株式会社 副社長 鄭からのご挨拶
続いて、小米技術日本株式会社 副社長の鄭からご挨拶しました。鄭は、「先月13日にオープンの発表をさせていただき、こうして2店舗無事にオープンできたのは、支えてくださるファンの皆さまのおかげです。今後の展開にも期待いただけますと幸いです。」と来場者に感謝を伝え、今後のXiaomi Store拡大への意欲を述べました。

■ゲストの登壇とテープカットセレモニー
オープンセレモニーの締めくくりとして、イオンモール株式会社 イオンモール川口 ゼネラルマネージャー 東氏、小米技術日本株式会社 副社長 鄭、小米技術日本株式会社 プロダクトプランニング本部長 安達、そしてXiaomiファンが登壇し、盛大なテープカットが行われました。また、小米技術日本株式会社 プロダクトプランニング本部長 安達が当日の一日店長を務めることも発表されました。テープカットの瞬間、会場からは大きな拍手が沸き起こり、Xiaomi Storeイオンモール川口店の正式オープンが宣言されました。
■オープン記念キャンペーン
オープンを記念して、複数の特別キャンペーンが実施されています。

オープンキャンペーン1.:ご来店感謝キャンペーン
Xiaomi Store各店舗公式LINEのお友達登録でXiaomiギフトをプレゼントいたします。
※プレゼントの数量には限りがあります。無くなり次第終了となります。

オープンキャンペーン2.:お買い物キャンペーン
Xiaomi Storeでの購入金額に応じてXiaomiギフトをプレゼントいたします。
※プレゼントの数量には限りがあります。無くなり次第終了となります。

オープンキャンペーン3.:Xiaomi Store オープンセール
セール期間中スマートフォンやタブレット端末、ロボット掃除機などを含む複数製品が最大32%オフでお買い求めいただけます。
※セール期間は製品や店舗によって異なります。

■イベント概要
・イベント   :Xiaomi Storeイオンモール川口店 オープンセレモニー
・開催日    :2025年4月5日(土)
・開催場所   :イオンモール川口
・登壇者/ゲスト:
 イオンモール株式会社 イオンモール川口 ゼネラルマネージャー 東 駿太朗 様
 小米技術日本株式会社 副社長 鄭 彦
 小米技術日本株式会社 プロダクトプランニング本部長 安達 晃彦

Xiaomi Japanについて
小米技術日本株式会社(以下シャオミ・ジャパンと表記)は、Xiaomiの日本現地法人として、2019年12月に日本市場に参入して以来、グローバルで展開する最先端のスマートフォンやIoT製品を数多く販売しています。
シャオミ・ジャパンは、スマートフォンにおいては、SIMフリー市場に加え、2020年よりキャリア市場にも進出し、グローバルでの製品力に加え、ローカライズを推進。フラッグシップモデルからエントリーモデルまで幅広いラインナップにより、消費者のニーズに対応しています。
また、IoT製品においては、スマートバンドやスマートウォッチ、完全ワイヤレスイヤホンなどウエアラブル製品、Xiaomi TVなどAV製品、ロボット掃除機をはじめ、幅広いカテゴリーのスマートホーム製品を多数発売しています。

Xiaomi について
Xiaomi Corporation(以下Xiaomiと表記)は2010年4月に設立され、2018年7月9日(1810.HK)に香港証券取引所のメインボードに上場しました。Xiaomiは、IoTプラットフォームで接続されるスマートフォンとスマートハードウェアを核とした家電およびスマートデバイスを製造する企業です。
Xiaomiは「ユーザーの友となり、最もクールだと”心から”思ってもらえる企業になる」というビジョンを掲げ、イノベーション、高品質なユーザーエクスペリエンス、効率的な運営を追求しています。当社は、世界中の誰もが革新的なテクノロジーを通じてより良い生活を楽しめるように、適正な価格で優れた製品を製造し続けています。
Xiaomiは、世界をリードするスマートフォン関連企業の1つです。2024年9月、自社ファームウェアの月間アクティブユーザー数(MAU)は世界中で約6億8,580万に達しました。当社はまた、世界をリードするコンシューマIoT(AI+IoT)プラットフォームを確立しており、2024年9月30日時点で、8億6,140万台以上のスマートデバイス(スマートフォン、ラップトップ、タブレットを除く)が自社のプラットフォームに接続されています。2023年10月、Xiaomiは「ヒューマン×カー×ホーム」というコンセプトで、パーソナルデバイス、スマートホーム製品、電気自動車をシームレスに融合させるよりスマートなエコシステムを目指し、戦略をアップグレードしました。そして、Xiaomiは常にユーザーを大切にし、より包括的でシームレスな製品体験を提供します。
現在、Xiaomi製品は世界中の100を超える国と地域で販売されています。Xiaomiは2024年8月、6年連続で「Fortune Global 500」にランクインしています。



フラッグシティパートナーズ海外不動産投資セミナー 【DMM FX】入金

Source link

Views: 0

【Pyhton×Excel】Excel自動化 はじめの1歩




本書ではPythonを使ったExcel操作の自動化について解説をします。
「基本的な操作」や「実務を想定した内容」をこの1冊で学ぶことができます。

また、本書からPythonを始める方でも問題ないように、Pythonの始め方や基礎文法も収録しています。

・プログラミングを1から学びたい
・リスキリングして年収を上げたい
・面倒なExcel業務を自動化したい

そんな方は是非ご活用ください。

動作環境
・Windows 11
・openpyxl 3.1.2

※openpyxlは.xlsxファイル(Excel2007以降のExcelファイル)は処理できますが、.xlsファイル(Excel97-2003のExcelファイル)は処理できません。予めご了承ください。

フラッグシティパートナーズ海外不動産投資セミナー 【DMM FX】入金

Source link

Views: 0

デジタルリノタイプマシンのホット – Codepen


タイポグラフィのもの!私はそれを助けることができません、それは私の一部です。私はそれらがリリースされたのを見たとき、または初めて見たときに、見栄えの良い新しい書体をブックマークします(私によると)。これがいくつかです!

ロスリンデール

彼らはそうだと思います キャスロンからこのスローガンを蹴る そして、そうすることはひどく大胆です。ロスリンデールは、さまざまなオプション(可変バージョンを含む)が本当にきれいに見えているので、私はそれでクールです。完全なミニパッケージは200ドルです。そのため、クリスマスに依頼する必要があるかもしれません。

モノヌディカ

彼らが使用するコードエディターのスクリーンショットはです 黒と白だけ 属性のみがあります 大胆な。 見た目は素晴らしく、いつかコーディングを試してみたいと思います。 (しかし、私は自分の構文を強調表示するテーマを書く必要がありますが、もちろん、このフォントはそれを自動的に行いません)。ヌディカは奇妙で上品に見えます(25%セリフのように??)。

Tatsuro

素晴らしい話 この非常に優れた書体の背後。 Tatsuroの見出し、Roslindale Body Copy、Nudicaコードブロック、引用、ハイライトを備えたWebサイトを作りたいと思います。

空港

それはヘルベティカによく似ています…

コンピューターアーツのインタビューで、カーターは次のようにコメントしています。[I]あなたが今日それを見るなら、あなたはヘルベティカの裂け目だと思うでしょう。しかし、1961年にロンドンでヘルベティカを見たことはありませんでしたが、1957年にハース鋳造工場のバーゼル近くのスイスで生産されていました。

ダムナット97

ハードコア。

名前、ダムナット97は、ゴッドダムニットとラファイエットという言葉のマッシュアップです。 Goddamnitは、アルカリトリオの最初のフルレングススタジオアルバムのタイトルであり、ラファイエットは1885年にセントラルタイプファウンドリのGustave F. Schroederがデザインした書体の名前です。


そして今、いくつかの魅力的なホットリンク。

  • 素敵な新しい書体編集 創造的なブームについて。私は特に好きです 公のような、私にはホイットニーのバリエーションのように見えます(しかし、安いです!)。
  • 液体タイプのテイク Tobias Ahlin Bjerromeから、しかしCSSでユーティリティクラスを使用しています。 ライブラリの最終出力 私には少し重く見えますが、プロジェクトが十分に堅牢であれば、私はそれを見ることができました。
  • パフォーマンスの優先順位の方法であるFout(flash of Unstyled Textのフラッシュ)に傾くサイトを設計するとき、それはユーザーがテキストをフォールバックと見なすかもしれないことを意味します フロップオーバー 後で「実際の」フォントに。もしそうなら、 Stoyan Stefanovのこのブックマークレット そのフロッピングを行うのに役立つので、フォントメトリックを適切に取得して、そのエクスペリエンスを可能な限り非jar索することができます。
  • Brecht de Ruyteの4部構成シリーズ 最新のユニットとテクニックを使用したタイプの設定について。

フラッグシティパートナーズ海外不動産投資セミナー 【DMM FX】入金

Source link

Views: 0

色々な言語で作った複数のWASMコンポーネントを連携させる #Go – Qiita



色々な言語で作った複数のWASMコンポーネントを連携させる #Go - Qiita

はじめに

今回は WASI (WebAssembly System Interface) Preview2 という新しいWebAssembly(WASM)仕様で核となる、Component Modelという新しいWASM間の通信インターフェイスを試すべく、Rust・Go・JavaScriptでそれぞれWASMコンポーネントを作成しそれらを連携させてみました。

Component Model について

モジュールの仕様と問題点

WASI Preview1の仕様では、WASMで作成したバイナリはモジュールという、直接WASMランタイムで実行できる形式になっています。

モジュールの問題点として、モジュール間のデータのやり取りは線形メモリを介して行われる方式のため、通信が非常に煩雑になります。線形メモリとは、連続したアドレス空間を持つ単一のメモリ領域、つまり実体はただのバイト配列です。

基本的にどんな型であっても、生のバイト列として線形メモリに格納されます。モジュール間でやりとりするのはメモリに書き込んだバイト列へのポインタだけです。

WASI Preview1 でのモジュール間のデータのやりとり
linear_memory.png

読み取る側のモジュールは、そのポインタから必要なバイト数だけ指定して読み取り、その生のバイト列を解釈する必要があるため、メモリ安全・型安全ではない点、エンコード・デコードの必要な点がデメリットであると言えます。

コンポーネント

そこでWASI Preview2で登場したのが、Component Modelという仕組みです。

Component Modelで登場するコンポーネントとは、従来のWASMモジュールをさらに外側からラップしたような部品です。そしてそのコンポーネントが外部とやりとりするデータの型や、関数などのインポート・エクスポート依存関係を WIT (Wasm Interface Type) というインターフェイス記述言語(IDL)で統一的に定義します。

WASI Preview2のComponent Model
components.png

メリットとして以下のようなものが挙げられます。

  • メモリ安全性
    • コンポーネントが持つWASMメモリには、外界から直接アクセスできない
    • プログラミング言語ランタイムのメモリ管理方法に依存しない
  • 型安全性
    • WITによってやりとりするデータ型を明示的に定義できる
    • 豊富な型が用意されている
  • 統一性
    • 統一的な型、統一的なメモリ管理方法により異なるプログラミング言語で作られたWASMコンポーネント間の連携が容易になる

WIT (WebAssembly Interface Types) について

WITはコンポーネントがどのモジュールをインポート・エクスポートするのか、およびそのモジュールが扱うデータの型はどのような型なのかを定義します。
WITの形式は次のようになっています。

package health-tools:bmi;

interface bmitool {
  calcbmi: func(weight: f64, height: f64) -> f64;
}

world bmi {
  export bmitool;
}

これはcalcbmiというBMI計算関数をエクスポートするコンポーネントのWITです。
WITの構成要素は次のようなものがあります。

  • interface(インターフェイス)

    • やりとりする関数と扱うデータ型をまとめて名前をつけたもの
    • 例では、calcbmiという64ビット浮動小数点型(f64)をとって返す2引数関数を中で定義している
  • world(ワールド)

    • コンポーネントがインポート/エクスポートするインターフェイスや関数などをまとめて宣言する場所
    • 例では、コンポーネントは上のbmitoolインターフェイスを外界にエクスポートすることを宣言している
    • これにより、このコンポーネントの利用者はbmitoolcalcbmi関数をインポート・利用できる

あくまでWITはインターフェイスを定義するものであって、関数の実装は中身であるWASMモジュールにあります。

今回やりたいこと

今回は題材として様々な健康指標の計算関数を提供するコンポーネントを、Rust、Go、JavaScriptの三種のプログラミング言語で作成してみます。以下のようなアーキテクチャでコンポーネント間を連携してみたいと思います。

architecture.png

  • ゲストコンポーネント
    • BMI tool
      • BMI値(ボディ・マス指数)を算出する関数calcBMIをエクスポート
      • Rustで作ります
    • BMR tool
      • BMR値(基礎代謝量)を算出する関数calcBMRをエクスポート
      • Goで作ります
    • Waist tool
      • WHR値(ウェスト・ヒップ比)を算出する関数calcWHRをエクスポート
      • WHtR値(ウェスト・身長比)を算出する関数calcWHtRをエクスポート
      • JavaScriptで作ります
  • ホストコンポーネント
    • 上記3つのコンポーネントをインポートし、利用する側のコンポーネント
    • Rustで作ります

コンポーネントの作成

動作環境・バージョン

  • macOS Sonoma 14.7.3 (M2 Proチップ)
  • Rust 1.85.0
  • Go 1.24.1
  • TinyGo 0.37.0

準備

Cargoで必要ツールのインストール

# wac-cli (https://crates.io/crates/wac-cli)
# wit-deps (https://crates.io/crates/wit-deps-cli)
# wkg (https://crates.io/crates/wkg/) 
$ cargo install wac-cli wit-deps-cli wkg

# wasm-tools (https://github.com/bytecodealliance/wasm-tools) 
# --lockedオプションをつけないとインストール時のビルドが失敗するので注意
$ cargo install wasm-tools --locked

# 今回使用したバージョン
$ cargo install --list                                                           
wac-cli v0.6.1:
    wac
wasm-tools v1.228.0:
    wasm-tools
wit-deps-cli v0.5.0:
    wit-deps
wkg v0.10.0:
    wkg

ビルドターゲットの追加

今回使用するRustのビルドターゲットはWASI Preview2に準拠したwasm32-wasip2です。

$ rustup target add wasm32-wasip2

Wasmtimeのインストール

最後にコンポーネントの動作確認をするために、WASMランタイムであるWasmtimeをインストールします。今回はHomebrew経由でインストールしました。

$ brew install wasmtime

$ wasmtime --version                                                             
wasmtime 31.0.0 (7a9be587f 2025-03-20)

RustでBMIコンポーネントの作成

プロジェクト準備

まずはcargo new --libでライブラリターゲットのプロジェクトを作ります。

# ライブラリターゲットなので--libをつける
$ cargo new --lib bmi-tool

Cargo.tomlのクレートタイプは以下のようにcdylibにしてください。

Cargo.toml

[package]
name = "bmi-tool"
version = "0.1.0"
edition = "2024"

[lib]
crate-type = ["cdylib"]

また、wit-bindgenをインストールします。使用したバージョンは0.41.0です。

wit-bindgenはWITファイルからRustコードの雛形を自動生成するマクロを提供するライブラリです。
WITで定義した関数シグネチャや型情報を自動生成してコードに反映してくれます。

WITの作成

それではWITの作成をしましょう。
プロジェクト直下にwitディレクトリを作り、その中にbmi.witファイルを作成します。VSCodeで開発する場合、WIT IDL拡張機能があると便利です。
WITの内容は次のようになります。

wit/bmi.wit

package health-tools:bmi;

interface bmitool {
  // BMIを計算する関数
  // weight: 体重(kg)
  // height: 身長(cm)
  // return: BMI値
  calcbmi: func(weight: f64, height: f64) -> f64;
}

world bmi {
  export bmitool;
}

関数の実装

wit-bindgenのマクロを使い、関数を実装します。

src/lib.rs

use exports::health_tools::bmi::bmitool::Guest;

wit_bindgen::generate!();

struct Bmi;

impl Guest for Bmi {
    fn calcbmi(weight:f64,height:f64) -> f64 {
        // cm -> m 単位変換
        let height_m = height / 100.0; 
        let bmi = weight / (height_m * height_m);
        bmi
    }
}

export!(Bmi);

ちなみに、wit-bindgenのマクロではなくCLIバージョン(wit-bindgen-cli)を使うという手もあります。CLIツールの場合は、WITからbindings.rsというRustのソースファイルが生成されます。マクロ生成が好みでない場合はこちらを使うこともできます。

ビルド

最後にビルドします。

$ cargo build --target wasm32-wasip2

ビルドに成功すると、target/wasm32-wasip2/debug/bmi_tool.wasmが作成されます。

便宜上、プロジェクト直下にbmi.wasmという名前でコピーしておきます。

$ cp target/wasm32-wasip2/debug/bmi_tool.wasm ./bmi.wasm

wasm-toolsにはコンポーネントのWITを解析する機能があるので、これで調べてみましょう。

$ wasm-tools component wit bmi.wasm

package root:component;

world root {
  export health-tools:bmi/bmitool;
}
package health-tools:bmi {
  interface bmitool {
    calcbmi: func(weight: f64, height: f64) -> f64;
  }
}

きちんとWITが反映されています。これで完成です。

GoでBMRコンポーネントの作成

プロジェクト作成

bmi-toolプロジェクトと同階層のフォルダにbmr-toolというフォルダを作成し、プロジェクトを作成と依存関係のインストールなど行います。

$ ls
bmi-tool

$ mkdir bmr-tool
$ cd bmr-tool
$ go mod init bmr-tool

go.modに以下を追加し、go mod tidyを実行してください。

go.mod

tool go.bytecodealliance.org/cmd/wit-bindgen-go

wit-bindgen-goはWITファイルからGo用にコードを自動で生成するツールです。今回使用したのはv0.6.2です。

WITの作成

同じようにwit/bmr.witを作成し、以下のように記述します。

wit/bmr.wit

package health-tools:bmr;

interface bmrtool {

  // 性別を表す列挙型
  enum gender {
    male,
    female,
  }

  // BMRを計算する関数
  // weight: 体重(kg)
  // height: 身長(cm)
  // age: 年齢
  // gender: `male`(男性) or `female`(女性)
  // return: BMR値
  calcbmr: func(weight: f64, height: f64, age: u8, gender: gender) -> f64;
}

world bmr {
  include wasi:cli/imports@0.2.0;
  export bmrtool;
}

genderは列挙型です。このような高度な型もWASI Preview2では定義できます。

なお、include wasi:cli/imports@0.2.0;という箇所があります。これはWASI標準インターフェイスの一種で、標準出力などの機能を利用する時に使用するものです。
どうもTinyGoのwasip2ターゲットはいかなるコンポーネントの場合でもこの記述を必須にしているらしく、この記述がないとビルド時エラーになってしまいます。
今回はこのコンポーネント単体で実行させることはないため、本当は不要なのですがTinyGoの仕様上必須になるためやむを得ず入れています。

コード生成

今回はwasi:cli/imports@0.2.0があるので、そのWITとバイナリをフェッチしてバンドルする必要があるため、wkgを使います。プロジェクト直下で以下を実行してください。

$ wkg wit build --output bindings.wasm   

するとbindings.wasmwkg.lockというファイルができます。bindings.wasmwasi:cli/imports@0.2.0のバイナリがバンドルされたファイルです。このファイルを基にしてwit-bindgen-goでGoのコード生成してみましょう。

$ go tool wit-bindgen-go generate --world bmr --out internal bindings.wasm

internalフォルダ内にGoのコードが生成されました。

関数の実装

プロジェクト直下にmain.goを作成し、以下のようなコードを作成します。

main.go

package main

import "bmr-tool/internal/health-tools/bmr/bmrtool"

func init() {
	bmrtool.Exports.Calcbmr = func(weight, height float64, age uint8, gender bmrtool.Gender) float64 {
		if gender == bmrtool.GenderMale {
			return 13.397*weight + 4.799*height - 5.677*float64(age) + 88.362
		}
		return 9.247*weight + 3.098*height - 4.330*float64(age) + 447.593
    }
}

func main() {}

ビルド

最後にビルドします。

$ tinygo build --target=wasip2 -o bmr.wasm \
--wit-package bindings.wasm --wit-world bmr main.go

するとプロジェクト直下にbmr.wasmファイルができました。
wasm-toolsで調べてみましょう。

$ wasm-tools component wit bmr.wasm

package root:component;

world root {
  import wasi:cli/environment@0.2.0;
  import wasi:io/error@0.2.0;
  import wasi:io/streams@0.2.0;
  import wasi:cli/stdin@0.2.0;
  import wasi:cli/stdout@0.2.0;
  import wasi:cli/stderr@0.2.0;
  import wasi:clocks/monotonic-clock@0.2.0;
  import wasi:clocks/wall-clock@0.2.0;
  import wasi:filesystem/types@0.2.0;
  import wasi:filesystem/preopens@0.2.0;
  import wasi:random/random@0.2.0;

  export health-tools:bmr/bmrtool;
}

# ===省略===

package health-tools:bmr {
  interface bmrtool {
    enum gender {
      male,
      female,
    }

    calcbmr: func(weight: f64, height: f64, age: u8, gender: gender) -> f64;
  }
}

上では省略されていますが、実際は中間にwasi:cli関連機能のWIT記述があるので長くなっています。

JavaScriptでWaistツールコンポーネントを作成

Node.js環境の準備

bmi-toolbmr-toolと同階層のフォルダにwaist-toolというフォルダを作成、新しいNode.jsのプロジェクトを作成します。
今回はNode.jsのバージョン22.14.0を使用しました。

$ ls
bmi-tool   bmr-tool

$ mkdir waist-tool
$ cd waist-tool
$ npm init
# ウィザードが起動する。全てデフォルトのままでOK

パーケージ名はデフォルトのままwaist-toolとしました。
依存関係にjcoComponentizeJSをインストールします。

$ npm install --save-dev @bytecodealliance/componentize-js @bytecodealliance/jco

jcoはバージョン1.10.2を、componentizeはバージョン0.18.0を使用しました。
これらのツールはWASMコンポーネントを作成する用途で使用されます。

WITの作成

プロジェクト直下にwitフォルダを作り、その中にwaist.witを作成します。

wit/waist.wit

package health-tools:waist;

interface waisttool {
  // ウエスト・ヒップ比(WHR、Waist to Hip Ratio)を計算する
  // waist: ウエストのサイズ(cm)
  // hip: ヒップのサイズ(cm)
  // return: ウエスト・ヒップ比(WHR)
  calcwhr: func(waist: f64, hip: f64) -> f64;

  // ウエスト・身長比(WHtR、Waist to Height Ratio)を計算する
  // waist: ウエストのサイズ(cm)
  // height: 身長のサイズ(cm)
  // return: ウエスト・身長比(WHtR)
  calcwhtr: func(waist: f64, height: f64) -> f64;
}

world waist {
  export waisttool;
}

関数の実装

JavaScriptにはwit-bindgenのようなコード自動生成ツールがないので、手動で実装します。
プロジェクト直下にsrcフォルダを作り、中にwaistTool.jsを作成します。
そして先ほど書いたWITに対応するコードとして次を記述します。

src/waistTool.js

export class WaistTool {
  calcwhr(waist, hip) {
    return waist / hip;
  }
  calcwhtr(waist, height) {
    return waist / height;
  }
}

export const waisttool = new WaistTool();

WITのインターフェイスはJavaScriptではクラスに対応します。またWITのインターフェイスのエクスポートは、JavaScriptではクラスから生成したインスタンスのエクスポートに対応します。

ビルド

jcoを使ってWASMコンポーネントへビルドしてみましょう。

$ npx jco componentize src/waistTool.js --wit wit/waist.wit -o waist.wasm --disable all

プロジェクト直下にwaist.wasmというファイルができたと思います。
--disable allは、WASI標準インターフェイスなどの不要な機能をコンポーネントへ入れないようにするオプションです。

wasm-toolsで確認してみましょう。

$ wasm-tools component wit waist.wasm

package root:component;

world root {
  export health-tools:waist/waisttool;
}
package health-tools:waist {
  interface waisttool {
    calcwhr: func(waist: f64, hip: f64) -> f64;

    calcwhtr: func(waist: f64, height: f64) -> f64;
  }
}

ホストコンポーネントの作成

最後に、上記3つをインポートして利用するコンポーネントであるホストコンポーネントを作りましょう。
bmi-toolbmr-toolwaist-toolと同じ階層のフォルダに、Cargoコマンドでhostというバイナリパッケージを作成します。wit-bindgenもインストールします。

$ ls
bmi-tool   bmr-tool   waist-tool

# バイナリパッケージなので--libをつけない
$ cargo new host

$ cd host
$ cargo add wit-bindgen

WITの作成

プロジェクト直下にwitフォルダを作成してhost.witファイルを以下のように作成します。

wit/host.wit

package health-tools:host;

world host {
  import health-tools:bmi/bmitool;
  import health-tools:bmr/bmrtool;
  import health-tools:waist/waisttool;
}

wit-depsで依存性解決

wit-depsを使ってWITの依存性解決を行うため、deps.tomlを作成して依存関係を定義します。

wit/deps.toml

bmi = "../../bmi-tool/wit"
bmr = "../../bmr-tool/wit"
waist = "../../waist-tool/wit"
cli = "https://github.com/WebAssembly/wasi-cli/archive/v0.2.0.tar.gz"

そしてプロジェクト直下でwit-depsコマンドを実行します。

wit/deps/フォルダに必要なWITファイルが作成されました。

メイン関数の実装

src/main.rsに実装を書きます。

src/main.rs

use health_tools::{
    bmi::bmitool::calcbmi,
    bmr::bmrtool::{calcbmr, Gender},
    waist::waisttool::{calcwhr, calcwhtr},
};

wit_bindgen::generate!({
    // generate_all を指定しないと、wit/depsフォルダの方のWITファイルを反映してくれない
    generate_all,
});

fn main() {
    let weight = 70.0; // 体重 (kg)
    let height = 175.0; // 身長 (cm)
    let age = 30; // 年齢 (歳)
    let gender = Gender::Male;
    let waist = 80.0; // ウエスト (cm)
    let hip = 90.0; // ヒップ (cm)

    // BMIを計算
    let bmi = calcbmi(weight, height);
    println!("BMI: {:.2}", bmi);

    // BMRを計算
    let bmr = calcbmr(weight, height, age, gender);
    println!("基礎代謝量(BMR): {:.2} kcal", bmr);

    // ウエスト・ヒップ比を計算
    let whr = calcwhr(waist, hip);
    println!("ウエスト/ヒップ 比(WHR): {:.2}", whr);

    // ウエスト・身長比を計算
    let whtr = calcwhtr(waist, height);
    println!("ウエスト/身長 比(WHtR): {:.2}", whtr);
}

ビルド

それではビルドします。

$ cargo build --target wasm32-wasip2
# target/wasm32-wasip2/debug/host.wasm が作成される

# 便宜上プロジェクト直下にコピーしておく
$ cp target/wasm32-wasip2/debug/host.wasm ./host.wasm

コンポーネント同士を繋ぎ合わせる

今まで、3つの計算コンポーネントbmi.wasmbmr.wasmwaist.wasm、およびホストコンポーネントhost.wasmを作りましたが、このままでは実行できません。最後にその4つのコンポーネントをwacを使って繋ぎ合わせます。

今まで作った4プロジェクトの親フォルダに移動し、wacコマンドで繋ぎ合わせます。

# 4プロジェクトの親フォルダに移動
$ cd ..
$ ls 
bmi-tool   bmr-tool   host       waist-tool

# 4つのコンポーネントを繋ぎ合わせる
$ wac plug host/host.wasm \
--plug bmi-tool/bmi.wasm \
--plug bmr-tool/bmr.wasm \
--plug waist-tool/waist.wasm \
-o composed.wasm

するとcomposed.wasmが作成されました。ついに完成です!

実行

では実行してみましょう。

$ wasmtime composed.wasm

BMI: 22.86
基礎代謝量(BMR): 1695.67 kcal
ウエスト/ヒップ 比(WHR): 0.89
ウエスト/身長 比(WHtR): 0.46

正常に実行されました。

まとめ

今回はWASI Preview2で定義されたComponent Modelを試してみるべく、Rust、Go、JavaScriptでそれぞれWASMコンポーネントを作成し、WITを記述してコンポーネント間のデータの連携を定義し、コンポーネントを組み合わせて実行してみました。

Component Modelの登場によってWASM間でのデータの連携がかなりやりやすくなったと思います。
現時点では発展途上の技術であるためツールの対応や情報も十分ではありませんが、今後のWASMはコンポーネントの開発を中心に移行していくのではないかと考えています。
今後も注目していきたいと思います。



フラッグシティパートナーズ海外不動産投資セミナー 【DMM FX】入金

Source link

Views: 0