きよくらの備忘録

「三日坊主と呼ばせない!日記」改め。主にソフトウェア開発関連の話題。

arcade1up:全体的な構造についての所感やLCD パネル部の構造と(雑な)寸法など

先日購入したarcade1upギャラガ、なかなか全体を開封して組み立てる時間はないので取り急ぎディスプレイ部だけ開梱して分解・採寸したりしたのでメモ。

 

【各部品の名称は、付属の組み立て説明書に準じます(オフィシャルサイトでPDFで提供されています: https://arcade1up.jp/ のページ下部のリンクを参照)】

全体の構成

基本的には12mm程度のMDFで組まれた中空の箱です。 電気的に動作する部品は「LCD パネル(ディスプレイパネルの部分)」と「コントロールユニット(ジョイスティックなどの部分)」の部分の二か所。

CPUとかROMといった心臓部はLCD パネルにくっついています(後述)。 コントロールユニットはMDFの板に樹脂製のボックスがとりつけられていて、その中にはスイッチ類の他にスピーカーが組み込まれています。

いわば『中空の箱に薄いLCDとコントロールパネルが付いてるだけ』、といった構造のた非常にシンプルで空間に余裕がある筐体です。 排熱の対策さえできればラズパイやコンシューマゲーム機はおろかミドルタワークラスのPCでも仕込むのは難しくなさそうです。

f:id:kiyokura:20200922101038p:plain
背面から見た内部の様子(添付の組み立て説明書より抜粋、背面パネルは未取り付けの状態)

MDFなのであまり頻繁なネジの開け閉めはしないほうが良いと思いますが、木材なので加工も比較的容易ですからメンテナンスハッチを付けるなどやりようはいくらでもありそうです(そのうちやりたい)。

 

何にせよ、DIYでぼちぼち手を入れて改造していくには格好の素体だと感じています。

 

LCD パネル部の外観

表面はこんな感じ。17インチディスプレイが垂直レイアウトでベゼルに収まってる感じです。 f:id:kiyokura:20200922020404p:plain

こちらが裏側。 f:id:kiyokura:20200922020656p:plain

LCDの真ん中あたりにへばりついている生えた長方形の箱が、LCDのコントローラー(ドライバー)やらROMやらが入った、いわばこのarcade1upの本体というべきユニットです。

 

LCDの素性

LCDのラベルに「M170ETN01 1」というモデル名?のようなものが印字されているので調べてみると、どうやらOEM向けとして販売されているLCDモジュールのようです。世間では(?)「M170ETN01.1」で通っているようで、TFT方式で解像度は1280x1024…などといった情報が出てきました。 通販サイトなどでも$50から$90くらいで販売されているようで、万一つぶしてしまっても同じものは比較的容易に手に入りそうではあります。

またHDMI等の汎用的な映像入力を受け付けて駆動するLCDドライバモジュールなども通販で容易に手に入るようです(これについては後日あらためて触れる予定)。このたりも改造したいとしての素性の良さを感じます。

 

LCD パネル部の構造

LCD パネル部は大雑把に以下の3つで構成されています。

  • 透明パネル(アクリル……かもしかしたらPETかも?厚みは2mm程度)
  • LCD(と本体)
  • ベセル(MDF/12mm程度)

これらが適宜ねじ止めされています。

またベゼルは中央に穴があるだけではなくLCDの耳(?)を固定する部分が凹モールドになっています。 ざっくり図示するとこんな感じ。 f:id:kiyokura:20200922020131p:plain

断面図だとこんな感じです。 f:id:kiyokura:20200922020953p:plain

非常にシンプルで合理的な構造だと思いました。

 

採寸

LCD パネルの箱(だけ)を開梱したついでに、ざっくり採寸してみました。

f:id:kiyokura:20200922232354p:plain
arcade1up ギャラガ筐体LCDパネル部のだいたいの寸法

ただし、ノギスや指金がすぐ手元になくたまたまポケットに入ってたメジャーで雑に測っただけですので、あまり鵜呑みにはしないで欲しいなと思います*1

*1:「信じてカットしたのに合わなかった!」などと言われても責任取れません……

arcade1upのギャラガを買った

8末のことではあるのですが、arcade1upのギャラガを購入しました。

ARCADE1UP|株式会社タイトー

 

発売当初からずっと欲しかったのですが、今年の8月に入ってふと気が付いたら元々6万円ほどだったはずの定価が29,800円になっており且つ一部で期間限定という噂もあり(真偽不明)、『この価格で液晶画面付きのコンパクトでいじり易そうな(ここ重要!)アーケードゲーム筐体が買える』と考えればまあお得だな、と踏ん切りをつけました。

 

実物の3/4サイズでコンパクト……とは言え一人では少々持ちにくいサイズと形状で重量も25kgほどだったため、(こっそりと)二階に持って上がるのはしそれなりにしんどかったりしつつ。 一部の部品については開封はしたもののまだ組み立てや通電はしておらず、半倉庫状態になってる一室に置かれたままだったり。 f:id:kiyokura:20200922014527p:plain

 

今後やろうと思っているのはこのあたり:

  • ディスプレイの横置き化&汎用入力化
  • スピーカーのステレオ化
  • コントロールパネルの汎用2L12B化

まあ、ぼちぼち弄っていこうかなと思ってます。

 

(それはそれとして、カプコン版権のヤツは今からでも国内販売して欲しいです特にMarvel Super HeroesとかMarvel Super HeroesとかMarvel Super Heroesとか)

CLIツールを使わずにコード中からプロジェクトをビルドしたりdacpacをデプロイしたりする(その2)

前回の続きです。

Microsoft.SqlServer.DACFx でdacpacをデータベースにデプロイする

続いて、出来上がったdacpacファイルから Microsoft.SqlServer.DACFx を使ってデータベースにデプロイしてみる。

www.nuget.org

上記NuGetッケージを取り込んだ上で、以下のコードでごくシンプルに実現できた。

var connectionString = "<デプロイ先データベースに接続するための接続文字列>";
var databaseName = "<デプロイ先のデータベース名>";

var dac = new DacServices(connectionString);
var dacpac = DacPackage.Load(@"C:\hoge\output.dacpac");
dac.Deploy(dacpac, databaseName , true);

まとめ

以下、前回のエントリも含めてまとめる。

  • CLIツールを使用せず、NuGetで提供されているパッケージを利用することで.NETのコードだけでプロジェクトdacpacの生成とデプロイが可能
  • 今回参照したパッケージは以下
  • Microsoft.Build.Evaluation.ProjectクラスBuildメソッドによるプロジェクトのビルドについてのメモ:
    • ビルド成否はboolで返る
    • ビルドログは引数として渡したロガー経由で取得する必要がある
    • SetPropertyメソッドでプロパティをコード中から設定することが可能
    • sqlproj をビルドしてdacpacを生成する場合は Microsoft.SqlServer.DacFx の参照が必要
  • Microsoft.SqlServer.Dac.DacServicesクラスDeployメソッドによるdacpacのデプロイについてのメモ:
    • DacPackageクラスのLoadメソッド でdacpacをロードし、Deployの引数に設定してデプロイする

サンプルコード

今回検証したサンプルコードを以下に公開した github.com

CLIツールを使わずにコード中からプロジェクトをビルドしたりdacpacをデプロイしたりする(その1)

先日、こんなエントリを書いた。 kiyokura.hateblo.jp

要約すると『コード中からMSBuild.exeを使ってプロジェクトファイルからdacpacをビルドして、それをSqlPackage.exeを使ってデプロイする』という内容である。 上記エントリではMSBuildやSqlPackageを利用するために割と無理やり泥臭くそれらのパスを取得しているところがなんだかアレであったり、そもそもローカルの環境に事前にインストールされているものに強く依存しているあたりもアレだったりするので、そのあたりで若干悶々としていた。

そんな折にこの上記内容をチームのメンバに展開したところ、優秀なチームメンバから

  • SqlPackage.exeのところDacFxで置き換えれるのではないか?
  • MsBuild.exeのところはMicrosoft.Build.Evaluation 名前空間のライブラリで置き換えれるのではないか?

という素晴らしい指摘をいただいた。 ので、さっそく試してみることにした。

Microsoft.Build.Evaluation でプロジェクトをビルドする(その1:csproj編)

Microsoft.Build.Evaluation名前空間の機能は主に NuGetパッケージ の Microsoft.Build で提供されている模様。 www.nuget.org

早速、新規にコンソールアプリを作成して上記パッケージを取り込み、以下のようなコードで別のシンプルなクラスライブラリのビルドを試みた。

var p1 = ProjectCollection.GlobalProjectCollection.LoadProject(@"C:\MyClassLib\MyClassLib.csproj");
p1.Build();

だが、上記コードでコンパイルは通るのだがBuild()メソッド実行箇所で以下の例外が発生した。

Microsoft.Build.Shared.InternalErrorException
  HResult=0x80131500
  Message=MSB0001: Internal MSBuild Error: Type information for Microsoft.Build.Utilities.ToolLocationHelper was present in the whitelist cache as Microsoft.Build.Utilities.ToolLocationHelper, Microsoft.Build.Utilities.Core, Version=15.1.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a but the type could not be loaded. unexpectedly null
  Source=Microsoft.Build

調べてみるとビルド実行には Microsoft.Build.Tasks.Core パッケージも必要になる模様。

www.nuget.org

これのパッケージを追加すると無事に上記コードでクラスライブラリが生成された。

Microsoft.Build.Evaluation でプロジェクトをビルドする(その2:sqlproj編)

次は同様にSQL Server Databaseプロジェクトのビルドを試みるため、以下のようなコードを実行してみた。

var p2 = ProjectCollection.GlobalProjectCollection.LoadProject(@"C:\MyDataBase\MyDataBase.sqlproj");
p2.Build();

しかし実行で例外などは発生しないものの、成果物が生成されていなかった。 少し調べてみると以下のことが分かった。

  • 実行されたビルドが失敗に終わっても例外は発生しない(Buildメソッドの実行自体は成功してるのでそれはそうだろう)
  • ビルドの成否はBuildメソッドの戻り値としてbool値で返される
  • ビルドの実行ログはBuildメソッドにロガーを渡すことで取得できる
    • ロガーは Microsoft.Build.Framework.ILogger の実装である必要がある
    • 既定でFileLoggerやConsoleLoggerが実装されている

という事で、以下のようにコードを書き換えて再度実行してみた。

var p2 = ProjectCollection.GlobalProjectCollection.LoadProject(@"C:\MyDataBase\MyDataBase.sqlproj");
var p2Result = p2.Build(new[] { new ConsoleLogger() });
Console.WriteLine($"p2 result : {p2Result}");

すると以下のようなビルドエラーが出力された。つまるところSQL Server Databaseプロジェクトをビルドするためのtarget、Microsoft.Data.Tools.Schema.SqlTasks.targets が参照しているアセンブリが足らない(見れていない)模様だ。

C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\MSBuild\Microsoft\VisualStudio\v16.0\SSDT\Microsoft.Data.Tools.Schema.SqlTasks.targets(491,5): error MSB4062: The "SqlModelResolutionTask" task could not be loaded from the assembly C:\Program Files (x86)\Microsoft Visual Studio\2019\Enterprise\Common7\IDE\Extensions\Microsoft\SQLDB\Dac\150\Microsoft.Data.Tools.Schema.Tasks.Sql.dll. アセンブリ 'Microsoft.Data.Tools.Schema.Tasks.Sql, Version=16.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a' からの型 'Microsoft.Data.Tools.Schema.Tasks.Sql.SqlBuildTask' にあるメソッド 'get_BuildEngine' に実装が含まれていません。 Confirm that the declaration is correct, that the assembly and all its dependencies are available, and that the task contains a public class that implements Microsoft.Build.Framework.ITask.

しばらく悩んだのだが、ふと「Microsoft.Data.Tools.Schema.Tasks.Sql.dllとかってDacFxのパッケージに含まれてるちゃうか??」と思い、Microsoft.SqlServer.DACFx をインストールして再度実行してみた。 www.nuget.org

すると、以下の通りビルドが成功し、dacpacファイルも生成されていた。 f:id:kiyokura:20200916225548p:plain

さらに、ビルドスクリプトのプロパティを設定してdacpacを出力先を任意に任意の名前で出力することもできた。

var p2 = ProjectCollection.GlobalProjectCollection.LoadProject(@"C:\MyDataBase\MyDataBase.sqlproj");
p2.SetProperty("OutputPath", @"C:\hoge\");
p2.SetProperty("SqlTargetName", "output");
var p2Result = p2.Build(new[] { new ConsoleLogger() });
Console.WriteLine($"p2 result : {p2Result}");

f:id:kiyokura:20200916230246p:plain

続く

ちょっと長くなったので今回のエントリはいったんここまでとする。 次回はMicrosoft.SqlServer.DACFxを利用したdacpacのデプロイについて書く予定だ。

SQL Server データベースプロジェクトでSSDTの単体テスト機能を使わずに単体テストを行うアレコレ(主にデプロイ面の話)

前書き:SQL Server データベースプロジェクトはとても便利なのだけどSSDTの単体テスト機能は割と辛みがあるでNUnitとかxUnitとかでやりたい

いくつかの案件で、Visual StudioのSQL Server データベースプロジェクト*1(以下、DBプロジェクト)を用いてSQL Server上の各種オブジェクトの開発や構成管理を行っている。その開発・保守に際して、ストアドプロシージャや関数等のいわゆる自動単体テスト*2を行いたい要求があった。

SQL Server Data Tools(以下、SSDT)ではDBプロジェクトの単体テスト機能も提供しており、このSSDTの単体テスト機能はそれなりに便利で手軽ではある……のだが、私は現在ではあまり利用していない。

当初はそれなりに使ってはいたのだが、このSSDTの単体テスト機能の少々使い勝手が微妙な部分が、使い込むにしたがって許容できない判断するに至った。そのため現状はNUnitなどを用いてC#のコードからテスト用のデータベースに接続してテストするという手法に落ち着いている。

テスト対象オブジェクトのデータべースへのデプロイをどうするかという問題

単体テスト自体にSSDTは利用しないものの、DBプロジェクト内のソースをデータベースにデプロイするのは正直とても楽なので、その部分だけ無理やり(?)使っていた。

……いたのだが、紆余曲折あり*3、デプロイにもなるべく……少なくとも単体テストのプロジェクトから直接SSDTのクラスを参照するのは避けたいという思いが強くなった。

そこで代わりの方法を模索することにした。

達成したいポイントは以下だった。

  • SSDT関連のアセンブリに直接依存しない(プロジェクトからアセンブリ参照しない)
  • 事前に手動操作など挟まず単体テスト実行時に自動でDBプロジェクト内のソースを任意のデータベースにデプロイしたい

今回やってみたこと

前置きが長くなったが、これらを解決するために以下を試してみた。

  • 単体テストのセットアップ中に以下を行うことでDBにソースからオブジェクトをデプロイする
    • MSBuildをキックしてDBプロジェクトからdacpacを生成
    • SqlPackage.exeでデータベースに発行
  • MSBuild.exeと SqlPackage.exeを単体テストのSetupから実行するためのこれらのパスの解決を以下の方法で実施
    • 単体テストプロジェクトのビルド時、ビルド後イベントでVSのマクロ変数から拡張機能のインストールパスを取得、テキストファイルに書き出す
    • 単体テストのセットアップ時に前述のテキストファイルを読み出す

【2020.09.16追記】

コマンドラインツールそのものを実行するのではなく、NuGetで提供されているライブラリを利用して同等のことができるのを確認しました。 そのうちブログに書きます。

書きました!https://kiyokura.hateblo.jp/entry/2020/09/16/230331

コマンドラインツールによるビルドとデプロイ

DBプロジェクトはMSBuildでビルドすると普通にdacpacを生成するので、MSBuild.exeのパスさえわかれば特に問題はない。

これについては、先日のエントリ https://kiyokura.hateblo.jp/entry/2020/09/01/114511 を参照。

またSSDTで同時にインストールされるSqlPackage.exeを利用すればdacpacをデータベースへデプロイすることが可能で、これもSqlPackage.exeのパスさえわかれば問題ない。

こちらについては https://kiyokura.hateblo.jp/entry/2020/09/01/154255 を参照。

コマンドラインツールのパスの解決

少し考える必要がったのは、MSBuildやSqlPackgeの実行パスの取得方法である。 設定ファイルなどに個別に書いても良いが、当然実行環境ごとにパスは異なる可能性は当然あり(VS2017以降ではVSのバージョンだけでなくエディションによっても拡張機能インストールパスが異なる)、リポジトリの管理などでも別途考えることが出てくるので避けたかった。

そこで思いついたのがビルドイベント。ここであれでば $(MSBuildBinPath)$(DevEnvDir) などでビルドのタイミングでその環境で有効なパスが取得できるので、例えば以下のようにしてやればあとは単体テスト実行時に読んでやれば良い。

echo $(MSBuildBinPath)\msbuild.exe > "$(TargetDir)msbuildpath.txt"
echo $(DevEnvDir)Extensions\Microsoft\SQLDB\DAC\150\sqlpackage.exe > "$(TargetDir)sqlpackagepath.txt"

サンプルプロジェクト

これらを実際に組み込んだサンプルプロジェクトを以下に置いてたので、興味ある方は見ていただければ。

github.com

(ちなみに上記サンプルでは、データベースには SQL Server LocalDBを利用し、テスト実行時にその都度データベースインスタンスとDBを作り直してまっさらな状態でテストするようにしています)

*1:「Visual StudioのSQL Server データベースプロジェクトとは?」という方は https://docs.microsoft.com/ja-jp/sql/ssdt/project-oriented-offline-database-development?view=sql-server-ver15 や手前みそですが https://www.slideshare.net/kiyokura/sql-server-238387166/kiyokura/sql-server-238387166 など参照していただければと

*2:コードでテストを記述してテストランナーとかで実行するアレ

*3:書くと長くなりそうなので割愛