📄 interface.cxx
字号:
} catch(...) { interp->set_result(CdlParse::construct_diagnostic(interp, "internal error", "", "Unexpected C++ exception")); result = TCL_ERROR; } // Restore the interpreter to its prior state. interp->pop_node(old_node); if (0 != old_commands) { interp->pop_commands(old_commands); } CYG_REPORT_RETVAL(result); return result;}//}}}//{{{ Persistence support // ----------------------------------------------------------------------------voidCdlInterfaceBody::initialize_savefile_support(CdlToplevel toplevel){ CYG_REPORT_FUNCNAME("CdlInterface::initialize_savefile_support"); toplevel->add_savefile_command("cdl_interface", 0, &savefile_interface_command); CdlValuableBody::initialize_savefile_support(toplevel, "cdl_interface"); CYG_REPORT_RETURN();}voidCdlInterfaceBody::save(CdlInterpreter interp, Tcl_Channel chan, int indentation, bool minimal){ CYG_REPORT_FUNCNAME("CdlInterface::save"); CYG_REPORT_FUNCARG5XV(this, interp, chan, indentation, minimal); CYG_PRECONDITION_THISC(); CYG_PRECONDITION_CLASSC(interp); // Interfaces contain only calculated data, so for a minimal save // there is no point in storing any of the data. if (!minimal || this->has_additional_savefile_information()) { // Start with the UserVisible data, which will result in a suitable set // of comments before the package definition itself. this->CdlUserVisibleBody::save(interp, chan, indentation, minimal); // Now output the line "cdl_interface <name> {" // The name is guaranteed to be a valid C preprocessor symbol, so it // is not going to need any quoting. std::string data = std::string(indentation, ' ') + "cdl_interface " + get_name() + " {\n"; // Start with details of everything that implements this interface. if (!minimal) { const std::vector<CdlReferrer>& referrers = this->get_referrers(); std::vector<CdlReferrer>::const_iterator ref_i; int real_referrers = 0; for (ref_i = referrers.begin(); ref_i != referrers.end(); ref_i++) { CdlNode node = ref_i->get_source(); CdlProperty prop = ref_i->get_source_property(); CdlValuable valuable = dynamic_cast<CdlValuable>(node); if ((0 != valuable) && (CdlPropertyId_Implements == prop->get_property_name())) { real_referrers++; data += std::string(indentation, ' ') + " # Implemented by " + valuable->get_name() + ", " + (valuable->is_active() ? "active" : "inactive") + ", " + (valuable->is_enabled() ? "enabled" : "disabled") + '\n'; } } if (0 == real_referrers) { data += std::string(indentation, ' ') + " # No options implement this inferface\n"; } } interp->write_data(chan, data); // Deal with the value this->CdlValuableBody::save(interp, chan, indentation + 4, false, minimal); // Close the cdl_interface body. A blank line is added here. data = "};\n\n"; interp->write_data(chan, data); } CYG_REPORT_RETURN();}intCdlInterfaceBody::savefile_interface_command(CdlInterpreter interp, int argc, char** argv){ CYG_REPORT_FUNCNAMETYPE("CdlInterface::savefile_interface_command", "result %d"); CYG_PRECONDITION_CLASSC(interp); int result = TCL_OK; CdlToplevel toplevel = interp->get_toplevel(); CYG_ASSERT_CLASSC(toplevel); std::vector<CdlInterpreterCommandEntry> subcommands; std::vector<CdlInterpreterCommandEntry>* toplevel_commands = 0; CdlNode old_node = 0; try { if (3 != argc) { CdlParse::report_error(interp, "", "Invalid cdl_interface command in savefile, expecting two arguments."); } else { CdlNode current_node = toplevel->lookup(argv[1]); if (0 == current_node) { // FIXME: save value in limbo CdlParse::report_error(interp, "", std::string("The savefile contains a cdl_interface command for an unknown interface `") + argv[1] + "'."); } else { toplevel->get_savefile_subcommands("cdl_interface", subcommands); toplevel_commands = interp->push_commands(subcommands); old_node = interp->push_node(current_node); std::string tcl_result; result = interp->eval(argv[2], tcl_result); interp->pop_commands(toplevel_commands); toplevel_commands = 0; interp->pop_node(old_node); old_node = 0; } } } catch(...) { if (0 != old_node) { interp->pop_node(old_node); } if (0 != toplevel_commands) { interp->pop_commands(toplevel_commands); } throw; } CYG_REPORT_RETVAL(result); return result;}//}}}//{{{ check_this() // ----------------------------------------------------------------------------boolCdlInterfaceBody::check_this(cyg_assert_class_zeal zeal) const{ if (CdlInterfaceBody_Magic != cdlinterfacebody_cookie) { return false; } CYGDBG_MEMLEAK_CHECKTHIS(); return CdlNodeBody::check_this(zeal) && CdlUserVisibleBody::check_this(zeal) && CdlValuableBody::check_this(zeal) && CdlParentableBody::check_this(zeal) && CdlBuildableBody::check_this(zeal) && CdlDefinableBody::check_this(zeal);}//}}}//{{{ recalculate() // ----------------------------------------------------------------------------// There has been a change in the configuration which may affect the value// of an interface. This can happen for a variety of reasons. For simplicity// the entire value is just recalculated, with no attempt at optimisation.// This may have to change in future.voidCdlInterfaceBody::recalculate(CdlTransaction transaction){ CYG_REPORT_FUNCNAME("CdlInterface::recalculate"); const CdlValue& old_value = transaction->get_whole_value(this); cdl_int count = 0; std::vector<CdlValuable> implementers; std::vector<CdlValuable>::const_iterator valuable_i; this->get_implementers(implementers); for (valuable_i = implementers.begin(); valuable_i != implementers.end(); valuable_i++) { if (transaction->is_active(*valuable_i)) { const CdlValue& implementer_value = transaction->get_whole_value(*valuable_i); if (implementer_value.is_enabled()) { count++; } } } // What to do with the count depends on the flavor. switch(this->get_flavor()) { case CdlValueFlavor_Bool : { bool new_bool = (count > 0); if (new_bool != old_value.is_enabled()) { CdlValue new_value = old_value; new_value.set_enabled(new_bool, CdlValueSource_Default); transaction->set_whole_value(this, old_value, new_value); } break; } case CdlValueFlavor_BoolData: { // The only thing that actually needs checking is the count value. // Iff that has changed then the boolean part may need changing as well. if (count != old_value.get_integer_value()) { CdlValue new_value = old_value; new_value.set_enabled_and_value(count > 0, count, CdlValueSource_Default); transaction->set_whole_value(this, old_value, new_value); } break; } case CdlValueFlavor_Data: { if (count != old_value.get_integer_value()) { CdlValue new_value = old_value; new_value.set_integer_value(count, CdlValueSource_Default); transaction->set_whole_value(this, old_value, new_value); } break; } default: break; } CYG_REPORT_RETURN();}//}}}//{{{ misc // ----------------------------------------------------------------------------boolCdlInterfaceBody::is_modifiable() const{ CYG_REPORT_FUNCNAME("CdlInterface::is_modifiable (false)"); CYG_PRECONDITION_THISC(); CYG_REPORT_RETURN(); return false;}std::stringCdlInterfaceBody::get_class_name() const{ CYG_REPORT_FUNCNAME("CdlInterface::get_class_name"); CYG_PRECONDITION_THISC(); CYG_REPORT_RETURN(); return "interface";}voidCdlInterfaceBody::get_implementers(std::vector<CdlValuable>& implementers) const{ CYG_REPORT_FUNCNAME("CdlInterface::get_implementers"); CYG_PRECONDITION_THISC(); const std::vector<CdlReferrer>& referrers = this->get_referrers(); std::vector<CdlReferrer>::const_iterator ref_i; for (ref_i = referrers.begin(); ref_i != referrers.end(); ref_i++) { CdlNode node = ref_i->get_source(); CdlProperty prop = ref_i->get_source_property(); CdlValuable valuable = dynamic_cast<CdlValuable>(node); if ((0 != valuable) && (CdlPropertyId_Implements == prop->get_property_name())) { implementers.push_back(valuable); } } CYG_REPORT_RETURN();}// Interfaces are somewhat peculiar, in that they can be defined implicitly// simply by occurring in an "implements" property, or explicitly inside// a CDL script. Worse, they can switch between these two states when// loadables are added or removed.boolCdlInterfaceBody::was_generated() const{ CYG_REPORT_FUNCNAMETYPE("CdlInterface::was_generated", "result %d"); CYG_REPORT_FUNCARG1XV(this); CYG_PRECONDITION_THISC(); bool result = this->generated; CYG_REPORT_RETVAL(result); return result;}//}}}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -