Diarkis Module のカスタイマイズ

本ページでは directmessage_simple サンプルからコードの一部を紹介し Diarkis Module をカスタマイズして利用する方法を説明します。 実際のサンプルのソース・コードは samples\directmessage_simple\directmessage_simple.cpp に配置されています。

Diarkis Module の各機能のカスタマイズ

利用したいモジュールにアプリケーション専用の処理を組み込みます。例えば Room に参加したタイミングや Room からメンバーがいなくなったことをアプリケーション側で認識して UI を更新する、といったことが可能です。 directmessage_simple では他のユーザーから 1 度でも何かメッセージを受信したかどうかを判断するために Diarkis Module の DM 機能をカスタマイズしています。 Diarkis Module の機能をカスタマイズするには各機能のベース・クラス(DiarkisModuleNameBase)を継承します。DM 機能は DiarkisDirectMessageBase に実装されており、サンプルではこのクラスを継承して必要な処理を実装します。 以下のコードが実際の実装の一部となります。

/*
 * DirectMessage 関連の処理をアプリ側でカスタマイズするための実装。
 * DirectMessage 関連のデータを受信した際に On... 系のコールバックが発火するため、アプリが処理したい内容を実装します。
 * 本サンプルでは取得したメッセージをコンソールへ表示しています。
 */
class DirectMessageSimple : public DiarkisDirectMessageBase
{
public:
    DirectMessageSimple() : DiarkisDirectMessageBase() {}
    virtual ~DirectMessageSimple() {}

    bool IsAnyMessageReceived() const
    {
        return anyMessageReceived_;
    }
private:
    /**
     * @~japanese
     * @brief DirectMessage の通知を切断する際に呼ばれるコールバック・イベントを取得する。
     * @details DirectMessage Disconnect の通知 ( サーバーからの Push ) が送られた際に呼ばれる。
     * @~
     */
    virtual void OnDisconnect(const DiarkisDirectMessageEventArgs& e) override
    {
        ...
    }

    /**
     * @~japanese
     * @brief 他のリモート・ユーザーから DirectMessage が送られてきた際に呼ばれるコールバック・イベントを取得する。
     * @details DirectMessage Message の通知 ( サーバーからの Push ) が送られた際に呼ばれる。
     * @~
     */
    virtual void OnMessage(const DiarkisDirectMessageEventArgs& e) override
    {
        ...
        anyMessageReceived_ = true;
    }
private:
    bool anyMessageReceived_ = false;
};

DiarkisDirectMessageBase には主に DM 機能を使用するためのインターフェイスとイベントを受け取るためのインターフェイスが定義されています。DM 機能を使用するためのインターフェイスでは DM の機能を呼び出す前に特定の処理を実行するような用途に使用することができます。一方のイベントを受け取るためのインターフェイスでは DM 機能でメッセージを受信したときなど、何かイベントが発生したときの通知に対する処理を実装することができます。 サンプル実装では DM でメッセージを受信したときに発火する DiarkisDirectMessageBase::OnMessage をオーバーライドし、メッセージを受け取ったかどうかを保存しています。

DiarkisInterfaceBase のカスタマイズ

Diarkis Module を使用した場合、各機能を実装しているクラスのインスタンスはすべて DiarkisInterfaceBase クラスが管理しており、インスタンスの生成も DiarkisInterfaceBase の内部で行われます。ベース・クラスをカスタマイズした場合、DiarkisInterfaceBase 内で生成されるインスタンスのタイプを変更する必要があるため、DiarkisInterfaceBase を継承しカスタマイズされた DiarkisInterfaceBase クラスを実装します。以下がサンプル実装の一部となります。

/*
 * DirectInterface が内部で管理する各機能のモジュールをアプリ固有のものに置き換えるために DiarkisInterfaceBase を継承したクラスを実装します。
 */
class DiarkisInterfaceDirectMessageSimple : public DiarkisInterfaceBase
{
public:
    ...

    void SetupDirectMessage(void)
    {
        if (tcpBase_ != nullptr && tcpBase_->Get() != nullptr)
        {
            // アプリ側でカスタマイズしたクラスを作成します。
            if (dmBase_ == nullptr)
                dmBase_ = Diarkis::DiarkisAllocShared<DirectMessageSimple>();

            // DirectMessage クラスを初期化してコールバック・イベントを登録
            dmBase_->SetupTcp(tcpBase_->Get(), this->GetLoggerFactory());
        }

        if (udpBase_ != nullptr && udpBase_->Get() != nullptr)
        {
            // アプリ側でカスタマイズしたクラスを作成します。
            if (dmBase_ == nullptr)
                dmBase_ = Diarkis::DiarkisAllocShared<DirectMessageSimple>();
            // DirectMessage クラスを初期化してコールバック・イベントを登録
            dmBase_->SetupUdp(udpBase_->Get(), this->GetLoggerFactory());
        }
    }

    std::shared_ptr<DirectMessageSimple> GetDirectMessage()
    {
        return std::static_pointer_cast<DirectMessageSimple>(GetDirectMessageBase());
    }
};

各機能のインスタンスの生成は DiarkisInterfaceBase::Setup... で行われます。DM 機能のインスタンスは DarkisInterfaceBase::SetupDirectMessage() で行われるためこのメソッドをオーバーライドしてユーザーがカスタマイズした DM 機能のクラスを生成します。また、あわせてカスタマイズした型で DM 機能のインスタンスを取得できるメソッドも追加しています。

これらのカスタマイズしたクラスを使用することで、Diarkis Module へアプリケーション固有の処理を組み込みカスタマイズすることができます。

std::shared_ptr<DiarkisInterfaceDirectMessageSimple> diarkis;

...

// Diarkis のすべての機能にアクセスするために DiarkisInterface を継承したクラスを作成します。
diarkis = Diarkis::DiarkisAllocShared<DiarkisInterfaceDirectMessageSimple>(uid);

...

std::shared_ptr<DirectMessageSimple> dm = diarkis->GetDirectMessage();

...

// 簡易的なタイミング合わせの実装です。
// "2222" から初回のメッセージが到達したタイミングで "1111" からのデータの送信も開始します。
while (!dm->IsAnyMessageReceived())
{
    std::this_thread::sleep_for(std::chrono::milliseconds(1000));
}

注意点

Diarkis Module がソース・コードで提供されているという性質上、ベース・クラスを継承せず直接変更することでも同じようにカスタマイズすることは可能です。しかし、Diarkis Module のソース・コードはバージョンアップ時に大きく変更される可能性があり、マージが困難になることが想定されます。 こういった状況を避けるため、本ページで紹介した方法でカスタマイズされることをおすすめします。

最終更新