summaryrefslogtreecommitdiff
path: root/common/accel-union.hpp
blob: 136db44296fa81053cf97f4043f43c725a658fa2 (plain) (blame)
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
#pragma once

#include "accel-classic.hpp"
#include "accel-jump.hpp"
#include "accel-lookup.hpp"
#include "accel-motivity.hpp"
#include "accel-natural.hpp"
#include "accel-noaccel.hpp"
#include "accel-power.hpp"

namespace rawaccel {

    union accel_union {
        accel_noaccel noaccel;
        lookup lut;
        classic<GAIN> classic_g;
        classic<LEGACY> classic_l;
        jump<GAIN> jump_g;
        jump<LEGACY> jump_l;
        natural<GAIN> natural_g;
        natural<LEGACY> natural_l;
        power<GAIN> power_g;
        power<LEGACY> power_l;
        loglog_sigmoid<GAIN> loglog_sigmoid_g;
        loglog_sigmoid<LEGACY> loglog_sigmoid_l;

        template <template <bool> class AccelTemplate, typename Visitor>
        auto visit_helper(Visitor vis, bool gain)
        {
            if (gain) return vis(reinterpret_cast<AccelTemplate<GAIN>&>(*this));
            else  return vis(reinterpret_cast<AccelTemplate<LEGACY>&>(*this));
        }

        template <typename Visitor>
        auto visit(Visitor vis, const accel_args& args)
        {
            switch (args.mode) {
            case accel_mode::classic:  return visit_helper<classic>(vis, args.gain);
            case accel_mode::jump:     return visit_helper<jump>(vis, args.gain);
            case accel_mode::natural:  return visit_helper<natural>(vis, args.gain);
            case accel_mode::motivity: return visit_helper<loglog_sigmoid>(vis, args.gain);
            case accel_mode::power:    return visit_helper<power>(vis, args.gain);
            case accel_mode::lookup:   return vis(lut);
            default:                   return vis(noaccel);
            }
        }

        void init(const accel_args& args)
        {
            visit([&](auto& impl) {
                impl = { args };
            }, args);
        }

    };

}