ゲームエフェクトデザイナーのブログ | A Real-Time VFX Artist's Blog

About Making Materials on UE, Making Tools with C#, etc

Helix Core(Perforce)の .NET向けAPIの導入方法 ②

前回に引き続き「Helix Core(旧称 Perforce)」を使ったファイルのバージョン管理の操作を、.NET/C# で制作するWindows Forms Application上で行います。

今回は「P4サーバーへの接続」「ファイルのチェックアウト」「サブミット」です。

f:id:moko_03_25:20200905004620g:plain

下記2つの公式ページをそのまま参考にしました。

Creating pending changelists with P4API.NET 公式のP4API.NET導入記事
Introduction 公式のチュートリアル(最下部がチェックアウトとサブミット)

本記事で解説する内容はこちら。


GUIの作成

まずはデザイナーで適当にUIを作ります。テスト用なので今はこんな感じです。
ワークスペースに接続するための4つの情報を入力するテキストボックスと「接続」「チェックアウト」「サブミット」の3つのボタンを配置しています。

f:id:moko_03_25:20200905005130p:plain


変数の定義

ワークスペースに接続するための4つの情報、編集したいファイルのパス、サブミット時のコメントの変数と、リポジトリ(ディポ)・接続・チェンジリストのオブジェクト変数を定義しておきます。

string P4PORT;
string P4USER;
string P4PASSWD;
string P4CLIENT;

string editFilePath;
string comment;

Repository p4;
Connection con;
Changelist myChange;

ワークスペースに接続する関数の定義

4つのテキストボックスから情報を取得して変数に代入、Repositoryオブジェクトを生成・接続オブジェクトを生成してから接続しています。

public void ConnectWS()
{
    P4PORT = tbServer.Text;
    P4USER = tbUser.Text;
    P4PASSWD = tbPassword.Text;
    P4CLIENT = tbWorkspace.Text;

    Server srv = new Server(new ServerAddress(P4PORT));
    p4 = new Repository(srv);

    con = p4.Connection;
    con.UserName = P4USER;
    con.Client = new Client();
    con.Client.Name = P4CLIENT;

    // Connect
    bool connected = con.Connect(null);
    if (connected)
    {
        try
        {
            // Attempt a Login
            Credential cred = con.Login(P4PASSWD);

            MessageBox.Show("Connect Success!");
        }
        catch (Exception ex)
        {
            MessageBox.Show("Connect Error!");
        }
    }
}

 

ファイルをチェックアウトする関数の定義

ファイルを指定してパスをフォーム上のラベルに表示、チャンジリストをデフォルトチェンジリストではなく新しく作成、ファイルをチェックアウトしています。

public void EditFile()
{
    // Connect
    bool connected = con.Connect(null);
    if (connected)
    {
        try
        {
            editFilePath = @"D:\P4V_WS_Root\Content\testA.png";
            lblFilePath.Text = editFilePath;
            comment = "補助ツールによるチェックアウト";

            // Create a new custom changelist
            myChange = new Changelist();
            myChange.Description = comment;
            myChange = p4.CreateChangelist(myChange);
            FileSpec editFile = new FileSpec(new LocalPath(editFilePath));
            Options editOptions = new Options();
            editOptions["-c"] = String.Format("{0}", myChange.Id);

            try
            {
                // Open the file for edit
                p4.Connection.Client.EditFiles(editOptions, new FileSpec[] { editFile });
            }
            catch (P4Exception e)
            {
                Console.WriteLine("Couldn't open file for edit!\n {0} : {1}", e.ErrorCode, e.Message);
            }

            MessageBox.Show("Edit Success!");
        }
        catch (Exception ex)
        {
            MessageBox.Show("Edit Error!");
        }
    }
}

ファイルをサブミットする関数を定義

チェンジリストオブジェクトのサブミット関数を実行している一行で済みますが、その前にフォームのコメント入力欄から文字列を取得してコメントを上書きしようとしています。

単純に「myChange.Description = comment;」ではうまくいかないようです。

public void SubmitFile()
{
    // Connect
    bool connected = con.Connect(null);
    if (connected)
    {
        try
        {
            // Submit the edit
            comment = tbComment.Text;
            myChange.Description = comment;
            myChange.Submit(new Options());

            MessageBox.Show("Submit Success!");
        }
        catch (Exception ex)
        {
            MessageBox.Show("Submit Error!");
        }
    }
}

そして p4miscさんに解決策を教えていただきました(ありがとうございます!)

こちらのように GetChangelist で再取得して UpdateChangelist で更新してやれば良いようです。そしてこちらでうまくいきました!

public void SubmitFile()
{
    // Connect
    bool connected = con.Connect(null);
    if (connected)
    {
        try
        {
            // Submit the edit
            comment = tbComment.Text;
myChange = p4.GetChangelist(myChange.Id); myChange.Description = comment;
p4.UpdateChangelist(myChange); myChange.Submit(new Options()); MessageBox.Show("Submit Success!"); } catch (Exception ex) { MessageBox.Show("Submit Error!"); } } }

ボタンクリックイベント

ここは、ボタンに対応した関数を実行しているだけです。

private void bConnect_Click(object sender, EventArgs e)
{
    ConnectWS();
}

private void bEdit_Click(object sender, EventArgs e)
{
    EditFile();
}

private void bSubmit_Click(object sender, EventArgs e)
{
    SubmitFile();
}

 

次回以降は下記のあたりに手を入れたいと思います。

・コメントを入力した文字列に変える処理
・接続情報はオプション設定画面に移してメインフォームをコンパクトに
・接続情報とコメント情報の記憶と次回起動時の復元
・フォーム起動時に自動接続
・フォーム上へのファイルのドラッゴ&ドロップ対応
・ドラッグ&ドロップと同時にチェックアウト
・リバートボタン追加
・コメントにヘッダ専用テキストボックスを追加
・コメントをテンプレートから選択可能に


今回は以上です!