#ifndef _fencer_message_receiver_h
#define _fencer_message_receiver_h

#include "stdint.h"
#include "typeclass_helpers.h"

typedef uint32_t MessageID;

typedef struct IMessageReceiver {
    void* (*const handle_message)(void*, MessageID, void*);
} IMessageReceiver;

typedef struct MessageReceiver {
    void* data;
    IMessageReceiver const* tc;
} MessageReceiver;

extern void* message_receiver_refuse(void* self, MessageID id, void* data);

extern MessageReceiver message_receiver_no_implementation(void* x);

#define impl_no_MessageReceiver_for(T)\
static inline MessageReceiver T##_as_MessageReceiver(T* x) {\
    return message_receiver_no_implementation(x);\
}

#define impl_MessageReceiver_for(T, handle_message_f)\
static inline MessageReceiver T##_as_MessageReceiver(T* x) {\
    TC_FN_TYPECHECK(void*, handle_message_f, T*, MessageID, void*);\
    static IMessageReceiver const tc = {\
        .handle_message = (void*(*const)(void*,MessageID,void*)) handle_message_f,\
    };\
    return (MessageReceiver){.data = x, .tc = &tc};\
}

#endif // !_fencer_message_receiver_h
