> For the complete documentation index, see [llms.txt](https://help.diarkis.io/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://help.diarkis.io/diarkis-client/diarkis-module/how-to-customize-module.md).

# 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** の機能をカスタマイズするには各機能のベース・クラス(Diarkis**ModuleName**Base)を継承します。DM 機能は `DiarkisDirectMessageBase` に実装されており、サンプルではこのクラスを継承して必要な処理を実装します。 以下のコードが実際の実装の一部となります。

```cpp
/*
 * 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` クラスを実装します。以下がサンプル実装の一部となります。

```cpp
/*
 * 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 機能のインスタンスは `DiarkisInterfaceBase::SetupDirectMessage()` で行われるためこのメソッドをオーバーライドしてユーザーがカスタマイズした DM 機能のクラスを生成します。また、あわせてカスタマイズした型で DM 機能のインスタンスを取得できるメソッドも追加しています。

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

```cpp
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** のソース・コードはバージョンアップ時に大きく変更される可能性があり、マージが困難になることが想定されます。\
こういった状況を避けるため、本ページで紹介した方法でカスタマイズされることをおすすめします。


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://help.diarkis.io/diarkis-client/diarkis-module/how-to-customize-module.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
