| 1 |
#include "LedStatus.hh" |
| 2 |
|
| 3 |
#include "CommandController.hh" |
| 4 |
#include "MSXCliComm.hh" |
| 5 |
#include "Timer.hh" |
| 6 |
|
| 7 |
#include "stl.hh" |
| 8 |
#include "strCat.hh" |
| 9 |
#include "xrange.hh" |
| 10 |
|
| 11 |
#include <algorithm> |
| 12 |
#include <array> |
| 13 |
#include <string_view> |
| 14 |
|
| 15 |
namespace openmsx { |
| 16 |
|
| 17 |
using namespace std::literals; |
| 18 |
|
| 19 |
[[nodiscard]] static std::string_view getLedName(LedStatus::Led led) |
| 20 |
{ |
| 21 |
static constexpr std::array<std::string_view, LedStatus::NUM_LEDS> names = { |
| 22 |
"power", "caps", "kana", "pause", "turbo", "FDD" |
| 23 |
}; |
| 24 |
return names[led]; |
| 25 |
} |
| 26 |
|
| 27 |
LedStatus::LedStatus( |
| 28 |
RTScheduler& rtScheduler, |
| 29 |
CommandController& commandController, |
| 30 |
MSXCliComm& msxCliComm_) |
| 31 |
: RTSchedulable(rtScheduler) |
| 32 |
, msxCliComm(msxCliComm_) |
| 33 |
, interp(commandController.getInterpreter()) |
| 34 |
, ledStatus(generate_array<NUM_LEDS>([&](auto i) { |
| 35 |
return ReadOnlySetting( |
| 36 |
commandController, |
| 37 |
tmpStrCat("led_", getLedName(static_cast<Led>(i))), |
| 38 |
"Current status for LED", |
| 39 |
TclObject("off")); |
| 40 |
})) |
| 41 |
, lastTime(Timer::getTime()) |
| 42 |
{ |
| 43 |
std::ranges::fill(ledValue, false); |
| 44 |
} |
| 45 |
|
| 46 |
void LedStatus::setLed(Led led, bool status) |
| 47 |
{ |
| 48 |
if (ledValue[led] == status) return; |
| 49 |
ledValue[led] = status; |
| 50 |
|
| 51 |
|
| 52 |
|
| 53 |
|
| 54 |
|
| 55 |
auto now = Timer::getTime(); |
| 56 |
auto diff = now - lastTime; |
| 57 |
if (diff > 10000) { |
| 58 |
|
| 59 |
lastTime = now; |
| 60 |
handleEvent(led); |
| 61 |
} else { |
| 62 |
|
| 63 |
if (!isPendingRT()) { |
| 64 |
scheduleRT(10000 - diff); |
| 65 |
} |
| 66 |
} |
| 67 |
} |
| 68 |
|
| 69 |
void LedStatus::handleEvent(Led led) noexcept |
| 70 |
{ |
| 71 |
std::string_view str = ledValue[led] ? "on"sv : "off"sv; |
| 72 |
ledStatus[led].setReadOnlyValue(TclObject(str)); |
| 73 |
msxCliComm.updateFiltered(CliComm::UpdateType::LED, getLedName(led), str); |
| 74 |
} |
| 75 |
|
| 76 |
void LedStatus::executeRT() |
| 77 |
{ |
| 78 |
for (auto i : xrange(int(NUM_LEDS))) { |
| 79 |
if (ledValue[i] != ledStatus[i].getValue().getBoolean(interp)) { |
| 80 |
handleEvent(static_cast<Led>(i)); |
| 81 |
} |
| 82 |
} |
| 83 |
lastTime = Timer::getTime(); |
| 84 |
} |
| 85 |
|
| 86 |
} |