aboutsummaryrefslogtreecommitdiffstats
path: root/al/eax/call.h
blob: 45ff328c04b6fca3c12801f79437d237dc4f3cd3 (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
#ifndef EAX_EAX_CALL_INCLUDED
#define EAX_EAX_CALL_INCLUDED

#include "AL/al.h"
#include "alnumeric.h"
#include "alspan.h"
#include "api.h"
#include "fx_slot_index.h"

enum class EaxCallType {
    none,
    get,
    set,
}; // EaxCallType

enum class EaxCallPropertySetId {
    none,
    context,
    fx_slot,
    source,
    fx_slot_effect,
}; // EaxCallPropertySetId

class EaxCall {
public:
    EaxCall(
        EaxCallType type,
        const GUID& property_set_guid,
        ALuint property_id,
        ALuint property_source_id,
        ALvoid* property_buffer,
        ALuint property_size);

    bool is_get() const noexcept { return mCallType == EaxCallType::get; }
    bool is_deferred() const noexcept { return mIsDeferred; }
    int get_version() const noexcept { return mVersion; }
    EaxCallPropertySetId get_property_set_id() const noexcept { return mPropertySetId; }
    ALuint get_property_id() const noexcept { return mPropertyId; }
    ALuint get_property_al_name() const noexcept { return mPropertySourceId; }
    EaxFxSlotIndex get_fx_slot_index() const noexcept { return mFxSlotIndex; }

    template<typename TException, typename TValue>
    TValue& get_value() const
    {
        if(mPropertyBufferSize < sizeof(TValue))
            fail_too_small();

        return *static_cast<TValue*>(mPropertyBuffer);
    }

    template<typename TValue>
    al::span<TValue> get_values(size_t max_count) const
    {
        if(max_count == 0 || mPropertyBufferSize < sizeof(TValue))
            fail_too_small();

        const auto count = minz(mPropertyBufferSize / sizeof(TValue), max_count);
        return {static_cast<TValue*>(mPropertyBuffer), count};
    }

    template<typename TValue>
    al::span<TValue> get_values() const
    {
        return get_values<TValue>(~0_uz);
    }

    template<typename TException, typename TValue>
    void set_value(const TValue& value) const
    {
        get_value<TException, TValue>() = value;
    }

private:
    const EaxCallType mCallType;
    int mVersion;
    EaxFxSlotIndex mFxSlotIndex;
    EaxCallPropertySetId mPropertySetId;
    bool mIsDeferred;

    const ALuint mPropertyId;
    const ALuint mPropertySourceId;
    ALvoid*const mPropertyBuffer;
    const ALuint mPropertyBufferSize;

    [[noreturn]] static void fail(const char* message);
    [[noreturn]] static void fail_too_small();
}; // EaxCall

EaxCall create_eax_call(
    EaxCallType type,
    const GUID* property_set_id,
    ALuint property_id,
    ALuint property_source_id,
    ALvoid* property_buffer,
    ALuint property_size);

#endif // !EAX_EAX_CALL_INCLUDED