.. _release-notes-24.01: ========================= SMTK 24.01 Release Notes ========================= See also :ref:`release-notes-23.04` for previous changes. API-Breaking Changes ==================== We have been forced to remove ``smtk::task::Adaptor::reconfigureTask()`` which has been replaced by ``smtk::task::Adaptor::updateDownstreamTask(State upstreamPrev, State upstreamNext)`` and is a pure virtual method that must be overridden. Normally we would have deprecated the method but the issue is that derived classes may have overridden reconfigureTask and it would have been difficult to indicate these methods needed to be replaced. By removing this virtual method, the compiler will now see these overridden methods as errors. SMTK Common Related Changes ===================================== Default observer priority ------------------------- The :smtk:`smtk::common::Observers` template now uses a default priority of 0 instead of ``std::numeric_limits::lowest()`` (which is a negative number). Any code that inserts observers using the signature that does not take an explicit priority may now invoke that observer earlier than in previous releases of SMTK. If you wish to maintain the old behavior, you must now explicitly pass a priority. The :smtk:`smtk::common::Observers` template now provides methods named ``defaultPriority()`` and ``lowestPriority()`` for your convenience. This change was made to facilitate observers provided by SMTK that need to ensure they are the last invoked after an operation since they release objects from managers and may invalidate the operation result object. TypeContainer Changes --------------------- A few minor changes were made to :smtk:`smtk::common::TypeContainer`: + Methods and variables that were previously private are now protected so that this class can be subclassed. + The wrapper class used to store objects in the type container now provides a string token holding the type-name of the inserted type. This is used by the new :smtk:`smtk::common::RuntimeTypeContainer` subclass described below. + The ``insert_or_assign()`` method has been renamed ``insertOrAssign()`` to be consistent with the rest of SMTK. The original name is deprecated and will be removed in a future version of SMTK. New RuntimeTypeContainer ------------------------ :smtk:`smtk::common::RuntimeTypeContainer` is a new subclass of TypeContainer. The base TypeContainer class can only hold a single object of a given type. When applications handle many objects that share a common base type (i.e., whose complete type is unknown since only a pointer to a base type is held), there was no way to insert these distinct objects into a TypeContainer even if their complete types were distinct. To resolve this issue, the RuntimeTypeContainer class allows you to insert objects by their base type but use a "declared type-name" as the key. As long as these declared type-names are unique, multiple objects sharing the base type can be held by the container simultaneously. See the class and its test for detailed documentation. Type Hierarchy Reflection ------------------------- SMTK has long provided ``smtkTypeMacro()`` and ``smtkSuperclassMacro()`` in order to provide classes with type-aliases and virtual methods that allow reflection of an object's type. This has now been extended to provide (when a ``Superclass`` type-alias is present) the entire inheritance hierarchy. In addition to the virtual ``typeName()`` method, each class that uses ``smtkTypeMacro()`` or ``smtkTypeMacroBase()`` now provides * ``matchesType(smtk::string::Token baseType)`` – which returns true if the object is or inherits the given base type * ``classHierarchy()`` – which returns a vector of string-tokens holding the type-names of the object and its base classes. * ``generationsFromBase(smtk::string::Token baseType)`` – which returns an integer indicating the number of "hops" along the inheritance tree required to get from the object's type to the given base type. See ``smtk/common/testing/cxx/UnitTestTypeHierarchy.cxx`` for examples. SMTK Resource Related Changes ============================= Resource Manager No Longer Adds Created Resources To Itself ----------------------------------------------------------- While some signatures of ``smtk::resource::Manager::create()`` no longer added their returned resources to the resource manager, not all of them did. This inconsistency has been corrected such that no call to create a resource adds it to the manager; this required changes to several tests. If your project relies on resources being automatically added to the resource manager as it creates them, you will need to change your code manually add them with ``smtk::resource::Manager::add()`` after your call to ``create()``. Note that in proper applications (as opposed to tests or batch scripts), you should always create resources inside an :smtk:`Operation ` and append it to a :smtk:`smtk::attribute::ResourceItem` named "resource" in your operation's result. This will result in the resource being added to the manager at the completion of the operation rather than immediately (during the operation). The immediate addition of newly-created (and thus empty) resources was problematic when the resource was further modified by the operation since the the order of observations in Qt-based applications cause the application to ignore newly-created components in the new resource. Removed the MODIFIED Event from the Resource Manager ---------------------------------------------------- It was determined that this event type was redundant since actions that would cause a Resource to be modified should be done via operations which would produce they own events. In addition, it was observed that in some cases, operations that would change a Resource's **clean** state, would trigger the Resource's manager to emit its MODIFIED event which caused observer issues. **Note:** The Resource::setClean method was the only thing that would explicitly cause the MODIFIED event to be emitted (though other methods do call setClean) and no longer does so. Supporting Object Type Labels in the Resource Manager ----------------------------------------------------- The :smtk:`smtk::resource::Manager` class now provides an ``objectTypeLabels()`` method returning a map that registrars can use to register human-readable (and application-specific) strings given an object's type-name. This method is intended to map fully-qualified type-names for *any* class to labels that are descriptive to users, not just subclasses of :smtk:`smtk::resource::PersistentObject`. Labels should be as short as possible while remaining descriptive; applications should not expect labels to be sentences or paragraphs of text. If you use the ``smtkTypeMacroBase()``/``smtkTypeMacro()`` macros, you can use the virtual ``typeToken()`` method on any object to identify its class name and search the map returned by ``objectTypeLabels()`` to obtain a human-readable string. You can also use the :smtk:`smtk::common::typeName` template to identify a string for any class and look it up in the map. Applications should only look names up; registrars should write data to the map. If existing registrars use a name that is unsuitable for your application, simply create a registrar in your application whose ``Dependencies`` tuple lists these registrars and overwrite their strings with ones better for your application; because your application registrar depends on others, it will always be invoked last. Currently, this facility is only used by the diagram panel. (In the future, descriptive phrases may also adopt these type labels.) SMTK Attribute Related Changes ============================== Expanding Units Support in Attribute Resource --------------------------------------------- SMTK's Attribute DoubleItems and DoubleItemDefinitions can now support units specified as Defaults as well as values. When a default's or value's units differ from those defined by the Item's Definition, they are converted into the Definition's units. If no conversion is possible then the method assigning the default or value will fail. The Item's value(...) methods will always return the value in the units specified in its Definition. The Item's valueAsString(...) methods will always return a string based on the unconverted value When specifying Default Values (for DoubleItemDefinitions) and Values (for DoubleItems) the following is the expected behavior: ``DoubleItemDefinition::setDefaultValueAsString`` and ``DoubleItemDefinition::setDefaultValue`` 1. Will only append units to its default string values iff its units are supported by its units system 2. Will remove the units from a default value string iff its units are not supported by its units system 3. Its static splitStringStartingDouble method now trims both the value and units strings it returns. 4. Added a hasSupportedUnits method that returns true if the Definition's units are set and are supported by its units system. ``DoubleItem::setValue and DoubleItem::setValueFromString`` 1. Will only append units if its definition's units are supported by its units system and the input value string does not contains units 2. Will remove units from an input value string if its definition's units are not supported by its units system Developer changes ~~~~~~~~~~~~~~~~~~ SMTK Resources can now hold a units::System. In the case of an Attribute Resource, it will have a default units::System associated with it at construction time; however, this can be replaced as long as there are no Definitions defined within the Resource. New Resource Methods: * ``setUnitsSystem(const shared_ptr & unitsSystem)`` * ``const shared_ptr & unitsSystem() const;`` All ItemDefintions now hold onto a units::System. The methods are protected and are identical to the ones added to Resource. DoubleItemDefinition has the following new methods: * ``bool setDefaultValue(const double& val, const std::string& units);`` * ``bool setDefaultValue(const std::vector& vals, const std::string& units);`` * ``bool setDefaultValueAsString(const std::string& val);`` * ``bool setDefaultValueAsString(std::size_t element, const std::string& val);`` * ``bool setDefaultValueAsString(const std::vector& vals);`` * ``const std::string defaultValueAsString(std::size_t element = 0) const;`` * ``const std::vector defaultValuesAsStrings() const;`` * ``bool hasSupportedUnits() const;`` DoubleItem has the following new methods: * ``bool setValue(std::size_t element, const double& val, const std::string& units);`` In addition, `DoubleItem::setValueFromString` method can now handle strings that include a double followed by an option units. For example "20 m/s". Supporting Templates in Attribute XML Files ------------------------------------------- Templates are a new feature for SMTK's XML-based attribute file format (.sbt, .sbi extensions) version 7 and later. Templates are an extension to the existing ItemBlock concept. The main difference between an ItemBlock and a Template is that a Template's contents can be parameterized. When a Template is instantiated, these parameters can be assigned different values and will thereby change the information being copied. A Template's parameter can also be given a default value. **Note** All parameters that do not have a default value must be given values when the Template is instanced. Here is an example: .. code-block:: xml