traintastic/server/src/hardware/output/outputcontroller.hpp
Reinder Feenstra a308165ed1 fix: input monitor / output monitor didn't work
dynamic_cast was used while not fully constructed
2022-08-21 23:33:30 +02:00

165 Zeilen
4.3 KiB
C++

/**
* server/src/hardware/output/outputcontroller.hpp
*
* This file is part of the traintastic source code.
*
* Copyright (C) 2021-2022 Reinder Feenstra
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License
* as published by the Free Software Foundation; either version 2
* of the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
#ifndef TRAINTASTIC_SERVER_HARDWARE_OUTPUT_OUTPUTCONTROLLER_HPP
#define TRAINTASTIC_SERVER_HARDWARE_OUTPUT_OUTPUTCONTROLLER_HPP
#include <cstdint>
#include <vector>
#include <unordered_map>
#include <memory>
#include "../../core/objectproperty.hpp"
#include "../../enum/tristate.hpp"
#ifdef interface
#undef interface // interface is defined in combaseapi.h
#endif
class IdObject;
class Output;
class OutputKeyboard;
class OutputList;
enum class OutputListColumn;
class OutputController
{
public:
struct OutputMapKey
{
uint32_t channel;
uint32_t address;
inline bool operator ==(const OutputMapKey other) const noexcept
{
return channel == other.channel && address == other.address;
}
};
static_assert(sizeof(OutputMapKey) == sizeof(uint64_t));
struct OutputMapKeyHash
{
std::size_t operator()(const OutputMapKey& value) const noexcept
{
return std::hash<uint64_t>{}(*reinterpret_cast<const uint64_t*>(&value));
}
};
using OutputMap = std::unordered_map<OutputMapKey, std::shared_ptr<Output>, OutputMapKeyHash>;
private:
IdObject& interface();
protected:
OutputMap m_outputs;
std::unordered_map<uint32_t, std::weak_ptr<OutputKeyboard>> m_outputKeyboards;
OutputController(IdObject& interface);
void addToWorld(OutputListColumn columns);
void destroying();
public:
static constexpr std::vector<uint32_t>* noOutputChannels = nullptr;
static constexpr uint32_t defaultOutputChannel = 0;
ObjectProperty<OutputList> outputs;
/**
*
*/
inline const OutputMap& outputMap() const { return m_outputs; }
/**
*
*/
virtual const std::vector<uint32_t>* outputChannels() const { return noOutputChannels; }
/**
*
*/
virtual const std::vector<std::string_view>* outputChannelNames() const { return nullptr; }
/**
*
*/
bool isOutputChannel(uint32_t channel) const;
/**
*
*/
virtual std::pair<uint32_t, uint32_t> outputAddressMinMax(uint32_t channel) const = 0;
/**
*
*/
[[nodiscard]] virtual bool isOutputAddressAvailable(uint32_t channel, uint32_t address) const;
/**
* @brief Get the next unused output address
*
* @return An usused address or Output::invalidAddress if no unused address is available.
*/
uint32_t getUnusedOutputAddress(uint32_t channel) const;
/**
*
* @return \c true if changed, \c false otherwise.
*/
[[nodiscard]] virtual bool changeOutputChannelAddress(Output& output, uint32_t newChannel, uint32_t newAddress);
/**
*
* @return \c true if added, \c false otherwise.
*/
[[nodiscard]] bool addOutput(Output& output);
/**
*
* @return \c true if removed, \c false otherwise.
*/
[[nodiscard]] bool removeOutput(Output& output);
/**
* @brief ...
*/
[[nodiscard]] virtual bool setOutputValue(uint32_t channel, uint32_t address, bool value) = 0;
/**
* @brief Update the output value
*
* This function should be called by the hardware layer whenever the output value changes.
*
* @param[in] channel Output channel
* @param[in] address Output address
* @param[in] value New output value
*/
void updateOutputValue(uint32_t channel, uint32_t address, TriState value);
/**
*
*
*/
std::shared_ptr<OutputKeyboard> outputKeyboard(uint32_t channel);
};
#endif