📄 cdlcore.hxx
字号:
// A definable object is a valuable object whose value can result// in #define statements in a header fileclass CdlDefinableBody;// A loadable which can contain definablesclass CdlDefineLoadableBody;// TODO: add instantiation support// Custom dialogs and wizards are provided by the core.class CdlDialogBody;class CdlWizardBody;class CdlInterfaceBody;// Support for Tcl interpreters is also in the core, since it is// difficult to do anything CDL-related without at least one Tcl// interpreter lying around.class CdlInterpreterBody;// The basic conflict class is part of the core library, as are a// number of common derived classes for specific types of conflict.class CdlConflictBody;class CdlConflict_UnresolvedBody;class CdlConflict_IllegalValueBody;class CdlConflict_EvalExceptionBody;class CdlConflict_RequiresBody;class CdlConflict_DataBody;// Many operations happen (or may happen) in the context of a// transaction. This is necessary to keep track of the various// changes that can happen: for example, changing a component's// value may require other entities' default values to be// recalculated; it may change some legal_values list expressions,// causing current values to become invalid; it may affect// "requires" properties, causing goals to become satisfied or// not-satisfied; it may change the "active" state of everything// below the component, not to mention any entity with an// "active_if" properties, and when an entity becomes active or// inactive that may in turn affect other entities.//// Keeping track of all of this via recursion is possible, but there// are problems. If an entity is updated multiple times, no// optimizations are possible. It becomes much more difficult to// detect cycles. During an unload operation things can get very// messy. There is no easy way to track all of the changes and report// them to higher level code via a callback. There is no support// for any kind of rollback. A transaction model potentially// provides support for all of this, at the cost of a more// complex API.class CdlTransactionBody;// This class is used to pass information back to the application// about what has actually changed in a transaction.class CdlTransactionCallback;// Build info class. This is always an expanded object, but is// needed here to break a circular dependency.class CdlBuildInfo;// ----------------------------------------------------------------------------// Typedefs for the pointers. There are separate typedefs to cope with// const vs. non-const objects. Otherwise you end up with the problem// that "const CdlNode x" means that the pointer is const, not the// object pointed at.typedef CdlExpressionBody* CdlExpression;typedef CdlListExpressionBody* CdlListExpression;typedef CdlGoalExpressionBody* CdlGoalExpression;typedef CdlPropertyBody* CdlProperty;typedef CdlProperty_MinimalBody* CdlProperty_Minimal;typedef CdlProperty_StringBody* CdlProperty_String;typedef CdlProperty_TclCodeBody* CdlProperty_TclCode;typedef CdlProperty_ReferenceBody* CdlProperty_Reference;typedef CdlProperty_StringVectorBody* CdlProperty_StringVector;typedef CdlProperty_ExpressionBody* CdlProperty_Expression;typedef CdlProperty_ListExpressionBody* CdlProperty_ListExpression;typedef CdlProperty_GoalExpressionBody* CdlProperty_GoalExpression;typedef CdlNodeBody* CdlNode;typedef CdlContainerBody* CdlContainer;typedef CdlLoadableBody* CdlLoadable;typedef CdlToplevelBody* CdlToplevel;typedef CdlUserVisibleBody* CdlUserVisible;typedef CdlValuableBody* CdlValuable;typedef CdlParentableBody* CdlParentable;typedef CdlBuildableBody* CdlBuildable;typedef CdlBuildLoadableBody* CdlBuildLoadable;typedef CdlDefinableBody* CdlDefinable;typedef CdlDefineLoadableBody* CdlDefineLoadable;typedef CdlDialogBody* CdlDialog;typedef CdlWizardBody* CdlWizard;typedef CdlInterfaceBody* CdlInterface;typedef CdlInterpreterBody* CdlInterpreter;typedef CdlConflictBody* CdlConflict;typedef CdlConflict_UnresolvedBody* CdlConflict_Unresolved;typedef CdlConflict_IllegalValueBody* CdlConflict_IllegalValue;typedef CdlConflict_EvalExceptionBody* CdlConflict_EvalException;typedef CdlConflict_RequiresBody* CdlConflict_Requires;typedef CdlConflict_DataBody* CdlConflict_Data;typedef CdlTransactionBody* CdlTransaction;// ----------------------------------------------------------------------------typedef const CdlExpressionBody* CdlConstExpression;typedef const CdlListExpressionBody* CdlConstListExpression;typedef const CdlGoalExpressionBody* CdlConstGoalExpression;typedef const CdlPropertyBody* CdlConstProperty;typedef const CdlProperty_MinimalBody* CdlConstProperty_Minimal;typedef const CdlProperty_StringBody* CdlConstProperty_String;typedef const CdlProperty_TclCodeBody* CdlConstProperty_TclCode;typedef const CdlProperty_ReferenceBody* CdlConstProperty_Reference;typedef const CdlProperty_StringVectorBody* CdlConstProperty_StringVector;typedef const CdlProperty_ExpressionBody* CdlConstProperty_Expression;typedef const CdlProperty_ListExpressionBody* CdlConstProperty_ListExpression;typedef const CdlProperty_GoalExpressionBody* CdlConstProperty_GoalExpression;typedef const CdlNodeBody* CdlConstNode;typedef const CdlContainerBody* CdlConstContainer;typedef const CdlLoadableBody* CdlConstLoadable;typedef const CdlToplevelBody* CdlConstToplevel;typedef const CdlUserVisibleBody* CdlConstUserVisible;typedef const CdlValuableBody* CdlConstValuable;typedef const CdlParentableBody* CdlConstParentable;typedef const CdlBuildableBody* CdlConstBuildable;typedef const CdlBuildLoadableBody* CdlConstBuildLoadable;typedef const CdlDefinableBody* CdlConstDefinable;typedef const CdlDefineLoadableBody* CdlConstDefineLoadable;typedef const CdlDialogBody* CdlConstDialog;typedef const CdlWizardBody* CdlConstWizard;typedef const CdlInterfaceBody* CdlConstInterface;typedef const CdlInterpreterBody* CdlConstInterpreter;typedef const CdlConflictBody* CdlConstConflict;typedef const CdlConflict_UnresolvedBody* CdlConstConflict_Unresolved;typedef const CdlConflict_IllegalValueBody* CdlConstConflict_IllegalValue;typedef const CdlConflict_EvalExceptionBody* CdlConstConflict_EvalException;typedef const CdlConflict_RequiresBody* CdlConstConflict_Requires;typedef const CdlConflict_DataBody* CdlConstConflict_Data;typedef const CdlTransactionBody* CdlConstTransaction;//}}}//{{{ Miscellaneous types etc. // ----------------------------------------------------------------------------// This section is used for data types, function prototypes, etc. which could// not be defined until after the main CDL classes and handles.// This typedef is used for error and warning reporting functions.// Typically such a function pointer will be passed when the library// is asked to perform any non-trivial parsing operation, e.g. loading// a package.//// If the error is fatal then this callback function should raise// a CdlParseException.typedef void (*CdlDiagnosticFnPtr)(std::string);// ----------------------------------------------------------------------------// This function is used for update handler. Whenever there is a change// to CDL entity (it has just been loaded, or its value has changed, or// whatever) this can affect other CDL entities that reference it.// All such references occur via properties, and there should be// update handlers associated with those properties.//// Update handlers are also invoked for initialization and finalization// operations, i.e. when the source object itself has just been loaded// or is in the process of being unloaded.//// The arguments to an update handler are:// 1) the transaction in which the operation takes place// 2) the source object containing the reference// 3) the source property containing the reference// 4) the destination object. This may be 0 for some update// operations.// 5) an indication of the change that has happened. This should// be a CdlUpdate value.typedef void (*CdlUpdateHandler)(CdlTransaction, CdlNode, CdlProperty, CdlNode, CdlUpdate);// ----------------------------------------------------------------------------// This function is also used for transactions. Typically during a// transaction there will be one or more invocations of the inference engine,// with callbacks in between to allow one or more of the recommended// changes to be undone.typedef CdlInferenceCallbackResult (*CdlInferenceCallback)(CdlTransaction);// ----------------------------------------------------------------------------// The TCL API and C++ do not always mesh cleanly, for example a lot// happens in terms of ClientData which is a void* pointer. To avoid// too many casts all over the place libcdl provides a CdlInterpreter// class and the following alternative to Tcl_CmdProc*. A single// function will be used for the TCL command: its ClientData will be// the CdlInterpreterCommand, and the CdlInterpreter is accessible via// AssocData. This does result in some overheads, but none of these// should be in performance-critical code.typedef int (*CdlInterpreterCommand)(CdlInterpreter, int, char*[]);// ----------------------------------------------------------------------------// In the libcdl world it is often convenient to swap whole sets of// commands in and out. For example when executing the body of a// cdl_component it is desirable to swap in commands for all the// properties that make sense in a component and swap out all the// commands that made sense in a higher level. It is assumed that none// of the commands being swapped in or out are built-ins. Achieving// this involves a vector of this simple utility structure.class CdlInterpreterCommandEntry { public: std::string name; CdlInterpreterCommand command; CdlInterpreterCommandEntry() : name(""), command(0) {} CdlInterpreterCommandEntry(const char *name_arg, CdlInterpreterCommand command_arg) : name(name_arg), command(command_arg) { } CdlInterpreterCommandEntry(std::string name_arg, CdlInterpreterCommand command_arg) : name(name_arg), command(command_arg) { } ~CdlInterpreterCommandEntry() { name = ""; command = 0; }};// ----------------------------------------------------------------------------// Persistence support.// Some applications want to be able to store additional information// in savefiles, and essentially this involves extra commands that// get executed when the savefile is executed. It is possible that// the application reading back the savefile does not understand// the same set of commands as the application that wrote back the// data, so the library tries hard not to lose data.//// The CdlSaveCallback function typedef is used when installing// an application-specific savefile command. The first argument// indicates the node for which the callback is being invoked:// this may be the entire toplevel, or just an option, or whatever.//// The CdlSavefileCommand structure keeps track of the command,// the save callback if any (non-zero only for application-specific// data, zero implies that the command is handled by the lirary).// The load command is invoked when reading in a savefile and the// appropriate command is executed: unrecognised commands will be// processed by CdlToplevelBody::savefile_handle_unknown().typedef void (*CdlSaveCallback)(CdlNode, CdlInterpreter, Tcl_Channel, int);struct CdlSavefileCommand { std::string name; CdlSaveCallback save_callback; CdlInterpreterCommand load_command;};// ----------------------------------------------------------------------------// Widget hint.// This structure provides widget hint information for a CdlValuable.// There are separate hints for the bool and data parts, and possibly// some additional data such as a string identifying the set of// items in a radio button.struct CdlWidgetHint { CdlBoolWidget bool_widget; CdlValueWidget value_widget; std::string radio_button_interface;};//}}}//{{{ Memory leak detection // ----------------------------------------------------------------------------// Provide some macros that are useful for detecting memory leaks. Basically// there is a static counter for every class, which gets incremented by the// constructor(s) and decremented by the destructor. Memory leak detection// is currently enabled if tracing is enabled. It would be possible to use// another configure-time option, but the overheads of tracing are likely// to dwarf the overheads of memory leak detection.//// For now the memleak counters are always present, even in non-debug// versions. The overhead is sufficiently small that it can be// ignored.There is control over whether or not the counters get// updated in the constructor or destructor. Otherwise there would be problems// with whether or not there should be a semicolon at the end of the// CYGDBG_DECLARE_MEMLEAK_COUNTER() macro definition.#define CYGDBG_DECLARE_MEMLEAK_COUNTER() static int memleak_counter#define CYGDBG_DEFINE_MEMLEAK_COUNTER(class) int class::memleak_counter = 0#define CYGDBG_GET_MEMLEAK_COUNTER(class) class::memleak_counter#ifdef CYGDBG_USE_TRACING#define CYGDBG_MEMLEAK_CONSTRUCTOR() this->memleak_counter++;#define CYGDBG_MEMLEAK_DESTRUCTOR() this->memleak_counter--;#define CYGDBG_MEMLEAK_CHECKTHIS() if (this->memleak_counter < 0) { return false; } #else#define CYGDBG_MEMLEAK_CONSTRUCTOR()#define CYGDBG_MEMLEAK_DESTRUCTOR()#define CYGDBG_MEMLEAK_CHECKTHIS()#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -