~ttt/async

0f1e3b2ad8fbf108a0c881bc392f7b5446bc8691 — Tomasz Klak 8 years ago fe1b9d6
having fun ;)
M AsynchronousService/src/Dispatcher.h => AsynchronousService/src/Dispatcher.h +1 -1
@@ 7,7 7,7 @@ class Dispatcher
{
public:
    virtual ~Dispatcher() {}
    virtual void dispatch(Message message) = 0;
    virtual void dispatch(const Message& message) = 0;
};



M AsynchronousService/src/DispatcherImpl.h => AsynchronousService/src/DispatcherImpl.h +12 -18
@@ 3,36 3,30 @@

#include <vector>
#include <functional>
#include <utility>
#include <array>
#include "Dispatcher.h"

class DispatcherImpl : public Dispatcher
{
public:
    template<typename T>
    void bind(MessageId messageId, void(T::*method)(), T* object)
    using callback = std::function<void()>;

    template <typename F>
    void bind(MessageId messageId, F f)
    {
        subscribers.push_back( {messageId, std::bind(method, object)} );
      subscribers[static_cast<size_t>(messageId)].emplace_back(std::forward<F>(f));
    }

    void dispatch(Message message)
    void dispatch(const Message& message)
    {
        std::vector<Subscribe>::iterator it;

        for (it = subscribers.begin(); it != subscribers.end(); it++)
        {
            if (it->messageId == message.id)
                it->function();
        }
      const auto id = static_cast<size_t>(message.id);
      std::for_each(begin(subscribers[id]), end(subscribers[id]), std::mem_fn(&callback::operator()));
    }

private:
    struct Subscribe
    {
        MessageId messageId;
        std::function<void (void)> function;
    };

    std::vector<Subscribe> subscribers;
    using callbacks = std::vector<callback>;
    std::array<callbacks,static_cast<size_t>(MessageId::Count)> subscribers;
};

#endif // DISPATCHERIMPL_H

M AsynchronousService/src/MainMessageLoop.h => AsynchronousService/src/MainMessageLoop.h +2 -2
@@ 21,9 21,9 @@ public:
    {
        Message message = messageQueue.get();

        while (message.id != ShutDownMessage)
        while (message.id != MessageId::ShutDownMessage)
        {
            if (message.id == CompleteTaskMessage)
            if (message.id == MessageId::CompleteTaskMessage)
                completion.completeTask(message.customData);
            else
                dispatcher.dispatch(message);

M AsynchronousService/src/MessageIdentifiers.h => AsynchronousService/src/MessageIdentifiers.h +3 -2
@@ 1,12 1,13 @@
#ifndef MESSAGEIDENTIFIERS_H
#define MESSAGEIDENTIFIERS_H

enum MessageId
enum class MessageId
{
    ShutDownMessage,
    CompleteTaskMessage,
    AnyPurposeMessage,
    RunParallelTasksMessage
    RunParallelTasksMessage,
    Count
};

#endif // MESSAGEIDENTIFIERS_H

M AsynchronousService/src/NotifierImpl.h => AsynchronousService/src/NotifierImpl.h +1 -1
@@ 16,7 16,7 @@ public:
    {
        Message message;

        message.id = CompleteTaskMessage;
        message.id = MessageId::CompleteTaskMessage;
        message.customData = taskId;

        messageQueue.put(message);

M AsynchronousService/test/mocks/MockDispatcher.h => AsynchronousService/test/mocks/MockDispatcher.h +1 -1
@@ 7,7 7,7 @@
class MockDispatcher : public Dispatcher
{
public:
    MOCK_METHOD1(dispatch, void(Message));
    MOCK_METHOD1(dispatch, void(const Message&));
};

#endif // MOCKDISPATCHER_H

M AsynchronousService/test/ut/DispatcherShould.cpp => AsynchronousService/test/ut/DispatcherShould.cpp +5 -4
@@ 21,10 21,11 @@ TEST(DispatcherShould, ForwardMessagesToRelatedBindMethods)
    }

    DispatcherImpl dispatcher;
    
    dispatcher.bind(MessageId::AnyPurposeMessage, [&]{ mockReactor.anyPurpose(); });

    dispatcher.bind(AnyPurposeMessage, &MockReactor::anyPurpose, &mockReactor);
    dispatcher.bind(RunParallelTasksMessage, &MockReactor::runParallelTasks, &mockReactor);
    dispatcher.bind(MessageId::RunParallelTasksMessage, [&]{ mockReactor.runParallelTasks(); });

    dispatcher.dispatch( Message{AnyPurposeMessage, nullptr} );
    dispatcher.dispatch( Message{RunParallelTasksMessage, nullptr} );
    dispatcher.dispatch( Message{MessageId::AnyPurposeMessage, nullptr} );
    dispatcher.dispatch( Message{MessageId::RunParallelTasksMessage, nullptr} );
}

M AsynchronousService/test/ut/MainMessageLoopShould.cpp => AsynchronousService/test/ut/MainMessageLoopShould.cpp +4 -3
@@ 12,7 12,7 @@ struct MainMessageLoopShould : public testing::Test
{
    MainMessageLoopShould()
        : mainMessageLoop(mockMessageQueue, mockCompletion, mockDispatcher),
          shutdownMessage{ShutDownMessage, 0}
          shutdownMessage{MessageId::ShutDownMessage, 0}
    {}

    void SetUp()


@@ 33,13 33,14 @@ struct MainMessageLoopShould : public testing::Test
TEST_F(MainMessageLoopShould, FinishExecutionAfterReceivingShutDownMessage)
{
    mainMessageLoop.dispatchMessagesOrCompleteTasksUntilShutDown();
    SUCCEED();
}

TEST_F(MainMessageLoopShould, ForwardTaskIdFromCompletionMessageToCompletionClass)
{
    TaskId someTaskId = reinterpret_cast<void*>(123);

    Message message{CompleteTaskMessage, someTaskId};
    Message message{MessageId::CompleteTaskMessage, someTaskId};

    EXPECT_CALL(mockMessageQueue, get())
            .WillOnce(Return(message))


@@ 57,7 58,7 @@ MATCHER_P(MessageMatcher, message, "")

TEST_F(MainMessageLoopShould, ForwardOtherMessagesToDistacher)
{
    Message message{AnyPurposeMessage, 0};
    Message message{MessageId::AnyPurposeMessage, 0};

    EXPECT_CALL(mockMessageQueue, get())
            .WillOnce(Return(message))

M AsynchronousService/test/ut/NotifierShould.cpp => AsynchronousService/test/ut/NotifierShould.cpp +1 -1
@@ 6,7 6,7 @@

MATCHER_P(CompleteMessage, taskId, "")
{
    return (arg.id == CompleteTaskMessage) && (arg.customData == taskId);
    return (arg.id == MessageId::CompleteTaskMessage) && (arg.customData == taskId);
}

TEST(NotifierShould, PutCompletionMessageIntoMessageQueue)