Analytics

Overview

In 15.0 Minor, we updated the event capture systems that will drive Analytics features that allows ease of adoption for all developers and manufacturers, as well as adding support for new functionality.

In this version:

  1. We updated how Snapper insert events are captured for Extension Analytics
  2. Allowed for all DsPData instances from a multi-data Data object (DsMultiPData) as entities into any data snapper events for Extension Analytics.
  3. Added support for generic custom events and custom events with numeric metrics for Extension Analytics
  4. Added support for Product Analytics

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.win

Added interfaces for logging custom events.

Added: public void logCustomEvent(str action, G3StatsEntity[] entities, symbol pkg=#:package : caller eval, bool lookupExtension=true)
Added: public void logCustomEvent(str action, str statsEntityKey, int quantity=1, symbol pkg=#:package : caller eval, bool lookupExtension=true)
Added: public void logNumericEvent(str action, str numericEntityKey, double value, numericType numType, symbol pkg=#:package : caller eval, bool lookupExtension=true)

cm.core

Added interfaces to log a quantity of identical snapper insert events.
Added interfaces to omit logging duplicate snapper and toolbox select events.
Addition of G3UserEventEnv class to collect and log snapper insert events.

//eventLogFunctions.cm
Added: public void logSnapperInsertEvent(Snapper snapper, int quantity)
Added: public void logSnapperEvent(str action, Snapper snapper, int quantity)
Added: public void logSnapperSelectEvent(Snapper snapper, bool checkDuplicate)
Added: public void logUserSelectTbCardEvent(ToolboxCard toolboxCard, bool checkDuplicate)

//G3UserEventEnv.cm
Added: public class G3UserEventEnv

cm.core.undo

Added interfaces for logging snapper insert events.

//undoOp.cm
Added: public void collectG3UserEvent(G3UserEventEnv env)

//undoStep.cm
Added: public void logG3UserEvents()

cm.abstract.materialHandling

More support for disabling snapping

MhSnapBehavior and MhRowAnimationInfo now has interfaces to allow disabling snapping. Return true for these interfaces if you want your snap behaviors or row insert animation to not snap when userSnapDisable() is true.

public class MhSnapBehavior extends MhBehavior {

    /**
     * Don't append snap alternatives when userSnapDisable.
     */
    extend public bool checkUserSnapDisabled() {
        return false;
    }


    /**
     * Append snap alternatives.
     */
    extend public void appendSnapAlternatives(Snapper snapper, SnapAlternative[] alternatives, Animation a, AnimationMouseInfo mi, SnapperFilter filter=null) {
        if (checkUserSnapDisabled and userSnapDisable()) return;
        ...
    }
}


public class MhRowAnimationInfo extends CoreObject {

    /**
     * Don't append row snap alternatives when userSnapDisable.
     */
    extend public bool checkUserSnapDisabled() {
        return true;
    }
}


public class MhRowInsertAnimation extends MhRowInsertToolAnimationG2 {

    /**
     * MoveToClosestRow
     */
    extend public void moveToClosestRow(AnimationMouseInfo mi, SpaceVolumeSearchResult searchResult) {
        ...
        if (info.checkUserSnapDisabled() and userSnapDisable()) return;
        ...
    }
}

Debug Tool - Engine Tracker Enhancement

There is a new feature added to the engine tracker. The engine tracker is located under the 'Debug Engine' section.

Engine Tracker

Right clicking on a function from the list of functions ran will now show a third option, 'Instantiated - [path to where the function was created]':

Engine Tracker Right Click

Clicking on it will show the place where the function was created in Emacs. This can be used to find the behavior that added the function into the engine run.

MhBehavior supports copy events

MhBehavior can now respond to the following snapper copy/paste events:

  • beforeUserCopied
  • userCopied
  • userPasted
public class MhBehavior extends CoreObject {
    /**
     * Before user copied.
     */
    extend public void beforeUserCopied(MhSnapper snapper, SpaceSelection selection) { }


    /**
     * User copied.
     */
    extend public void userCopied(MhSnapper snapper, SpaceSelection selection) { }


    /**
     * This snapper was pasted.
     */
    extend public void userPasted(MhSnapper snapper, SnapperSelection selection) { }
}


public class MhSnapper extends Snapper {
    /**
     * Before snapper was user copied.
     */
    public void beforeUserCopied(SpaceSelection selection) {
        super(..);
        forAllBehaviors(b in this) b.beforeUserCopied(this, selection);
    }


    /**
     * This snapper was user copied.
     */
    public void userCopied(SpaceSelection selection) {
        super(..);
        forAllBehaviors(b in this) b.userCopied(this, selection);
    }


    /**
     * This snapper was pasted.
     */
    public void userPasted(SnapperSelection selection) {
        super(..);
        ...
        forAllBehaviors(b in this) b.userPasted(this, selection);
    }
}

New behavior to copy frames together with bays

By default in single select mode, selecting a bay and then copying will only copy the bay snapper. We've added a behavior that will automatically copy the adjacent frames as well whenever a bay is copied. This is not added by default in the abstract so add it to your bay if this behavior is desired.

/**
 * Bay select frame user copy behavior.
 * Include frame if not in selection for copy.
 */
public class MhBaySelectFrameUserCopyBehavior extends MhBehavior {
    /**
     * Selected frames.
     */
    public Snapper{} selectedFrames();


    /**
     * Before snapper was user copied.
     */
    public void beforeUserCopied(MhSnapper snapper, SpaceSelection selection) {
        super(..);

        for (frame in snapper.nextNeighbors({sFrame})) {
            if (frame !in selection) {
                selection << frame;
                selectedFrames << frame;
                frame.beforeUserCopied(selection);
            }
        }
        for (frame in snapper.prevNeighbors({sFrame})) {
            if (frame !in selection) {
                selection << frame;
                selectedFrames << frame;
                frame.beforeUserCopied(selection);
            }
        }
    }


    /**
     * This snapper was user copied.
     */
    public void userCopied(MhSnapper snapper, SpaceSelection selection) {
        super(..);
        if (selectedFrames.any) {
            if (Space space = selection.?main.space) {
                for (frame in selectedFrames) {
                    selection.remove(frame);
                }

                space.select(selection);
            }
            selectedFrames.clear();
        }
    }
}