- 投稿日:2019-03-07T21:55:34+09:00
StyleCop.AnalyzersをCLIで使いたい
結論から言うと
今はできませんが、動くものを開発中です
StyleCop.Analyzers とは
RoslynベースのC#のコードに対する静的解析ツールです。
コーディング規約に違反していないかをチェック/修正まで行ってくれます
.NET Core/Roslyn などと同じくOSSとして公開されています
StyleCop.Analyzers使用方法
VisualStudio/Rider などの統合開発環境を使用している場合は容易に使用できます
導入方法は VisualStudioであれば、NuGet Package Managerなどから導入可能です
残念ながらVS CodeはサポートされていませんCLIで動かす同期
CIやgit commit hookなどでチェックしたいからです
その他に筆者はVS Code派なので...
特にコーディング規約に関わることはレビューで指摘するのは不毛ですので、
出来る限りPull/Merge Requestなどが上がった時点で自動的にチェックしたいという思いがありますCLIで動くStyleCopのツール郡は存在している
StyleCop.Analyzersの前身プロジェクトで、StyleCopというものがあります
StyleCopStyyleCop自身はCLIで動作し、静的解析としては必要十分な条件を満たしています
ただし、既に死んでいるプロジェクトです
StyleCop.Analyzersは開発が続けられており、新しいルールなども追加されています
また、StyleCopにはコードを修正する機能はありませんが、StyleCop.AnalyzersにはありますStyleCop.AnalyzersのCLIツールはあるのか
現時点ではありません
ただし、以下のようなIssuも上がっており、そのうち正式にサポートされるかもしれません
CLI?ですが、いつ実装されるかもわからないものを待つのは辛いです
何度かトライして諦めていた
実は結構前からトライしていたのですが、StyleCop.Analzyersをビルドするために
.NET Frameworkが必要でした
.NET FramworkはWindowsしかサポートしておらず、Mac/LinuxではStyleCop.Analyzersと依存しているライブラリ群をビルドしようとするとエラーとなり諦めていましたが、ようやく周辺環境も整ってきてビルドできるようになりました
Microsoft.Build.Locatorはβ版ではありますが使用できますなので作ってみた (まだ出来上がっていない)
進捗率は50%程度ですが、以下のように出力することができました
試しに解析してみたのは、gRPCのC#のソースコードですdotnet StyleCopAnalyzersCmd.dll -d ./grpc/src/csharpというようなコマンドで使えるようにしたいなと思ってますが、コマンド名がダサいので何か良い案があれば...
余談
まだチェックだけで、コードの修正までは出来ていませんが、チェック処理がある程度ものになった時点で公開したいと思います
CLIツールを作るのに、CySharpさんのMicroBatchFrameworkが非常に便利ですGitHubに公開する際にはこのツールを作るための苦労話なども記載しないと思います
StyleCop.Analyzersの機能の全てがinternalで容易にアクセスできないのが非常に辛い。。。
- 投稿日:2019-03-07T00:56:48+09:00
ObserverをUnityで使ってみようと頑張った話
interfaceすらふわっふわな人が書いてるので間違いが(たぶん)沢山あります。
目標:UnityでObserverパターンをつかってなにか動くものを作る
作るもの:入力された情報が変更されるたびに、動くScrollView
まず、作ってみたObserver
TextObserver.csusing System.Collections; using System.Collections.Generic; using UnityEngine; namespace My{ public interface ITextObserver<T>{ void Notify(string s); } class ShowGetText<T> : ITextObserver<T>{ public void Notify(string s){ Debug.Log(s); } } public class GetText<T> : ITextObserver<T>{ public void Notify(string s){ } } public interface ITextSubject<T>{ void AddObserver(ITextObserver<T> observer); void RemoveObserver(ITextObserver<T> observer); void NotifyObserver(string s); } public class TextOvserver<T> : ITextSubject<T>{ private List<ITextObserver<T>> _observeList = new List<ITextObserver<T>>(); public void AddObserver(ITextObserver<T> observer ){ _observeList.Add(observer); Debug.Log(observer); } public void RemoveObserver(ITextObserver<T> observer){ _observeList.Remove(observer); } public void NotifyObserver(string s){ _observeList.ForEach(o => o.Notify(s)); Debug.Log("Hello"); } } }つぎに、変化をするSubject側
TextSender.cspublic class TextSender : MonoBehaviour { public My.ITextS  ubject<string> Subject{get;} = new My.TextOvserver<string>(); string[] IN_Text = new string[3]; [SerializeField] int index; void Start(){ index = 0; IN_Text[0] = "ラットに20ダメージを与えた"; IN_Text[1] = "ピカピカの薬を手に入れた"; IN_Text[2] = "ラットから30ダメージを受けた"; } // Update is called once per frame void Update() { if(index>2){ index=0; } if(Input.GetMouseButtonDown(1)){ Subject.NotifyObserver(IN_Text[index]); ++index; } } }マウスの右クリックをするたびに文章が変わって0~2でループする。
これを空のGamaObjectに貼り付ける。最後にCanvasのScrollViewに下記のプログラムを貼り付ける
TextShow.csusing System.Collections; using System.Collections.Generic; using UnityEngine; using UnityEngine.UI; public class TextShow : MonoBehaviour,My.ITextObserver<string> { [SerializeField] public TextSender _test; [SerializeField] private ScrollRect scrollRect; [SerializeField] private Text textLog; private string GetText; public RectTransform originalElement; public RectTransform content; int elementNum; void Awake(){ originalElement.gameObject.SetActive(false); } void Start() { scrollRect.verticalNormalizedPosition = 0; _test.Subject.AddObserver(this); textLog.text = GetText; elementNum = 15; } void Update() { if(GetText != textLog.text && GetText != null){ OnSubmit(); DeleteText(); } } public void OnSubmit(){ textLog.text = GetText; Debug.Log(textLog.text); var element = GameObject.Instantiate<RectTransform> (originalElement); element.SetParent(content, true); element.SetAsLastSibling(); element.gameObject.SetActive(true); --elementNum; } public void DeleteText(){ var clones = GameObject.FindGameObjectsWithTag("Element"); if(elementNum <= 0){ Destroy(clones[elementNum]); ++elementNum; } } public void Notify(string s){ GetText = s; } public string OnRecieved(string value){ Debug.Log(value); return value; } }15まで表示で一番古いデータを一つづつ破壊。
NotifyでTextSenderで持っているテキスト内容が変化した文面を教えてくれる。
教えてくれたstring sをGetTextに入れてtextLog.textと内容が違ったらScrollViewに表示みたいな流れになっているはず。
出力された文面はElementのタグを付けたImageが保持するので強制的に分離させるみたいな構造なんだと思う……上記の様に設定。
成果:まだ全然わからん!でもとりあえず、動くものは作れた。
反省:アイテム取得とかダメージとかのメッセージを表示したいと思って色々漁った末にこんな物が出来上がりました。Notifyのところとかなにか使い方間違えている気がするし、Removeの使い所はどうすれば良いのかとかふわっとしている部分は色々ある。TextSenderに情報を集めればアイテム取得やダメージ表示できそうって思っているんだけどTextSenderに集めようとすると2重Observerみたいになってしまうからなにか考え方が間違ってる気がしている。
CやC++はかじったことあるけどC#全然わからない。
interfaceなにそれ!の状態から4日ぐらいかけて勉強。
Observerパターンを初めて組んでみた。ほとんどテラシュールブログさんの
http://tsubakit1.hateblo.jp/entry/2015/10/19/022720
と
人生詰んでるし死ぬ前にゲーム作ってみるさん
http://ntgame.wpblog.jp/2018/07/14/post-1796/
の上2つの記事を素人がいじくり回した結果です。勉強はとりすーぷさんのQiitaや動画、スライドを参考にさせていただきました。
https://learning.unity3d.jp/1324/
上の動画の説明が分かった気に一番なりました!※なにか問題がある部分があれば削除訂正しますのでメールかTwitterまでお願いします。

