mirror of
https://github.com/holub/mame
synced 2025-04-27 18:53:05 +03:00
device_state_interface overhaul
- device_state_entry::value and device_state_entry::set_value now do everything except the register lookup, allowing them to be made public. The debugger expression engine now uses these. - device_state_entry::dvalue and device_state_entry::set_dvalue have also been made public, theoretically permitting outside code layers to inspect and modify floating-point registers. - The double specialization of device_pseudo_state_register (now renamed device_functional_state_register) has been added to the core. - state_add now has an additional specialization that takes both a reference and a write function, using the former for reads only. - state_max_length has been eliminated in favor of obtaining the relevant info through device_state_entry::max_length. - The debugger state view no longer adds "flags" as "???" if none have been registered. - set_state_string has been removed. It was never properly implemented, and it is difficult to see how it could have been done in a useful and consistent way. - state_find_entry and its typical callers state_int and set_state_int have been inlined for some hopeful efficiency gains.
This commit is contained in:
parent
71bcb539fe
commit
46071c487e
@ -1238,35 +1238,6 @@ netlist_mame_cpu_device::netlist_mame_cpu_device(const machine_config &mconfig,
|
||||
}
|
||||
|
||||
|
||||
// Fixes overflow error in device_pseudo_state_register
|
||||
template<>
|
||||
class device_pseudo_state_register<double> : public device_state_entry
|
||||
{
|
||||
public:
|
||||
typedef typename std::function<double ()> getter_func;
|
||||
typedef typename std::function<void (double)> setter_func;
|
||||
|
||||
// construction/destruction
|
||||
device_pseudo_state_register(int index, const char *symbol, getter_func &&getter, setter_func &&setter, device_state_interface *dev)
|
||||
: device_state_entry(index, symbol, sizeof(double), ~u64(0), DSF_FLOATING_POINT, dev),
|
||||
m_getter(std::move(getter)),
|
||||
m_setter(std::move(setter))
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
// device_state_entry overrides
|
||||
virtual u64 entry_value() const override { return u64(m_getter()); }
|
||||
virtual void entry_set_value(u64 value) const override { m_setter(double(value)); }
|
||||
virtual double entry_dvalue() const override { return m_getter(); }
|
||||
virtual void entry_set_dvalue(double value) const override { m_setter(value); }
|
||||
|
||||
private:
|
||||
getter_func m_getter; // function to retrieve the data
|
||||
setter_func m_setter; // function to store the data
|
||||
};
|
||||
|
||||
|
||||
void netlist_mame_cpu_device::device_start()
|
||||
{
|
||||
LOGDEVCALLS("device_start entry\n");
|
||||
@ -1299,12 +1270,11 @@ void netlist_mame_cpu_device::device_start()
|
||||
else
|
||||
{
|
||||
auto nl = downcast<netlist::analog_net_t *>(n.get());
|
||||
state_add(std::make_unique<device_pseudo_state_register<double>>(
|
||||
state_add<double>(
|
||||
index++,
|
||||
name.c_str(),
|
||||
[nl]() { return nl->Q_Analog(); },
|
||||
[nl](double data) { nl->set_Q_Analog(data); },
|
||||
this));
|
||||
[nl](double data) { nl->set_Q_Analog(data); });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -513,8 +513,8 @@ device_debug::device_debug(device_t &device)
|
||||
strmakelower(tempstr.assign(entry->symbol()));
|
||||
m_symtable->add(
|
||||
tempstr.c_str(),
|
||||
std::bind(&device_state_interface::state_int, m_state, entry->index()),
|
||||
entry->writeable() ? std::bind(&device_state_interface::set_state_int, m_state, entry->index(), _1) : symbol_table::setter_func(nullptr),
|
||||
std::bind(&device_state_entry::value, entry.get()),
|
||||
entry->writeable() ? std::bind(&device_state_entry::set_value, entry.get(), _1) : symbol_table::setter_func(nullptr),
|
||||
entry->format_string());
|
||||
}
|
||||
}
|
||||
|
@ -147,7 +147,9 @@ void debug_view_state::recompute()
|
||||
}
|
||||
|
||||
// add a flags entry: flags:xxxxxxxx
|
||||
m_state_list.emplace_back(STATE_GENFLAGS, "flags", source.m_stateintf->state_string_max_length(STATE_GENFLAGS));
|
||||
const device_state_entry *flags = source.m_stateintf->state_find_entry(STATE_GENFLAGS);
|
||||
if (flags != nullptr)
|
||||
m_state_list.emplace_back(STATE_GENFLAGS, "flags", flags->max_length());
|
||||
|
||||
// add a divider entry
|
||||
m_state_list.emplace_back(REG_DIVIDER, "", 0);
|
||||
@ -158,7 +160,7 @@ void debug_view_state::recompute()
|
||||
if (entry->divider())
|
||||
m_state_list.emplace_back(REG_DIVIDER, "", 0);
|
||||
else if (entry->visible())
|
||||
m_state_list.emplace_back(entry->index(), entry->symbol(), source.m_stateintf->state_string_max_length(entry->index()));
|
||||
m_state_list.emplace_back(entry->index(), entry->symbol(), entry->max_length());
|
||||
}
|
||||
|
||||
// count the entries and determine the maximum tag and value sizes
|
||||
|
@ -138,6 +138,36 @@ void device_state_entry::format_from_mask()
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// value - return the current value as a u64
|
||||
//-------------------------------------------------
|
||||
|
||||
u64 device_state_entry::value() const
|
||||
{
|
||||
// call the exporter before we do anything
|
||||
if ((m_flags & DSF_EXPORT) != 0)
|
||||
m_device_state->state_export(*this);
|
||||
|
||||
// pick up the value
|
||||
return entry_value() & m_datamask;
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// dvalue - return the current value as a double
|
||||
//-------------------------------------------------
|
||||
|
||||
double device_state_entry::dvalue() const
|
||||
{
|
||||
// call the exporter before we do anything
|
||||
if ((m_flags & DSF_EXPORT) != 0)
|
||||
m_device_state->state_export(*this);
|
||||
|
||||
// pick up the value
|
||||
return entry_dvalue();
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// entry_baseptr - return a pointer to where the
|
||||
// data lives (if applicable)
|
||||
@ -178,7 +208,7 @@ double device_state_entry::entry_dvalue() const
|
||||
std::string device_state_entry::format(const char *string, bool maxout) const
|
||||
{
|
||||
std::string dest;
|
||||
u64 result = value();
|
||||
u64 result = entry_value() & m_datamask;
|
||||
|
||||
// parse the format
|
||||
bool leadzero = false;
|
||||
@ -359,6 +389,37 @@ std::string device_state_entry::format(const char *string, bool maxout) const
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// to_string - return the value of the given
|
||||
// piece of indexed state as a string
|
||||
//-------------------------------------------------
|
||||
|
||||
std::string device_state_entry::to_string() const
|
||||
{
|
||||
// get the custom string if needed
|
||||
std::string custom;
|
||||
if ((m_flags & DSF_CUSTOM_STRING) != 0)
|
||||
m_device_state->state_string_export(*this, custom);
|
||||
else if ((m_flags & DSF_FLOATING_POINT) != 0)
|
||||
custom = string_format("%-12G", entry_dvalue());
|
||||
|
||||
// ask the entry to format itself
|
||||
return format(custom.c_str());
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// max_length - return the maximum length of the
|
||||
// given state as a string
|
||||
//-------------------------------------------------
|
||||
|
||||
int device_state_entry::max_length() const
|
||||
{
|
||||
// ask the entry to format itself maximally
|
||||
return format("", true).length();
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// set_value - set the value from a u64
|
||||
//-------------------------------------------------
|
||||
@ -376,6 +437,10 @@ void device_state_entry::set_value(u64 value) const
|
||||
|
||||
// store the value
|
||||
entry_set_value(value);
|
||||
|
||||
// call the importer to finish up
|
||||
if ((m_flags & DSF_IMPORT) != 0)
|
||||
m_device_state->state_import(*this);
|
||||
}
|
||||
|
||||
|
||||
@ -389,6 +454,10 @@ void device_state_entry::set_dvalue(double value) const
|
||||
|
||||
// store the value
|
||||
entry_set_dvalue(value);
|
||||
|
||||
// call the importer to finish up
|
||||
if ((m_flags & DSF_IMPORT) != 0)
|
||||
m_device_state->state_import(*this);
|
||||
}
|
||||
|
||||
|
||||
@ -411,16 +480,6 @@ void device_state_entry::entry_set_dvalue(double value) const
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// set_value - set the value from a string
|
||||
//-------------------------------------------------
|
||||
|
||||
void device_state_entry::set_value(const char *string) const
|
||||
{
|
||||
// not implemented
|
||||
}
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// DEVICE STATE INTERFACE
|
||||
@ -449,110 +508,6 @@ device_state_interface::~device_state_interface()
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// state_int - return the value of the given piece
|
||||
// of indexed state as a u64
|
||||
//-------------------------------------------------
|
||||
|
||||
u64 device_state_interface::state_int(int index)
|
||||
{
|
||||
// nullptr or out-of-range entry returns 0
|
||||
const device_state_entry *entry = state_find_entry(index);
|
||||
if (entry == nullptr)
|
||||
return 0;
|
||||
|
||||
// call the exporter before we do anything
|
||||
if (entry->needs_export())
|
||||
state_export(*entry);
|
||||
|
||||
// pick up the value
|
||||
return entry->value();
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// state_string - return the value of the given
|
||||
// pieces of indexed state as a string
|
||||
//-------------------------------------------------
|
||||
|
||||
std::string device_state_interface::state_string(int index) const
|
||||
{
|
||||
// nullptr or out-of-range entry returns bogus string
|
||||
const device_state_entry *entry = state_find_entry(index);
|
||||
if (entry == nullptr)
|
||||
return std::string("???");
|
||||
|
||||
// get the custom string if needed
|
||||
std::string custom;
|
||||
if (entry->needs_custom_string())
|
||||
state_string_export(*entry, custom);
|
||||
else if (entry->is_float())
|
||||
custom = string_format("%-12G", entry->dvalue());
|
||||
|
||||
// ask the entry to format itself
|
||||
return entry->format(custom.c_str());
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// state_string_max_length - return the maximum
|
||||
// length of the given state string
|
||||
//-------------------------------------------------
|
||||
|
||||
int device_state_interface::state_string_max_length(int index)
|
||||
{
|
||||
// nullptr or out-of-range entry returns bogus string
|
||||
const device_state_entry *entry = state_find_entry(index);
|
||||
if (entry == nullptr)
|
||||
return 3;
|
||||
|
||||
// ask the entry to format itself maximally
|
||||
return entry->format("", true).length();
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// set_state_int - set the value of the given
|
||||
// piece of indexed state from a u64
|
||||
//-------------------------------------------------
|
||||
|
||||
void device_state_interface::set_state_int(int index, u64 value)
|
||||
{
|
||||
// nullptr or out-of-range entry is a no-op
|
||||
const device_state_entry *entry = state_find_entry(index);
|
||||
if (entry == nullptr)
|
||||
return;
|
||||
|
||||
// set the value
|
||||
entry->set_value(value);
|
||||
|
||||
// call the importer to finish up
|
||||
if (entry->needs_import())
|
||||
state_import(*entry);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// set_state - set the value of the given piece
|
||||
// of indexed state from a string
|
||||
//-------------------------------------------------
|
||||
|
||||
void device_state_interface::set_state_string(int index, const char *string)
|
||||
{
|
||||
// nullptr or out-of-range entry is a no-op
|
||||
const device_state_entry *entry = state_find_entry(index);
|
||||
if (entry == nullptr)
|
||||
return;
|
||||
|
||||
// set the value
|
||||
entry->set_value(string);
|
||||
|
||||
// call the importer to finish up
|
||||
if (entry->needs_import())
|
||||
state_import(*entry);
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// state_add - add a new piece of indexed state
|
||||
//-------------------------------------------------
|
||||
@ -626,24 +581,3 @@ void device_state_interface::interface_post_start()
|
||||
if (m_state_list.size() == 0)
|
||||
throw emu_fatalerror("No state registered for device '%s' that supports it!", device().tag());
|
||||
}
|
||||
|
||||
|
||||
//-------------------------------------------------
|
||||
// state_find_entry - return a pointer to the
|
||||
// state entry for the given index
|
||||
//-------------------------------------------------
|
||||
|
||||
const device_state_entry *device_state_interface::state_find_entry(int index) const
|
||||
{
|
||||
// use fast lookup if possible
|
||||
if (index >= FAST_STATE_MIN && index <= FAST_STATE_MAX)
|
||||
return m_fast_state[index - FAST_STATE_MIN];
|
||||
|
||||
// otherwise, scan the first
|
||||
for (auto &entry : m_state_list)
|
||||
if (entry->m_index == index)
|
||||
return entry.get();
|
||||
|
||||
// handle failure by returning nullptr
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -43,7 +43,6 @@ enum
|
||||
// class describing a single item of exposed device state
|
||||
class device_state_entry
|
||||
{
|
||||
friend class device_state_interface;
|
||||
public:
|
||||
// construction/destruction
|
||||
device_state_entry(int index, const char *symbol, u8 size, u64 sizemask, u8 flags, device_state_interface *dev);
|
||||
@ -73,6 +72,18 @@ public:
|
||||
device_state_interface *parent_state() const {return m_device_state;}
|
||||
const std::string &format_string() const { return m_format; }
|
||||
|
||||
// return the current value
|
||||
u64 value() const;
|
||||
double dvalue() const;
|
||||
|
||||
// return the current value as a string
|
||||
std::string to_string() const;
|
||||
int max_length() const;
|
||||
|
||||
// set the current value
|
||||
void set_value(u64 value) const;
|
||||
void set_dvalue(double value) const;
|
||||
|
||||
protected:
|
||||
// device state flags
|
||||
static constexpr u8 DSF_NOSHOW = 0x01; // don't display this entry in the registers view
|
||||
@ -84,22 +95,6 @@ protected:
|
||||
static constexpr u8 DSF_READONLY = 0x40; // set if this entry does not permit writes
|
||||
static constexpr u8 DSF_FLOATING_POINT = 0x80; // set if this entry represents a floating-point value
|
||||
|
||||
// helpers
|
||||
bool needs_custom_string() const { return ((m_flags & DSF_CUSTOM_STRING) != 0); }
|
||||
void format_from_mask();
|
||||
|
||||
// return the current value -- only for our friends who handle export
|
||||
bool needs_export() const { return ((m_flags & DSF_EXPORT) != 0); }
|
||||
u64 value() const { return entry_value() & m_datamask; }
|
||||
double dvalue() const { return entry_dvalue(); }
|
||||
std::string format(const char *string, bool maxout = false) const;
|
||||
|
||||
// set the current value -- only for our friends who handle import
|
||||
bool needs_import() const { return ((m_flags & DSF_IMPORT) != 0); }
|
||||
void set_value(u64 value) const;
|
||||
void set_dvalue(double value) const;
|
||||
void set_value(const char *string) const;
|
||||
|
||||
// overrides
|
||||
virtual void *entry_baseptr() const;
|
||||
virtual u64 entry_value() const;
|
||||
@ -107,6 +102,11 @@ protected:
|
||||
virtual double entry_dvalue() const;
|
||||
virtual void entry_set_dvalue(double value) const;
|
||||
|
||||
private:
|
||||
// helpers
|
||||
void format_from_mask();
|
||||
std::string format(const char *string, bool maxout = false) const;
|
||||
|
||||
// statics
|
||||
static const u64 k_decimal_divisor[20]; // divisors for outputting decimal values
|
||||
|
||||
@ -195,18 +195,47 @@ private:
|
||||
};
|
||||
|
||||
|
||||
// ======================> device_state_register
|
||||
// ======================> device_latched_functional_state_register
|
||||
|
||||
// class template representing a state register of a specific width
|
||||
template<class ItemType>
|
||||
class device_pseudo_state_register : public device_state_entry
|
||||
class device_latched_functional_state_register : public device_state_entry
|
||||
{
|
||||
public:
|
||||
typedef typename std::function<void (ItemType)> setter_func;
|
||||
|
||||
// construction/destruction
|
||||
device_latched_functional_state_register(int index, const char *symbol, ItemType &data, setter_func &&setter, device_state_interface *dev)
|
||||
: device_state_entry(index, symbol, sizeof(ItemType), std::numeric_limits<ItemType>::max(), 0, dev),
|
||||
m_data(data),
|
||||
m_setter(std::move(setter))
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
// device_state_entry overrides
|
||||
virtual void *entry_baseptr() const override { return &m_data; }
|
||||
virtual u64 entry_value() const override { return m_data; }
|
||||
virtual void entry_set_value(u64 value) const override { m_setter(value); }
|
||||
|
||||
private:
|
||||
ItemType & m_data; // reference to where the data lives
|
||||
setter_func m_setter; // function to store the data
|
||||
};
|
||||
|
||||
|
||||
// ======================> device_functional_state_register
|
||||
|
||||
// class template representing a state register of a specific width
|
||||
template<class ItemType>
|
||||
class device_functional_state_register : public device_state_entry
|
||||
{
|
||||
public:
|
||||
typedef typename std::function<ItemType ()> getter_func;
|
||||
typedef typename std::function<void (ItemType)> setter_func;
|
||||
|
||||
// construction/destruction
|
||||
device_pseudo_state_register(int index, const char *symbol, getter_func &&getter, setter_func &&setter, device_state_interface *dev)
|
||||
device_functional_state_register(int index, const char *symbol, getter_func &&getter, setter_func &&setter, device_state_interface *dev)
|
||||
: device_state_entry(index, symbol, sizeof(ItemType), std::numeric_limits<ItemType>::max(), 0, dev),
|
||||
m_getter(std::move(getter)),
|
||||
m_setter(std::move(setter))
|
||||
@ -223,12 +252,41 @@ private:
|
||||
setter_func m_setter; // function to store the data
|
||||
};
|
||||
|
||||
template<>
|
||||
class device_functional_state_register<double> : public device_state_entry
|
||||
{
|
||||
public:
|
||||
typedef typename std::function<double ()> getter_func;
|
||||
typedef typename std::function<void (double)> setter_func;
|
||||
|
||||
// construction/destruction
|
||||
device_functional_state_register(int index, const char *symbol, getter_func &&getter, setter_func &&setter, device_state_interface *dev)
|
||||
: device_state_entry(index, symbol, sizeof(double), ~u64(0), DSF_FLOATING_POINT, dev),
|
||||
m_getter(std::move(getter)),
|
||||
m_setter(std::move(setter))
|
||||
{
|
||||
}
|
||||
|
||||
protected:
|
||||
// device_state_entry overrides
|
||||
virtual u64 entry_value() const override { return u64(m_getter()); }
|
||||
virtual void entry_set_value(u64 value) const override { m_setter(double(value)); }
|
||||
virtual double entry_dvalue() const override { return m_getter(); }
|
||||
virtual void entry_set_dvalue(double value) const override { m_setter(value); }
|
||||
|
||||
private:
|
||||
getter_func m_getter; // function to retrieve the data
|
||||
setter_func m_setter; // function to store the data
|
||||
};
|
||||
|
||||
|
||||
// ======================> device_state_interface
|
||||
|
||||
// class representing interface-specific live state
|
||||
class device_state_interface : public device_interface
|
||||
{
|
||||
friend class device_state_entry;
|
||||
|
||||
public:
|
||||
// construction/destruction
|
||||
device_state_interface(const machine_config &mconfig, device_t &device);
|
||||
@ -238,17 +296,15 @@ public:
|
||||
const std::vector<std::unique_ptr<device_state_entry>> &state_entries() const { return m_state_list; }
|
||||
|
||||
// state getters
|
||||
u64 state_int(int index);
|
||||
std::string state_string(int index) const;
|
||||
int state_string_max_length(int index);
|
||||
u64 state_int(int index) { const device_state_entry *entry = state_find_entry(index); return (entry == nullptr) ? 0 : entry->value(); }
|
||||
std::string state_string(int index) const { const device_state_entry *entry = state_find_entry(index); return (entry == nullptr) ? std::string("???") : entry->to_string(); }
|
||||
offs_t pc() { return state_int(STATE_GENPC); }
|
||||
offs_t pcbase() { return state_int(STATE_GENPCBASE); }
|
||||
offs_t sp() { return state_int(STATE_GENSP); }
|
||||
u64 flags() { return state_int(STATE_GENFLAGS); }
|
||||
|
||||
// state setters
|
||||
void set_state_int(int index, u64 value);
|
||||
void set_state_string(int index, const char *string);
|
||||
void set_state_int(int index, u64 value) { const device_state_entry *entry = state_find_entry(index); if (entry != nullptr) entry->set_value(value); }
|
||||
void set_pc(offs_t pc) { set_state_int(STATE_GENPC, pc); }
|
||||
|
||||
// find the entry for a given index
|
||||
@ -267,19 +323,29 @@ public: // protected eventually
|
||||
return state_add(std::make_unique<device_state_register<ItemType>>(index, symbol, data, this));
|
||||
}
|
||||
|
||||
// add a new state pseudo-register item (template argument must be explicit)
|
||||
template<class ItemType> device_state_entry &state_add(int index, const char *symbol,
|
||||
typename device_pseudo_state_register<ItemType>::getter_func &&getter,
|
||||
typename device_pseudo_state_register<ItemType>::setter_func &&setter)
|
||||
// add a new state register item using functional setter
|
||||
template<class ItemType> device_state_entry &state_add(int index, const char *symbol, ItemType &data,
|
||||
typename device_latched_functional_state_register<ItemType>::setter_func &&setter)
|
||||
{
|
||||
assert(symbol != nullptr);
|
||||
return state_add(std::make_unique<device_pseudo_state_register<ItemType>>(index, symbol, std::move(getter), std::move(setter), this));
|
||||
return state_add(std::make_unique<device_latched_functional_state_register<ItemType>>(index, symbol, data, std::move(setter), this));
|
||||
}
|
||||
|
||||
// add a new state register item using functional getter and setter (template argument must be explicit)
|
||||
template<class ItemType> device_state_entry &state_add(int index, const char *symbol,
|
||||
typename device_pseudo_state_register<ItemType>::getter_func &&getter)
|
||||
typename device_functional_state_register<ItemType>::getter_func &&getter,
|
||||
typename device_functional_state_register<ItemType>::setter_func &&setter)
|
||||
{
|
||||
assert(symbol != nullptr);
|
||||
return state_add(std::make_unique<device_pseudo_state_register<ItemType>>(index, symbol, std::move(getter), [](ItemType){}, this)).readonly();
|
||||
return state_add(std::make_unique<device_functional_state_register<ItemType>>(index, symbol, std::move(getter), std::move(setter), this));
|
||||
}
|
||||
|
||||
// add a new read-only state register item using functional getter (template argument must be explicit)
|
||||
template<class ItemType> device_state_entry &state_add(int index, const char *symbol,
|
||||
typename device_functional_state_register<ItemType>::getter_func &&getter)
|
||||
{
|
||||
assert(symbol != nullptr);
|
||||
return state_add(std::make_unique<device_functional_state_register<ItemType>>(index, symbol, std::move(getter), [](ItemType){}, this)).readonly();
|
||||
}
|
||||
|
||||
device_state_entry &state_add(std::unique_ptr<device_state_entry> &&entry);
|
||||
@ -310,4 +376,30 @@ protected:
|
||||
// iterator
|
||||
typedef device_interface_iterator<device_state_interface> state_interface_iterator;
|
||||
|
||||
|
||||
|
||||
//**************************************************************************
|
||||
// INLINE FUNCTIONS
|
||||
//**************************************************************************
|
||||
|
||||
//-------------------------------------------------
|
||||
// state_find_entry - return a pointer to the
|
||||
// state entry for the given index
|
||||
//-------------------------------------------------
|
||||
|
||||
inline const device_state_entry *device_state_interface::state_find_entry(int index) const
|
||||
{
|
||||
// use fast lookup if possible
|
||||
if (index >= FAST_STATE_MIN && index <= FAST_STATE_MAX)
|
||||
return m_fast_state[index - FAST_STATE_MIN];
|
||||
|
||||
// otherwise, scan the first
|
||||
for (auto &entry : m_state_list)
|
||||
if (entry->index() == index)
|
||||
return entry.get();
|
||||
|
||||
// handle failure by returning nullptr
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
#endif /* MAME_EMU_DISTATE_H */
|
||||
|
Loading…
Reference in New Issue
Block a user