mirror of
https://github.com/holub/mame
synced 2025-07-06 18:39:28 +03:00
Add a method for copying part of an XML tree into another tree and use it to fix Cocoa debugger fatal error
This commit is contained in:
parent
05e84dccc0
commit
d7984c7d0c
@ -70,7 +70,7 @@ file::~file() { }
|
|||||||
|
|
||||||
file::ptr file::create()
|
file::ptr file::create()
|
||||||
{
|
{
|
||||||
try { return ptr(new file()); }
|
try { return ptr(new file); }
|
||||||
catch (...) { return ptr(); }
|
catch (...) { return ptr(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -213,7 +213,12 @@ data_node::data_node(data_node *parent, const char *name, const char *value)
|
|||||||
|
|
||||||
data_node::~data_node()
|
data_node::~data_node()
|
||||||
{
|
{
|
||||||
/* free the children */
|
free_children();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void data_node::free_children()
|
||||||
|
{
|
||||||
for (data_node *nchild = nullptr; m_first_child; m_first_child = nchild)
|
for (data_node *nchild = nullptr; m_first_child; m_first_child = nchild)
|
||||||
{
|
{
|
||||||
/* note the next node and free this node */
|
/* note the next node and free this node */
|
||||||
@ -382,6 +387,43 @@ data_node *data_node::get_or_add_child(const char *name, const char *value)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// recursively copy as child of another node
|
||||||
|
data_node *data_node::copy_into(data_node &parent) const
|
||||||
|
{
|
||||||
|
data_node *const result = parent.add_child(get_name(), get_value());
|
||||||
|
result->m_attributes = m_attributes;
|
||||||
|
|
||||||
|
data_node *dst = result;
|
||||||
|
data_node const *src = get_first_child();
|
||||||
|
while (src && (&parent != dst))
|
||||||
|
{
|
||||||
|
dst = dst->add_child(src->get_name(), src->get_value());
|
||||||
|
dst->m_attributes = src->m_attributes;
|
||||||
|
data_node const *next = src->get_first_child();
|
||||||
|
if (next)
|
||||||
|
{
|
||||||
|
src = next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dst = dst->get_parent();
|
||||||
|
next = src->get_next_sibling();
|
||||||
|
if (next)
|
||||||
|
{
|
||||||
|
src = next;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dst = dst->get_parent();
|
||||||
|
src = src->get_parent()->get_next_sibling();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*-------------------------------------------------
|
/*-------------------------------------------------
|
||||||
delete_node - delete a node and its
|
delete_node - delete a node and its
|
||||||
children
|
children
|
||||||
@ -389,9 +431,10 @@ data_node *data_node::get_or_add_child(const char *name, const char *value)
|
|||||||
|
|
||||||
void data_node::delete_node()
|
void data_node::delete_node()
|
||||||
{
|
{
|
||||||
/* first unhook us from the list of children of our parent */
|
/* don't allow deletion of document root */
|
||||||
if (m_parent)
|
if (m_parent)
|
||||||
{
|
{
|
||||||
|
/* first unhook us from the list of children of our parent */
|
||||||
for (data_node **pnode = &m_parent->m_first_child; *pnode; pnode = &(*pnode)->m_next)
|
for (data_node **pnode = &m_parent->m_first_child; *pnode; pnode = &(*pnode)->m_next)
|
||||||
{
|
{
|
||||||
if (*pnode == this)
|
if (*pnode == this)
|
||||||
@ -400,10 +443,15 @@ void data_node::delete_node()
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* now free ourselves and our children */
|
/* now free ourselves and our children */
|
||||||
delete this;
|
delete this;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* remove all children of document root */
|
||||||
|
free_children();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -118,6 +118,9 @@ public:
|
|||||||
// either return an existing child node or create one if it doesn't exist
|
// either return an existing child node or create one if it doesn't exist
|
||||||
data_node *get_or_add_child(const char *name, const char *value);
|
data_node *get_or_add_child(const char *name, const char *value);
|
||||||
|
|
||||||
|
// recursively copy as child of another node
|
||||||
|
data_node *copy_into(data_node &parent) const;
|
||||||
|
|
||||||
// delete a node and its children
|
// delete a node and its children
|
||||||
void delete_node();
|
void delete_node();
|
||||||
|
|
||||||
@ -189,6 +192,8 @@ private:
|
|||||||
attribute_node *get_attribute(const char *attribute);
|
attribute_node *get_attribute(const char *attribute);
|
||||||
attribute_node const *get_attribute(const char *attribute) const;
|
attribute_node const *get_attribute(const char *attribute) const;
|
||||||
|
|
||||||
|
void free_children();
|
||||||
|
|
||||||
|
|
||||||
data_node * m_next;
|
data_node * m_next;
|
||||||
data_node * m_first_child;
|
data_node * m_first_child;
|
||||||
@ -208,7 +213,7 @@ public:
|
|||||||
|
|
||||||
~file();
|
~file();
|
||||||
|
|
||||||
// create a new empty xml file object
|
// create a new, empty XML file
|
||||||
static ptr create();
|
static ptr create();
|
||||||
|
|
||||||
// parse an XML file into its nodes
|
// parse an XML file into its nodes
|
||||||
|
@ -30,6 +30,8 @@
|
|||||||
#import "osx/debugconsole.h"
|
#import "osx/debugconsole.h"
|
||||||
#import "osx/debugwindowhandler.h"
|
#import "osx/debugwindowhandler.h"
|
||||||
|
|
||||||
|
#include "util/xmlfile.h"
|
||||||
|
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
|
|
||||||
|
|
||||||
@ -44,7 +46,8 @@ public:
|
|||||||
osd_module(OSD_DEBUG_PROVIDER, "osx"),
|
osd_module(OSD_DEBUG_PROVIDER, "osx"),
|
||||||
debug_module(),
|
debug_module(),
|
||||||
m_machine(nullptr),
|
m_machine(nullptr),
|
||||||
m_console(nil)
|
m_console(nil),
|
||||||
|
m_config()
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -69,6 +72,7 @@ private:
|
|||||||
|
|
||||||
running_machine *m_machine;
|
running_machine *m_machine;
|
||||||
MAMEDebugConsole *m_console;
|
MAMEDebugConsole *m_console;
|
||||||
|
util::xml::file::ptr m_config;
|
||||||
|
|
||||||
static std::atomic_bool s_added_menus;
|
static std::atomic_bool s_added_menus;
|
||||||
};
|
};
|
||||||
@ -141,6 +145,11 @@ void debugger_osx::wait_for_debugger(device_t &device, bool firststop)
|
|||||||
// make sure the debug windows are visible
|
// make sure the debug windows are visible
|
||||||
if (firststop)
|
if (firststop)
|
||||||
{
|
{
|
||||||
|
if (m_config)
|
||||||
|
{
|
||||||
|
[m_console loadConfiguration:m_config->get_first_child()];
|
||||||
|
m_config.reset();
|
||||||
|
}
|
||||||
NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:[NSValue valueWithPointer:&device],
|
NSDictionary *info = [NSDictionary dictionaryWithObjectsAndKeys:[NSValue valueWithPointer:&device],
|
||||||
@"MAMEDebugDevice",
|
@"MAMEDebugDevice",
|
||||||
[NSValue valueWithPointer:m_machine],
|
[NSValue valueWithPointer:m_machine],
|
||||||
@ -296,10 +305,17 @@ void debugger_osx::config_load(config_type cfgtype, util::xml::data_node const *
|
|||||||
{
|
{
|
||||||
if ((config_type::GAME == cfgtype) && parentnode)
|
if ((config_type::GAME == cfgtype) && parentnode)
|
||||||
{
|
{
|
||||||
NSAutoreleasePool *const pool = [[NSAutoreleasePool alloc] init];
|
if (m_console)
|
||||||
create_console();
|
{
|
||||||
[m_console loadConfiguration:parentnode];
|
NSAutoreleasePool *const pool = [[NSAutoreleasePool alloc] init];
|
||||||
[pool release];
|
[m_console loadConfiguration:parentnode];
|
||||||
|
[pool release];
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_config = util::xml::file::create();
|
||||||
|
parentnode->copy_into(*m_config);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user