struct test_message : public AppFrame::actions::Message_<test_message>
{
    irr::core::stringc data;
    test_message()
    {

    }
    test_message(const char* msg)
    {
        data = msg;
    }
    virtual void serialize(AppFrame::IDataStream* stream)
    {
        stream->Write(data);
    }

    virtual void deserialize(AppFrame::IDataStream* stream)
    {
        stream->Read(data);
    }

    void print()
    {
        nlog<<"test_message received with "<<data.c_str()<<nlendl;
    }
};


struct test_message2 : public AppFrame::actions::Message_<test_message2>
{
    irr::core::stringc data;
    int health;
    test_message2()
    {
        health = 0;
    }
    test_message2(const char* msg, int h)
    {
        data = msg;
        health = h;
    }
    virtual void serialize(AppFrame::IDataStream* stream)
    {
        stream->Write(data);
        stream->Write(health);
    }

    virtual void deserialize(AppFrame::IDataStream* stream)
    {
        stream->Read(data);
        stream->Read(health);
    }

    void print()
    {
        nlog<<"test_message2 received with "<<data.c_str()<<" and "<<health<<nlendl;
    }
};

class testreceiver : public IConnectionMessageReceiver
{
public:
    testreceiver(CConnectionManager* _m, CStreamManager* stream_manager_)
    {
        m = _m;
        stream_manager = stream_manager_;
    }
    void onConnect(const ConnectionID& id)
    {
        nlog<<"Player connected"<<nlendl;
        stream_manager->getEventManager()->replicate(new test_message("Hello Events"), true);
        stream_manager->getEventManager()->replicate(new test_message2("Hello Events2", 567), true);
    }
    void onDisconnect(const ConnectionID& id)
    {
        nlog<<"Player disconnected"<<nlendl;
    }
    void onMessage(const ConnectionID& id, const CONNECTION_CHANNEL& channel, AppFrame::IDataStream* stream)
    {
    }
    CConnectionManager* m;
    CStreamManager* stream_manager;
};

void onMessage(test_message* test)
{
    test->print();
}

void onMessage2(test_message2* test)
{
    test->print();
}

int main(int argc, char* argv[])
{
    CConnectionManager connection;
    CStreamManager stream_manager(&connection);
    stream_manager.setEventReceiver(new testreceiver(&connection, &stream_manager));
    stream_manager.setUpdateRate(1, 1);

    stream_manager.getEventManager()->registerMessage<test_message>();
    stream_manager.getEventManager()->registerMessage<test_message2>();

    if (argc > 1)
    {
        nlog<<"Start Client"<<nlendl;
        connection.init(0, 1);
        connection.connect("127.0.0.1", 50000) ? nlog<<"Connecting..."<<nlendl : nlerror<<"Connection failed!"<<nlendl;

        stream_manager.getEventManager()->Bind(onMessage);
    }
    else
    {
        nlog<<"Start Server"<<nlendl;
        connection.init(50000, 10);
        stream_manager.getEventManager()->Bind(onMessage2);
    }

    while(true)
    {
        stream_manager.update();
        connection.update();
    }
    return 0;
}