RASCSI/cpp/devices/dispatcher.h
Uwe Seimet 621cc7d5a2
Code cleanup, especially casts, lambdas, data types, encapsulation (#952)
* Unit test updates

* Lambda syntax cleanup

* Use new-style casts

* Use std::none_of when saving the cache

* Use to_integer instead of casts

* Use accessors for getting CDB data

* Made ctrl_t private

* Improved encapsulation

* Replaced pointers by references

* Removed all remaining occurrences of DWORD and BYTE, making os.h obsolete
2022-11-02 07:36:25 +01:00

56 lines
1.2 KiB
C++

//---------------------------------------------------------------------------
//
// SCSI Target Emulator RaSCSI Reloaded
// for Raspberry Pi
//
// Copyright (C) 2022 Uwe Seimet
//
// A template for dispatching SCSI commands
//
//---------------------------------------------------------------------------
#pragma once
#include "log.h"
#include <unordered_map>
using namespace std;
using namespace scsi_defs;
template<class T>
class Dispatcher
{
public:
Dispatcher() = default;
~Dispatcher() = default;
using operation = void (T::*)();
using command_t = struct _command_t {
const char *name;
operation execute;
_command_t(const char *_name, operation _execute) : name(_name), execute(_execute) { };
};
unordered_map<scsi_command, unique_ptr<command_t>> commands;
void Add(scsi_command opcode, const char *name, operation execute)
{
commands[opcode] = make_unique<command_t>(name, execute);
}
bool Dispatch(T *instance, scsi_command cmd) const
{
if (const auto& it = commands.find(cmd); it != commands.end()) {
LOGDEBUG("%s Executing %s ($%02X)", __PRETTY_FUNCTION__, it->second->name, (int)cmd)
(instance->*it->second->execute)();
return true;
}
// Unknown command
return false;
}
};