cm.abstract.materialHandling

Multi Assortment

MhMultiAssortment is an assortment that hold few assortments. It is used when a rack/configuration is built using more than one assortment.

Added: public class MhMultiAssortment extends MhAssortment {

MhStorageAssortment changes

Now assortment has a classification field, that will act as a product line of the assortment.

Added: private LayerSet _classification;
Added: public LayerSet classification() {
Added: public LayerSet classification=(LayerSet c) {

MhAssortment changes

MhAssortment has a default setter and getter for classification for customization to extend from.

Added: extend public LayerSet classification() {
Added: extend public LayerSet classification=(LayerSet c) {

It also has a getter for spawnerSelector.

Added: extend public MhSystemSpawnerSelector spawnerSelector(LayerSet classi=null) {

New Debug Tool - Engine Visualiser Plug In Function Feature

The Engine Visualiser debug tool is improved to include a new Plug In Function feature. The new feature allows the option to clone the existing main space as an alternate space and allows developers to replace one single engine run function with a set of engine run functions during the engine run in the alternate space triggered by user actions from the main space. The current supported user action includes the setting of quick property values. The new feature is as shown in the screenshot below:

Engine Visualiser Plug In Feature

Toggling the "Enable alternate space for plug in function" button and clicking the "Clear All" button will reset the alternate space to the current main space.

Clicking the "Plug in function selector" will allow developers to select the old and new engine run functions to be used for the plug in feature. The function choices are populated according to the snappers present in the main space. Further instructions and details are displayed in the dialog shown below:

Engine Visualiser Plug In Function Selector

Added MhDebugAssortment to allow registration of custom debug plug in functions for the engine visualiser plug in function feature.

Added: public class MhDebugAssortment extends MhStorageAssortment {
Added: public MhDebugAssortment mhDebugAssortment() {

Added MhDebugPlugInFunctionSpace to differentiate between a regular space and an alternate plug in function space for the engine visualiser plug in function feature.

Added: public class MhDebugPlugInFunctionSpace extends Space {

Added MhDebugPlugInFunctionSpaceManager and its singleton instantiation to handle the alternate plug in function space including the instantiation and cloning of the space.

Added: public class MhDebugPlugInFunctionSpaceManager {
Added: public MhDebugPlugInFunctionSpaceManager mhDebugPlugInFunctionSpaceManager() {

Added MhDebugCorePropertiesManager and its singleton instantiation which overwrite void createQuickProperties(CorePropObj obj) which is required for the piping of the quick property changes from the main space to the alternate plug in function space.

Added: public class MhDebugCorePropertiesManager extends CorePropertiesManager {

Added function which checks if EngineVisualiserDialog is active.

Added: public bool dbg_engineVisualisationDebugSpaceEnabled() {

Added function to open EngineVisualiserFunctionSelectorDialog.

Added: public void showEngineVisualiserFunctionSelectorWindow() {

Added function to return the active alternate plug in function space view in the engine visualiser dialog.

Added: public REDRenderView3D dbg_engineVisualisationDebugSpaceView() {

Added function to handle replacement and execution of plug in functions.

public Object dbg_engineVisualisationExecFunction(MhEngineFunctionLibrary this, CxFunction fun, str->Object args) {

New afterPutEngineRunFunction method for engine behaviors

Engine behaviors now have a new method afterPutEngineRunFunction(MhEngine engine, MhEngineFunctionRun[] toRun, Object owner, symbol k, MhSnapperChangedEnv env=null). The purpose of this method is to allow you to react to specific engine functions being appended.

/**
 * Engine behavior.
 */
public class MhEngineBehavior extends MhBehavior : inherit constructors {

    /**
     * After put engine run function.
     */
    extend public void afterPutEngineRunFunction(MhEngine engine, MhEngineFunctionRun[] toRun, Object owner, symbol k, MhSnapperChangedEnv env=null) {
    }


    /**
     * Validate.
     */
    public void validate(Object owner, symbol k, MhSnapperChangedEnv env=null) {
        super(..);
        ...
                for (f in toRun) mhPutEngineRunFunction(engine, f);
                afterPutEngineRunFunction(engine, toRun, owner, k, env);
        ...
    }
}

cm.abstract.materialHandling.storage

New ways to select configuration

Previously if a drawing had multiple configurations in it, the user would need to open the Pre Configurator dialog to switch to a different configuration before inserting their racking system. We've added 2 different ways for users to change their currently selected configuration.

  1. New row insert animation Configuration property

A new Configuration property has been added to MhRowAnimationInfo and is visible to the row insert animations MhRowInsertAnimation, MhRowDownAisleInsertAnimation, and MhRowCrossAisleInsertAnimation.

Row Insert Animation Configuration Property

It is only enabled for MhRowInsertAnimation as modifying this property will:

  1. Change the current configuration
  2. Re-spawn a new snapper (based on the new configuration)
  3. Animation a new insert animation

For MhRowDownAisleInsertAnimation and MhRowCrossAisleInsertAnimation it will remain visible but disabled.

  1. New toolbox configuration selector popup

We've added a popup that can be added to your toolbox for easier access to changing configurations.

Configuration Selector Popup

Simply add the following code to your toolbox (sample code from Essential Pallet Racking):

    f(Control con)->void preconfigSelectCB = f(Control con)->void { mhCreateConfigSelectPopup(con, #:package, con.?parent.toScreen(con.pos + (0, con.h + 8))); };
    SectionButton btn(icon=icon("facelift2023/options"),
                      tooltip=$viewConfig,
                      callback=preconfigSelectCB);

    LibraryLimb global(root, pkg, "Settings", label=$SettingsLabel, buttons=[btn]);

Engine function to add additional bay classifications

Added a new engine function MhAddBayClassificationsFunction to add additional classifications into the bays of a row. To use this, register the function in your row engine behavior as shown below:

public class MhShuttleRowAnimEngineBehavior extends MhRowAnimationEngineBehavior {
    /**
     * Collect engine function to run.
     */
    public void fetchEngineFunctionsRun(MhEngineFunctionRun[] functions, MhSnapper snapper, symbol event="", Object env=null) {
        if (event == sSnapperInserted) {
            functions << MhEngineFunctionRun("addBayClassifications");
        }
    }


    /**
     * Gather function args.
     */
    public str->Object engineFunctionArgs(MhSnapper snapper, MhEngineFunctionRun func, symbol event="", MhPreprocessArgsEnv preprocessArgs=null, Object env=null) {
        if (func.name == "addBayClassifications") {
            MhStorageConfiguration config = mhStorageConfiguration(snapper);
            int->symbol additionalBayClassifications = config.?additionalBayClassifications(info);
            return props { snapper=snapper, additionalBayClassifications=additionalBayClassifications };
        }
        return super(..);
    }
}

cm.abstract.unitLoad

Unit Load Editor Redesign

The Unit Load Editor dialog has gotten a redesign!

Unit Load Editor

As of 15.5 Minor, this new design is opt-in and the dialog will still default to the old design. The dialog has a temporary bool useV2 field that when set to true, will build with the new design.

If you're using the dialog out of the box without extending it, you can update your library code to pass in useV2=true as shown below:

Old:
private void settingsContainer(LibraryLimb root) {
    LibraryLimb global(root, pkg, "Settings", label=$SettingsLabel);
    f()->void showCB = f()->void { showUnitLoadDialog(); };
    UIHint ulIH = imageHint("unitLoadEditor");
    VoidCallbackLimb(global, pkg, "showULDialog", hint=ulIH, callback=showCB);
}


New:
private void settingsContainer(LibraryLimb root) {
    LibraryLimb global(root, pkg, "Settings", label=$SettingsLabel);
    f()->void showCB = f()->void { showUnitLoadDialog(useV2=true); };
    UIHint ulIH = imageHint("unitLoadEditor");
    VoidCallbackLimb(global, pkg, "showULDialog", hint=ulIH, callback=showCB);
}

If you have extended and customized the dialog, make sure to set useV2=true when constructing the dialog and also refer to the UnitLoadDialog class to locate all the new methods that need to be overridden. If you would prefer to stick with the old design, we recommend copying over all the old code that is needed into your custom class as we intend on removing them in 16.0 Major. More info on this in UnitLoadDialog Redesign Changes under the Runtime/Behavior Changes section.