Analytics

Analytics

From 15.0 Minor onwards, there are some changes to existing statistics events captured for Extension Analytics.

  1. Allowed for all DsPData instances from a multi-data Data object (DsMultiPData) as entities into any data snapper events for Extension Analytics.
  2. Capture of insert events now happen via UndoChain instead of InsertAnimation. More snapper insert events will now be captured automatically.

For more information on this topic, please refer to the implementation article on Analytics available here: https://support.configura.com/hc/en-us/articles/22335281700503-Developer-s-Overview-of-Analytics

cm.abstract.materialHandling

New event for animation export

MhSystemAnimationExportFunction now calls the new event symbol sSnapperInsertedAnim on exported snappers instead of sSnapperInserted. This engine function is primarily used with inserting row snappers.

    /**
     * Exec.
     */
    public Object exec() {
        ...
            for (MhSnapper s in exported) {
                s.validateBehaviors(sSnapperInsertedAnim);
                if (s.isRow or s.isAisle) {
                    rows << s;
                }
            }
        ...
    }

Change in favorite animation returned

Previously MhSnapperAnimationBehavior.favoriteAnimation() would return InsertAnimationG2 by default. Now it will return the result of insertAnimation() instead unless useInsertAnimationG2ForFavorites() returns true. By default InsertAnimationG2 will be returned only when the selection contains the behavior's snapper as well as other snappers that are not children of the snapper.

Old:
    /**
     * Favorite insert animation.
     */
    public Animation favoriteAnimation(Snapper z, StartInsertAnimationEnv env) {
        if (Snapper root = eldestAncestorIn(z, env.?selection.snappers)) {
            if (z != root) {
                if (SnapperAnimationBehaviour rootAnimBehaviour = root.animationBehaviour) {
                    return rootAnimBehaviour.favoriteAnimation(root, env);
                }
            }
        }
        return InsertAnimationG2(env);
    }


New:
    /**
     * Favorite insert animation.
     */
    public Animation favoriteAnimation(Snapper z, StartInsertAnimationEnv env) {
        if (Snapper root = eldestAncestorIn(z, env.?selection.snappers)) {
            if (z != root) {
                if (SnapperAnimationBehaviour rootAnimBehaviour = root.animationBehaviour) {
                    return rootAnimBehaviour.favoriteAnimation(root, env);
                }
            }
        }
        if (SpaceSelection sel = env.?selection) {
            if (useInsertAnimationG2ForFavorites(z.MhSnapper, sel)) return InsertAnimationG2(env);
        }
        return insertAnimation(..);
    }


    /**
     * Use InsertAnimationG2 for favorites instead of insertAnimation(z, env).
     */
    extend public bool useInsertAnimationG2ForFavorites(MhSnapper snapper, SpaceSelection selection) {
        return !sameFamilySelection(..);
    }


    /**
     * Return true if selection only contains this and decendant.
     */
    extend public bool sameFamilySelection(MhSnapper snapper, SpaceSelection selection) {
        for (s in selection) {
            if (s == snapper) continue;
            if (!s.anyChildOf(snapper)) return false;
        }

        return true;
    }

New animation so that copy and paste bays/frames will generate row parents

A new animation MhRowChildFavoriteAnimationG2 has been created that can generate row parent snappers when copy-pasting bays/frames. This animation is by default used by bays and frames in the abstract (MhRowChildSnapperAnimationBehavior). The existing MhBaySnapperAnimationBehavior is modified to extend from this new parent, and we've added a new MhFrameSnapperAnimationBehavior for frames in the abstract.

When copy-pasting a bay/frame, pasting it will generate a row and then trigger the events sUserPastedAnim and sSnapperInserted. These are to ensure the row is properly updated (e.g. generating default frames for a stand-alone bay, generate empty bays in between the copied snappers).

Snapping also works with the new animation and the pasted snapper will be absorbed into the snapped parent, see MhRowChildFavoriteAnimationG2.tryAdoptChildrenIntoSnapAlt().

MhRowFillVoidEntriesFunction more ways to get a void bay sample

The method getVoidBaysSample() in MhRowFillVoidEntriesFunction previously will only return results if there were any removed bays. If there are no removed bays, it will now return the first group of imported bays with the same x-position, or even generate a bay construction entry if there are no imported bays.

public class MhRowFillVoidEntriesFunction extends MhSystemEngineFunction {
    /**
     * Get a sample of bays to be used as reference when filling up void bays.
     */
    extend public MhEngineBoxEntry[] getVoidBaysSample() {
        MhEngineEntryBlock[] blocks = systemEnvironment.?getImportedBlocks(snapper);
        MhEngineEntry[] entries = blocks.first.entries;
        entries = mhXSortedEntries(entries, unmodify=true);

        MhEngineBoxEntry[] res(4);

        // Gathers all the bays that have the same x-position
        appendVoidBaysSample(entries, res, acceptFirst=false);

        // Did not find any removed bay, fallback to first bays at same x-position.
        if (!res.any) appendVoidBaysSample(entries, res, acceptFirst=true);

        // No bay in entries, spawn a single default bay.
        if (!res.any) res <<? defaultBayConstructionEntry(entries);

        return res.any ? res : null;
    }
}