summaryrefslogtreecommitdiff
path: root/src/KingSystem/Utils/Thread/Message.h
blob: b61ec25ca7ed9c4128ed5b0bc95fecf4b80d6176 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
#pragma once

#include <basis/seadTypes.h>
#include <tuple>
#include "KingSystem/Utils/Thread/MessageTransceiverId.h"

namespace ksys {

struct MessageType {
    MessageType() = default;
    MessageType(u32 v) : value(v) {}  // NOLINT(google-explicit-constructor)

    u32 value;
};

class MessageDelayer {
public:
    MessageDelayer() = default;
    virtual ~MessageDelayer() = default;
    virtual bool shouldProcessMessage() = 0;
};

class Message {
public:
    struct DelayParams {
        DelayParams() : delay_ticks(), delayer() {}
        DelayParams(const DelayParams& other) { *this = other; }
        // Yes, this operator is quite pointless, but we need it to match.
        DelayParams& operator=(const DelayParams& other) {
            delay_ticks = other.delay_ticks;
            delayer = other.delayer;
            return *this;
        }

        int delay_ticks;
        MessageDelayer* delayer;
    };

    Message();
    Message(const Message& message) { *this = message; }
    Message(const MesTransceiverId& source, const MesTransceiverId& destination,
            const MessageType& type, void* user_data, const DelayParams& delay_params, bool ack);
    Message(const MesTransceiverId& source, const MessageType& type, void* user_data,
            const DelayParams& delay_params, bool ack);

    virtual ~Message();

    Message& operator=(const Message& other) {
        mSource = other.getSource();
        mDestination = other.getDestination();
        mType = other.getType();
        mUserData = other.getUserData();
        mBrokerId = other.getBrokerId();
        mDelayParams = other.mDelayParams;
        mShouldAck = other.shouldAck();
        return *this;
    }

    virtual const MesTransceiverId& getSource() const;
    virtual const MesTransceiverId& getDestination() const;
    virtual const MessageType& getType() const;
    virtual void* getUserData() const;
    virtual u32 getBrokerId() const;
    virtual bool shouldAck() const;
    virtual void setDestination(const MesTransceiverId& dest);
    virtual void setBrokerId(const u32& v);
    virtual bool shouldBeProcessed() const;

    bool hasDelayer() const { return mDelayParams.delayer != nullptr; }

    void decrementDelay() {
        if (mDelayParams.delay_ticks != 0)
            --mDelayParams.delay_ticks;
    }

    void reset() {
        mType = {};
        mUserData = {};
        mBrokerId = 0xffffffff;
        mDelayParams = {};
        mShouldAck = {};
        mSource.reset();
        mDestination.reset();
    }

    void resetIfValid() {
        if (isValid())
            reset();
    }

    bool isValid() const { return mDestination.isRegistered(); }

    void setBrokerId_(u32 id) { mBrokerId = id; }

private:
    MesTransceiverId mSource{};
    MesTransceiverId mDestination{};
    MessageType mType{};
    void* mUserData{};
    u32 mBrokerId = 0xffffffff;
    DelayParams mDelayParams{};
    bool mShouldAck = true;
};

}  // namespace ksys