📄 base.cxx
字号:
const std::vector<CdlNode>&CdlContainerBody::get_contents() const{ CYG_REPORT_FUNCNAME("CdlContainer::get_contents"); CYG_REPORT_FUNCARG1XV(this); CYG_PRECONDITION_THISC(); CYG_REPORT_RETURN(); return contents;}boolCdlContainerBody::contains(CdlConstNode node, bool recurse) const{ CYG_REPORT_FUNCNAMETYPE("CdlContainer::contains (node)", "result %d"); CYG_REPORT_FUNCARG3XV(this, node, recurse); CYG_PRECONDITION_THISC(); CYG_PRECONDITION_CLASSC(node); bool result = false; std::vector<CdlNode>::const_iterator node_i; for (node_i = contents.begin(); node_i != contents.end(); node_i++) { if (node == *node_i) { result = true; break; } if (recurse) { CdlConstContainer child = dynamic_cast<CdlConstContainer>(*node_i); if ((0 != child) && child->contains(node, true)) { result = true; break; } } } CYG_REPORT_RETVAL(result); return result;}boolCdlContainerBody::contains(const std::string name, bool recurse) const{ CYG_REPORT_FUNCNAMETYPE("CdlContainer::contains (name)", "result %d"); CYG_REPORT_FUNCARG2XV(this, recurse); CYG_PRECONDITION_THISC(); CYG_PRECONDITIONC("" != name); bool result = false; std::vector<CdlNode>::const_iterator node_i; for (node_i = contents.begin(); node_i != contents.end(); node_i++) { if ((*node_i)->get_name() == name) { result = true; break; } if (recurse) { CdlConstContainer child = dynamic_cast<CdlConstContainer>(*node_i); if ((0 != child) && child->contains(name, true)) { result = true; break; } } } CYG_REPORT_RETVAL(result); return result;}CdlNodeCdlContainerBody::find_node(const std::string name, bool recurse) const{ CYG_REPORT_FUNCNAMETYPE("CdlContainer::find_node", "result %p"); CYG_REPORT_FUNCARG2XV(this, recurse); CYG_PRECONDITION_THISC(); CYG_PRECONDITIONC("" != name); CdlNode result = 0; std::vector<CdlNode>::const_iterator node_i; for (node_i = contents.begin(); node_i != contents.end(); node_i++) { if ((*node_i)->get_name() == name) { result = *node_i; break; } if (recurse) { CdlConstContainer child = dynamic_cast<CdlConstContainer>(*node_i); if (0 != child) { result = child->find_node(name, true); if (0 != result) { break; } } } } CYG_REPORT_RETVAL(result); return result;}//}}}//{{{ Misc // ----------------------------------------------------------------------------std::stringCdlContainerBody::get_class_name() const{ CYG_REPORT_FUNCNAME("CdlContainer::get_class_name"); CYG_PRECONDITION_THISC(); CYG_REPORT_RETURN(); return "container";}//}}}//{{{ Propagation // ----------------------------------------------------------------------------// If a container becomes active and is enabled then it is necessary// to check all the children in case they want to become active as well.voidCdlContainerBody::update(CdlTransaction transaction, CdlUpdate change){ CYG_REPORT_FUNCNAME("CdlContainer::update"); CYG_REPORT_FUNCARG1XV(this); CYG_PRECONDITION_THISC(); CYG_PRECONDITION_CLASSC(transaction); if ((CdlUpdate_ActiveChange != change) && (CdlUpdate_ValueChange != change)) { CYG_REPORT_RETURN(); return; } if (transaction->is_active(this)) { // The container has become active. It is necessary to check // all the children. If any of them should be active as well // but are not then this needs to change. std::vector<CdlNode>::iterator node_i; for (node_i = contents.begin(); node_i != contents.end(); node_i++) { bool old_state = transaction->is_active(*node_i); bool new_state = (*node_i)->test_active(transaction); if (old_state != new_state) { transaction->set_active(*node_i, new_state); } } } else { // The container has become inactive. Any children that were // active should also become inactive. std::vector<CdlNode>::iterator node_i; for (node_i = contents.begin(); node_i != contents.end(); node_i++) { if (transaction->is_active(*node_i)) { transaction->set_active(*node_i, false); } } } CYG_REPORT_RETURN();}//}}}//{{{ Persistence // ----------------------------------------------------------------------------// This member function is invoked while traversing the hierarchy.// The container itself will have been saved already, this member// is responsible only for the contents. There are marker comments// in the output file to indicate a new level in the hierarchy.//// Note that this member can also be invoked for the "orphans" container.// That container will not appear in the save file, but its contents// will.voidCdlContainerBody::save(CdlInterpreter interp, Tcl_Channel chan, int indentation, bool minimal) throw(CdlInputOutputException, std::bad_alloc){ CYG_REPORT_FUNCNAME("CdlContainer::save"); CYG_REPORT_FUNCARG4XV(this, interp, chan, indentation); CYG_PRECONDITION_THISC(); CYG_PRECONDITION_CLASSC(interp); CYG_PRECONDITIONC(0 == indentation); if (0 != contents.size()) { if (!minimal) { interp->write_data(chan, "# >\n"); } std::vector<CdlNode>::const_iterator node_i; for (node_i = contents.begin(); node_i != contents.end(); node_i++) { (*node_i)->save(interp, chan, indentation, minimal); } if (!minimal) { interp->write_data(chan, "# <\n"); } } CYG_REPORT_RETURN();}//}}}//{{{ check_this() // ----------------------------------------------------------------------------boolCdlContainerBody::check_this(cyg_assert_class_zeal zeal) const{ if (CdlContainerBody_Magic != cdlcontainerbody_cookie) { return false; } CYGDBG_MEMLEAK_CHECKTHIS(); if (cyg_extreme == zeal) { std::vector<CdlNode>::const_iterator node_i; for (node_i = contents.begin(); node_i != contents.end(); node_i++) { if (!((*node_i)->check_this(cyg_quick))) { return false; } } } return CdlNodeBody::check_this(zeal);}//}}}//}}}//{{{ CdlLoadableBody //{{{ Constructor // ----------------------------------------------------------------------------// A loadable object keeps track of all the nodes read in from a// particular script, in an "owned" vector. Simply keeping things in a// hierarchy is not enough because of possible re-parenting. Actual// updates of the owned vector happen inside the CdlToplevel// add_node() and remove_node() family.CdlLoadableBody::CdlLoadableBody(CdlToplevel toplevel, std::string dir) : CdlContainerBody(){ CYG_REPORT_FUNCNAME("CdlLoadable:: constructor"); CYG_REPORT_FUNCARG1XV(this); CYG_PRECONDITION_CLASSC(toplevel); // Initialize enough of the object to support check_this() directory = dir; interp = 0; remove_node_loadables_position = -1; cdlloadablebody_cookie = CdlLoadableBody_Magic; // The owned vector takes care of itself. It is necessary // to create a new slave interpreter, using the master // interpreter from the toplevel. CdlInterpreter master = toplevel->get_interpreter(); CYG_ASSERTC(0 != master); interp = master->create_slave(this, false); CYGDBG_MEMLEAK_CONSTRUCTOR(); CYG_POSTCONDITION_THISC(); CYG_REPORT_RETURN();}// Needed by derived classes, but should never actually be used.CdlLoadableBody::CdlLoadableBody(){ CYG_FAIL("CdlLoadable default constructor should never get invoked");}//}}}//{{{ Destructor // ----------------------------------------------------------------------------// The loadable destructor. This gets invoked from two places: after an// unsuccessful load operation, and from inside the transaction commit// code. Either way most of the clean-up will have happened already:// all the nodes will have been removed from the toplevel's hierarchy,// and all property references to and from this loadable will have been// unbound.//// Since all nodes belonging to the loadable are also present in// the owned vector, they must be destroyed before this destructor// completes. Hence clearing out the contents cannot be left to// the base CdlContainer destructor.CdlLoadableBody::~CdlLoadableBody(){ CYG_REPORT_FUNCNAME("CdlLoadable:: destructor"); CYG_REPORT_FUNCARG1XV(this); CYG_PRECONDITION_THISC(); // Make sure that the loadable has already been removed from the // hierarchy: it should not have a toplevel or a parent. CYG_PRECONDITIONC(0 == toplevel); CYG_PRECONDITIONC(0 == parent); // Containers must have been created before any of their contents. // The only way to reverse this involves a parent property, but // all such properties will have been unbound already such that // the nodes can be safely deleted. The only worry is that // loadables own themselves. int i; for (i = owned.size() - 1; i >= 0; i--) { CdlNode node = owned[i]; CYG_LOOP_INVARIANT_CLASSC(node); if (node != this) { CdlToplevelBody::remove_node(this, node->parent, node); delete node; } } // Now there should be exactly one entry in the owned vector, // the loadable itself. We already know that this is no longer // part of the toplevel and it does not have a parent, so // the only field we need to worry about is the owner. CYG_ASSERTC(1 == owned.size()); CYG_ASSERTC(this == owned[0]); this->owner = 0; // Strictly speaking the owned vector should be clear by now, // but remove_node() does not actually bother to clear it. owned.clear(); // The loadable should now be empty. It remains to clean up // a few odds and ends. cdlloadablebody_cookie = CdlLoadableBody_Invalid; CYG_ASSERTC(0 == owned.size()); delete interp; interp = 0; directory = ""; CYGDBG_MEMLEAK_DESTRUCTOR(); CYG_REPORT_RETURN();}//}}}//{{{ Simple information access // ----------------------------------------------------------------------------const std::vector<CdlNode>&CdlLoadableBody::get_owned() const{ CYG_REPORT_FUNCNAME("CdlLoadable::get_owned"); CYG_REPORT_FUNCARG1XV(this); CYG_PRECONDITION_THISC(); CYG_REPORT_RETURN(); return owned;}boolCdlLoadableBody::owns(CdlConstNode node) const{ CYG_REPORT_FUNCNAMETYPE("CdlLoadable::owns", "result %d"); CYG_REPORT_FUNCARG2XV(this, node); CYG_PRECONDITION_THISC(); CYG_PRECONDITION_CLASSC(node); bool result = false; std::vector<CdlNode>::const_iterator i = std::find(owned.begin(), owned.end(), node); if (i != owned.end()) { result = true; } CYG_REPORT_RETVAL(result); return result;}CdlInterpreterCdlLoadableBody::get_interpreter() const{ CYG_REPORT_FUNCNAMETYPE("CdlLoadable::get_interpreter", "result %p"); CYG_REPORT_FUNCARG1XV(this); CYG_PRECONDITION_THISC(); CdlInterpreter result = interp; CYG_REPORT_RETVAL(result); return result;}std::string
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -