|
xentara-workbench-plugin v1.0.1
The Xentara Workbench Plugin Framework
|
Base class for elements provided by a Xentara skill. More...
#include <xentara/workbench/skill/Element.hpp>
Inheritance diagram for xentara::workbench::skill::Element:Classes | |
| class | Class |
| Meta-Information about an element class. More... | |
| class | ConcreteClass |
| Convenience subclass of Class that implements all callbacks. More... | |
| class | SyntheticChildPointer |
Public Types | |
| using | ForEachAttributeFunction = utils::functional::function_ref< auto(const model::Attribute &) ->bool > |
| A callback for iterating over all attributes. | |
| using | ForEachEventFunction = utils::functional::function_ref< auto(const process::Event &) ->bool > |
| A callback for iterating over all events. | |
| using | ForEachTaskFunction = utils::functional::function_ref< auto(const process::Task &) ->bool > |
| A callback for iterating over all tasks. | |
Public Member Functions | |
| virtual | ~Element ()=0 |
| Virtual destructor. | |
Access to the properties | |
| auto | name () const -> utils::string::StringView |
| Gets the name of the element. | |
| auto | primaryKey () const -> std::string |
| Gets the primary key of the element. | |
| auto | uuid () const -> utils::core::Uuid |
| Gets the UUID of the element. | |
| auto | elementClass () const noexcept -> const Class & |
| Gets the class of this element. | |
Access to the Xentara Element and the Element Hierarchy | |
| auto | element () const noexcept -> const model::Element & |
| Gets the Xentara element for this skill element. | |
| auto | childElements () const -> model::ChildElementAccessor |
| Returns a list of all the element’s children. | |
| auto | parentElement () const -> const model::Element & |
| Returns the element’s parent. | |
Public Member Functions inherited from xentara::workbench::bindings::PropertyController | |
| PropertyController () noexcept=default | |
| Default constructor. | |
| PropertyController (const PropertyController &) noexcept | |
| Copy constructor that does not actually copy anything. | |
| PropertyController (PropertyController &&) noexcept | |
| Copy constructor that does not actually move anything. | |
| constexpr auto | operator= (const PropertyController &) noexcept -> PropertyController & |
| Copy assignment operator that does not actually assign anything. | |
| constexpr auto | operator= (PropertyController &&) noexcept -> PropertyController & |
| Move assignment operator that does not actually assign anything. | |
| virtual | ~PropertyController ()=0 |
| virtual destructor | |
| template<typename Type , typename Value > requires std::equality_comparable_with<const Type &, const Value &> && std::assignable_from<Type &, Value &&> | |
| auto | setProperty (Type &property, Value &&value) const -> bool |
| Sets an address-based property, and publishes changes if necessary. | |
| template<typename Type , PropertyChangedInvocable ChangeCallback> | |
| auto | subscribe (const Type &property, ChangeCallback &&changeCallback) -> Subscription |
| Subscribes to an address-based property. | |
| template<typename Type > | |
| auto | subscribe (const Type &property, SubscriptionCallbacks callbacks) -> Subscription |
| Subscribes to an address-based property, with support for specialized callbacks. | |
| template<typename Type > | |
| auto | publish (const Type &property, Action action=Action::ValueChanged, std::size_t index={}) const -> void |
| Publishes a change to the value and state for an address-based property. | |
| template<typename Type > | |
| auto | publishValue (const Type &property, Action action=Action::ValueChanged, std::size_t index={}) const -> void |
| Publishes a change to only the value of an address-based property. | |
| template<typename Type > | |
| auto | publishState (const Type &property) const -> void |
| Publishes a change in only the state of an address-based property. | |
| template<typename Type > | |
| auto | publishVisibility (const Type &property) const -> void |
| Publishes a change in the visibility of an address-based property. | |
| template<typename Type > | |
| auto | propertyState (const Type &property) const -> const utils::eh::expected< void, ui::String > & |
| Gets the state of an address-based property. | |
| template<typename Type > | |
| auto | propertyVisible (const Type &property) const -> bool |
| Gets the visibility of an address-based property. | |
| template<typename Type > | |
| auto | propertyId (const Type &property) const noexcept -> PropertyId |
| Gets the ID of an address-based property. | |
| template<typename Type > | |
| auto | propertyHandle (const Type &property) noexcept -> PropertyHandle |
| Creates a handle for an address-based property. | |
| template<PropertyChangedInvocable ChangeCallback> | |
| auto | subscribe (const PropertyId &propertyId, ChangeCallback &&changeCallback) -> Subscription |
| Subscribes to a property. | |
| auto | subscribe (const PropertyId &propertyId, SubscriptionCallbacks callbacks) -> Subscription |
| Subscribes to a property, with support for specialized callbacks. | |
| auto | publish (const PropertyId &propertyId, Action action=Action::ValueChanged, std::size_t index={}) const -> void |
| Publishes a value and state change for a property. | |
| auto | publishValue (const PropertyId &propertyId, Action action=Action::ValueChanged, std::size_t index={}) const -> void |
| Publishes a change to only the value of a property. | |
| auto | publishState (const PropertyId &propertyId) const -> void |
| Publishes a change in the state of a property. | |
| auto | publishVisibility (const PropertyId &propertyId) const -> void |
| Publishes a change in the visibility of a property. | |
| auto | propertyState (const PropertyId &propertyId) const -> const utils::eh::expected< void, ui::String > & |
| Gets the state of a property. | |
| auto | propertyVisible (const PropertyId &propertyId) const -> bool |
| Gets the visibility of a property. | |
| auto | propertyHandle (const PropertyId &propertyId) noexcept -> PropertyHandle |
| Creates a handle for a property. | |
Public Member Functions inherited from xentara::workbench::bindings::PropertyContainer | |
| PropertyContainer () noexcept=default | |
| Default constructor. | |
| PropertyContainer (const PropertyContainer &other) | |
| Copy constructor. | |
| PropertyContainer (PropertyContainer &&other) noexcept | |
| Move constructor. | |
| auto | operator= (const PropertyContainer &rhs) -> PropertyContainer & |
| Copy assignment operator. | |
| auto | operator= (PropertyContainer &&rhs) noexcept -> PropertyContainer & |
| Move assignment operator that does not actually assign anything. | |
| virtual | ~PropertyContainer ()=0 |
| Virtual destructor. | |
| auto | setEnclosingPropertyContainer (PropertyContainer &enclosingContainer, SetEnclosingPropertyContainerOptions options={}) -> void |
| Sets the enclosing container. | |
| auto | resetEnclosingPropertyContainer (SetEnclosingPropertyContainerOptions options={}) -> void |
| Resets the enclosing container. | |
| auto | enclosingPropertyContainer () const -> PropertyContainer * |
| Gets the enclosing container. | |
| auto | propertyErrorCount () const -> std::size_t |
| Gets the number of error properties, including those of sub containers. | |
| template<std::invocable Callback> | |
| auto | subscribeToPropertyErrorCount (Callback &&callback) -> ErrorCountSubscription |
| Subscribes to a property. | |
| auto | forEachCrossReference (const ForEachCrossReferenceFunction &function, ForEachCrossReferenceOptions options={}) noexcept -> void |
| Calls a function for each cross reference contained within the container. | |
Protected Member Functions | |
Publishing changes | |
| auto | publishElementMembers () const -> void |
| Publishes a change in the list of attributes, events, and/or tasks. | |
| auto | publishSyntheticChildren () const -> void |
| Publishes a change in the list of synthetic children. | |
Protected Member Functions inherited from xentara::workbench::bindings::PropertyContainer | |
| auto | subPropertyContainerAdded (const PropertyContainer &container) -> void |
| Must be called by derived classes if a sub container was added. | |
| auto | subPropertyContainerRemoved (const PropertyContainer &container) -> void |
| Must be called by derived classes if a sub container was removed. | |
| auto | subPropertyContainerListChanged (SubPropertyContainerListChangedOptions options={}) -> void |
| Must be called by derived classes if the list of sub containers changed completely. | |
| auto | subPropertyContainerListCopied (const PropertyContainer &other, SubPropertyContainerListChangedOptions options={}) -> void |
| Must be called by derived classes if the list of sub containers was copied from another container. | |
| auto | subPropertyContainerListMoved (PropertyContainer &other, SubPropertyContainerListChangedOptions options={}) -> void |
| Must be called by derived classes if the list of sub containers was moved from another container. | |
| auto | subPropertyContainerListSwapped (PropertyContainer &other, SubPropertyContainerListChangedOptions options={}) -> void |
| Must be called by derived classes if the list of sub containers was swapped with another container. | |
| auto | localPropertyErrorCountChanged () -> void |
| Must be called by derived classes if the value returned by localPropertyErrorCount() has changed. | |
| auto | raisePropertyNotification (const PropertyId &propertyId) const -> void |
| Passes a property notification to the enclosing container. | |
Private Member Functions | |
Callbacks | |
| virtual auto | load (utils::json::decoder::Object &jsonObject, config::Context &context) -> void |
| Called by the framework to load the element’s configuration from a JSON object. | |
| virtual auto | save (utils::json::encoder::Object &jsonObject) const -> void |
| Called by the framework to save the element’s configuration to a JSON object. | |
| virtual auto | makeDefault () -> void |
| Called by the framework to prepare a newly created element for editing. | |
| virtual auto | forEachAttribute (const ForEachAttributeFunction &function) const -> bool |
| Called by the framework to iterate over all the attributes. | |
| virtual auto | forEachEvent (const ForEachEventFunction &function) const -> bool |
| Called by the framework to iterate over all the events. | |
| virtual auto | forEachTask (const ForEachTaskFunction &function) const -> bool |
| Called by the framework to iterate over all the tasks. | |
| virtual auto | createSyntheticChildren () const -> std::vector< SyntheticChildPointer > |
| Called by the framework to update the list of synthetic child elements. | |
| virtual auto | makeBinding () -> std::unique_ptr< bindings::AbstractElementBinding > |
| Called by the framework to create a binding for editing the element’s properties. | |
Callbacks for importing elements | |
| virtual auto | importId () const -> std::optional< utils::core::Uuid > |
| Called by the framework to determine whether which existing elements should be replaced during an import. | |
| virtual auto | importMerge (const model::Element &existingElement) -> void |
| Called by the framework to merge an imported element with an existing element. | |
| virtual auto | preserveExistingNameOnImport () const -> bool |
| Called by the framework to determine whether the element name should be preserved across imports. | |
Related Symbols | |
(Note that these are not member symbols.) | |
| template<std::derived_from< Element > Derived, typename... ConstructorArguments> | |
| auto | makeSyntheticChild (std::reference_wrapper< const Element::Class > elementClass, std::string name, ConstructorArguments &&...constructorArguments) -> Element::SyntheticChildPointer |
| Creates a synthetic child element. | |
| template<std::derived_from< Element > Derived, typename... ConstructorArguments> | |
| auto | makeSyntheticChild (std::string name, ConstructorArguments &&...constructorArguments) -> Element::SyntheticChildPointer |
| Creates a synthetic child, automatically selecting the class object. | |
Base class for elements provided by a Xentara skill.
| using xentara::workbench::skill::Element::ForEachAttributeFunction = utils::functional::function_ref<auto(const model::Attribute &)->bool> |
A callback for iterating over all attributes.
| using xentara::workbench::skill::Element::ForEachEventFunction = utils::functional::function_ref<auto(const process::Event &)->bool> |
A callback for iterating over all events.
| using xentara::workbench::skill::Element::ForEachTaskFunction = utils::functional::function_ref<auto(const process::Task &)->bool> |
A callback for iterating over all tasks.
|
pure virtualdefault |
Virtual destructor.
| auto xentara::workbench::skill::Element::childElements | ( | ) | const -> model::ChildElementAccessor |
Returns a list of all the element’s children.
This function is a equivalent to element().childElements().
|
privatevirtual |
Called by the framework to update the list of synthetic child elements.
A synthetic child element is a child element that is automatically created by the parent, and does not appear in the configuration.
|
noexcept |
Gets the Xentara element for this skill element.
|
noexcept |
Gets the class of this element.
|
privatevirtual |
Called by the framework to iterate over all the attributes.
Implementations must call the given function once for each attribute, until the function returns true. If the function returns true for any attribute, the implementation must return true, otherwise false. A possible implementation looks like this:
| function | The function that should be called for each attribute |
|
privatevirtual |
Called by the framework to iterate over all the events.
Implementations must call the given function once for each event, until the function returns true. If the function returns true for any event, the implementation must return true, otherwise false. A possible implementation looks like this:
| function | The function that should be called for each event |
|
privatevirtual |
Called by the framework to iterate over all the tasks.
Implementations must call the given function once for each task, until the function returns true. If the function returns true for any task, the implementation must return true, otherwise false. A possible implementation looks like this:
| function | The function that should be called for each task |
|
privatevirtual |
Called by the framework to determine whether which existing elements should be replaced during an import.
This function is called by the framework when a file is imported using an [import button](bindings::ImportButton]. If one of the newly created elements has the same import ID as an existing element, the existing element is replaced. This is used to make sure that equivalent elements are replaced when importing the same or an equivalent file multiple times.
For example, if the user imports an EtherCAT Network Information (ENI) file, elements are created for the devices and data items described in the file. The user may then add a new device, update the ENI file, and re-import it. When the file is imported a second time, the existing devices from the previous import need to be replaced. The framework will use the UUID returned by importId() to match the new devices to the old ones.
By default, this replacement is done based on the primary keys of the elements: an imported element with a certain primary key will replace an existing element with the same primary key. Sometimes, however, it is preferrable that elements be replaced based on some external unique identifier, like a protocol address. In such cases, the you can generate an import ID that will be used to match up equivalent elements.
A custom import ID should be based on some external unique identifier, like an OPC/UA identifier, a PLC variable name, or a Modbus register address. If the external identifier is already a UUID, you can use it directly. Otherwise, you can use utils::core::Uuid::createVersion5() to create a UUID from the identifier. Make sure to use a unique namespace UUID (the first parameter to utils::core::Uuid::createVersion5()) for each identifier namespace. For Modbus register addresses, for example, you need to use different namespace UUIDs for each of the four register types (coils, discrete inputs, input registers, and holding registers). This will prevent so that the Xentara Workbench from erroneously replacing coil 11 with holding register 11, for example.
If you want an element to never replace or be replaced by another element, you can return a null (default constructed) UUID from this callback. Null UUID are never matched up, and elements that return a null UUID will never replace or be replaced by another element.
If you want to retain the default behaviour of replacing elements based on primary key, you can return std::nullopt from this callback.
|
privatevirtual |
Called by the framework to merge an imported element with an existing element.
This function is called by the framework whenever an existing element is replaced with a new element during an import. This function should copy all information that is not contained in the import file from the old element to the new element. This can include things like the selected poll command, timeout behaviour, or other options.
| existingElement | The element that will be replaced. You can use [element_cast()](model::Element::element_cast(Element *element)] to cast the element to the required type. Just remember to use the overload that takes a pointer, rather than the reference overload, because the reference overload will throw an std::bad_cast exception if the element does not have the correct type, which is undesirable. |
|
privatevirtual |
Called by the framework to load the element’s configuration from a JSON object.
The standard configuration parameters "name", "UUID", "ACL", and "children" are handled automatically by the framework using a JSON object filter. The corresponding JSON members are filtered out, and will not be enumerated when you iterate over the JSON object’s members.
This function is called before the framework subscribes to any of the element’s properties via the base class bindings::PropertyController. It is therefore not necessary to publish any property changes as the properties are loaded.
| jsonObject | The JSON object. The object has a filter installed that will filter out and handle the standard configuration parameters. |
| context | A context that can be used to resolve cross-references. |
| std::runtime_error | The function must throw this exception (or a suitable subclass) if an error occurs. The loading function should be as permissive as possible, to allow faulty model files to be repaired using the Workbench. |
Reimplemented in xentara::workbench::skill::PlaceholderElement< DerivedElement, kClassName, kUuid, DisplayName, MenuText, kNewElementName, kCategory, kIsIncomplete >.
|
privatevirtual |
Called by the framework to create a binding for editing the element’s properties.
This callback is called whenever the user tries to edit the properties of the element. The binding defines the UI elements that should be shown, and how these UI elements affect the properties of the skill element.
The binding will normally bind the user interface to member functions or member variables of the element being edited. To facilitate this, you can derive your binding class from bindings::ElementBinding rather than bindings::AbstractElementBinding.
Reimplemented in xentara::workbench::skill::PlaceholderElement< DerivedElement, kClassName, kUuid, DisplayName, MenuText, kNewElementName, kCategory, kIsIncomplete >.
|
privatevirtual |
Called by the framework to prepare a newly created element for editing.
This function should set some default values to be used for new elements created in the Workbench. The function only needs to set values that are not already initialized to the desired values in the constructor.
| auto xentara::workbench::skill::Element::name | ( | ) | const -> utils::string::StringView |
Gets the name of the element.
| auto xentara::workbench::skill::Element::parentElement | ( | ) | const -> const model::Element & |
Returns the element’s parent.
This function is a equivalent to calling *element().parentElement().
|
privatevirtual |
Called by the framework to determine whether the element name should be preserved across imports.
This function is called by the framework whenever an existing element is replaced with a new element during an import to determine whether the existing name should be preserved on import.
If you return true from this callback, then names of imported elements will be overwritten by the names of elements they replace. If you return false (the default), then the name specified in the import data is kept.
This function is called on the imported element, not the element being replaced.
| auto xentara::workbench::skill::Element::primaryKey | ( | ) | const -> std::string |
Gets the primary key of the element.
|
protected |
Publishes a change in the list of attributes, events, and/or tasks.
|
protected |
Publishes a change in the list of synthetic children.
|
privatevirtual |
Called by the framework to save the element’s configuration to a JSON object.
The standard configuration parameters "name", "UUID", "ACL", and "children" are handled automatically by the framework and must not be written to the object.
| jsonObject | The JSON object. |
Reimplemented in xentara::workbench::skill::PlaceholderElement< DerivedElement, kClassName, kUuid, DisplayName, MenuText, kNewElementName, kCategory, kIsIncomplete >.
| auto xentara::workbench::skill::Element::uuid | ( | ) | const -> utils::core::Uuid |
Gets the UUID of the element.
|
related |
Creates a synthetic child element.
A synthetic child element is a child element that is automatically created by the parent, and does not appear in the configuration. You would normally call this function from your implementation of [createSyntheticChildren()[(Element::createSyntheticChildren())
| Derived | The class of the child element |
| elementClass | The meta-information object for the class of the child element |
| name | The name of the child element |
| constructorArguments | The arguments for the element’s constructor. |
|
related |
Creates a synthetic child, automatically selecting the class object.
A synthetic child element is a child element that is automatically created by the parent, and does not appear in the configuration. You would normally call this function from your implementation of [createSyntheticChildren()[(Element::createSyntheticChildren())
This function fetches the meta-information object for the child element class by calling Derived::Class::instance(). It is equivalent the following:
| Derived | The class of the child element. The meta-information object for the class must be available using Derived::Class::instance(). |
| name | The name of the child element |
| constructorArguments | The arguments for the element’s constructor. |