2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

今更オブジェクト指向,今更C++ということではあるが,現在C++を強烈なオブジェクト指向言語として利用中.あくまで一例,tipsとして.コードは一番下にあります.

テンプレの使用方法

Sampleを何かで置換してやるだけで動きます。
イベント関数の引数を変えたいときはinterfaceOnSampleHandleの引数,SampleEventHandlerCallonSampleEventHandlerの実装で呼び出す部分の引数をそれぞれほしいものに変えればよいです。

イベントを作成したいときは,初めにEventHandlerを用意し,欲しいイベントのprivateリストを作成します。
続いて,欲しい関数を作成するか,または実装したいクラスにインターフェースを継承させます。関数を作成した場合は,その関数fを引数にしてSampleEventHandler::Instance()->addOnSampleEvent(f)と登録してください。

イベントは,SampleEventHandler::Instance()->CallonSampleEventHandler(vargs)とすれば発火します。

解説

イベントハンドラの1つ目のリストは直接関数を,2つ目の関数はインターフェースの実装として登録する場合です。
直接関数は,関数をダイレクトにアタッチすることによって登録されます。この時,クラスのメンバ関数やstd::functionは禁止です。構造が異なります。

インターフェースの実装による登録は,テンプレ通りにすれば自動的に登録されます。ただし,少しオーバーヘッドがでかい恐れがあります。

本質はaddふにゃふにゃとCallon,vector2つなので,それらを内包させられる場合は一つのイベントハンドラで複数のイベントを管理できます。
これを利用して一つのイベントを複数のイベントに分解するなどの応用例があります。その場合は,Callon関数で自分の状態から適切な引数を与えるように呼び出せばよいです。

interface

    typedef void (OnSampleHandle)(int var);
    class ISampleListener 
    {
    public:
        ISampleListener();
        virtual ~ISampleListener() = default;
        virtual void onFired(int var) = 0;

    private:
        void registerListener();
    };

インターフェースの実装

    ISampleListener::ISampleListener()
    {
        this->registerListener();
    }

    void ISampleListener::registerListener()
    {
        SampleEventHandler::Instance()->addSampleListener(std::unique_ptr<std::remove_reference<decltype(*this)>::type>(this));
    }

EventHandler

    class SampleEventHandler : public Singleton
    {
    public:
        SampleEventHandler();
        void CallonSampleEventHandler(int var);

        void addOnSampleEvent(OnSampleHandle event);
        void addSampleEvent(std::shared_ptr<ISampleListener> listener);
    private:
        v2 var;

        std::vector<ISampleListener*> _onSample = {};
        std::vector<std::shared_ptr<ISampleListener>> _onpSample = {};
    };

ハンドラの実装

#include <omp.h>

    void SampleEventHandler::CallonSampleEventHandler(int var)
    {
        #pragma omp parallel for
        for (auto fn : this->_onSample)
        {
            fn(var);
        }
        #pragma omp parallel for
        for (auto p : this->_onpSample)
        {
            p->onFired(var);
        }
        }
    }
            void SampleEventHandler::addOnSampleEvent(OnSampleHandle event)
    {
        this->_onSample.push_back(event);
    }

    void SampleEventHandler::addSampleEvent(std::shared_ptr<ISampleListener> listener)
    {
        this->_onpSample.push_back(std::move(listener));
    }

2
3
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
3

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?