File: SensorFactory.h

package info (click to toggle)
libexadrums 0.7.0-1.1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 652 kB
  • sloc: cpp: 6,970; ansic: 220; makefile: 160; sh: 12
file content (133 lines) | stat: -rw-r--r-- 3,461 bytes parent folder | download | duplicates (2)
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
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
#ifndef LIBEXADRUMS_IO_SENSORFACTORY_H
#define LIBEXADRUMS_IO_SENSORFACTORY_H

#include "../Util/ErrorHandling.h"

#include "HddSensor.h"
#include "ISensor.h"
#include "SpiSensor.h"
#include "VirtualSensor.h"

#include <algorithm>
#include <array>
#include <functional>
#include <iostream>
#include <map>
#include <numeric>
#include <ranges>
#include <string>
#include <utility>
#include <vector>


namespace IO
{

    class SensorFactory
    {
    public:


        SensorFactory() = default;

        SensorFactory(std::string dataFolder)
        : dataFolder{std::move(dataFolder)}
        {

        }


        ISensorPtr MakeVirtual(size_t channel) const
        {
            return std::make_unique<VirtualSensor>(channel);
        }

        ISensorPtr MakeSpi(const std::vector<SpiDevPtr>& spidev, size_t channel) const
        {

            auto getNbChannels = std::views::transform([] (const auto& devPtr) { return devPtr->GetNbChannels(); });
            auto cumsum = std::views::transform([total = size_t{0}] (auto c) mutable { total += c; return total; });

            auto totalChannels = spidev | getNbChannels | cumsum;

            auto it = std::ranges::find_if(totalChannels, [&](auto n) { return channel < n; });

            if(it != totalChannels.end())
            {
                const auto index = std::distance(totalChannels.begin(), it);
                return std::make_unique<SpiSensor>(spidev[index].get(), channel);
            }

            throw Util::Exception("SPI channel index out of range.", Util::error_type_error);
        }

        ISensorPtr MakeHdd(const std::string& dataFolder, size_t channel) const
        {
            return std::make_unique<HddSensor>(dataFolder, channel);
        }

        ISensorPtr Make(const std::string& type, size_t channel) const
        {
            auto iter = sensorMap.find(type);

            if(iter == sensorMap.end())
            {
                throw Util::Exception("Sensor type doesn't exist.", Util::error_type_error);
            }

            return std::invoke(iter->second, this, channel); 
        }

        void SetSpiDev(const std::vector<SpiDevPtr>& spidev_)
        {
            this->spidev = &spidev_;
        }

        void SetDataFolder(const std::string& hddDataFolder)
        {
            this->dataFolder = hddDataFolder;
        }

        auto GetTypes() &&
        {
            using namespace std::views;
            return std::vector<std::string>{ keys(sensorMap).begin(), keys(sensorMap).end() };
        }


    private:

        ISensorPtr MakeSpi(size_t channel) const
        {
            return MakeSpi(*this->spidev, channel);
        }

        ISensorPtr MakeHdd(size_t channel) const
        {
            return MakeHdd(this->dataFolder, channel);
        }

        ISensorPtr MakeSerialMidi(size_t channel) const
        {
            return MakeVirtual(channel);
        }

        using FactoryPtmf = ISensorPtr(SensorFactory::*)(size_t) const;
        using SensorMap = std::map<std::string, FactoryPtmf>;

        const std::vector<SpiDevPtr>* spidev{nullptr};
        std::string dataFolder{};

        const SensorMap sensorMap
        {
            {"Virtual", &SensorFactory::MakeVirtual},
            {"Spi", &SensorFactory::MakeSpi},
            {"Hdd", &SensorFactory::MakeHdd},
            {"SerialMidi", &SensorFactory::MakeSerialMidi},
        };

    };

}

#endif /* LIBEXADRUMS_IO_SENSORFACTORY_H */