Compile Time Changes

MhDeepstorageUnitLoadConstructionalPopulateFunction changes

The following method noOfUnitLoads() has been removed and replaced with MhUnitLoadConstructionalPopulateFunction.loadCount. We have also added a new field MhDeepstorageUnitLoadConstructionalPopulateFunction.noOfUnitLoadsInDepth. loadCount will populate loads along the x-axis, and noOfUnitLoadsInDepth will populate loads along the y-axis.

Old:
/**
 * Deep storage unit load constructional populate function.
 */
public class MhDeepstorageUnitLoadConstructionalPopulateFunction extends MhUnitLoadConstructionalPopulateFunction {
    /**
     * Number of unit loads.
     */
    extend public int noOfUnitLoads() {
        return configuration.getValue(cMhNoOfUnitLoadsPK).int;
    }
}


New:
/**
 * Unit load constructional populate.
 */
public class MhUnitLoadConstructionalPopulateFunction extends MhSystemEngineFunction {
    /**
     * Unit load depth count.
     * Load row count perpendicular to populate vector.
     */
    public Int loadCount;
}


New:
/**
 * Deep storage unit load constructional populate function.
 */
public class MhDeepstorageUnitLoadConstructionalPopulateFunction extends MhUnitLoadConstructionalPopulateFunction {
    /**
     * No of unit loads in depth.
     */
    public Int noOfUnitLoadsInDepth;
}

Any previous calls to noOfUnitLoads() should be replaced with loadCount.

/**
 * Deep storage unit load constructional populate function.
 */
public class MhDeepstorageUnitLoadConstructionalPopulateFunction extends MhUnitLoadConstructionalPopulateFunction {

Old:
    /**
     * BedWidhts
     */
    extend public double[] bedWidths(MhSystemEngineEnvironment env) {
        double segment = firstBedWidth();
        int unitLoadCount = noOfUnitLoads();

        double[] bedWidths();
        while (unitLoadCount > 0) {
            bedWidths << segment;
            unitLoadCount--;
        }

        return bedWidths;
    }
}


New:
    /**
     * BedWidhts
     */
    extend public double[] bedWidths(MhSystemEngineEnvironment env) {
        double segment = firstBedWidth();
        int unitLoadCount = loadCount.?v;

        double[] bedWidths();
        while (unitLoadCount > 0) {
            bedWidths << segment;
            unitLoadCount--;
        }

        return bedWidths;
    }
}

To maintain your existing workflow, you will need to pass the desired value in as an argument for this function. It is typically executed from a levelConstruction function as shown below.

/**
 * Level Populate engine. Used to populate additional levels from existing ones.
 */
public class MhLevelPopulateFunction extends MhSystemEngineFunction {
    /**
     * levelChildContruction
     */
    extend public void levelChildConstruction(MhEngineConstructionEntry entry) {
        if (?MhStorageConfiguration configuration = configuration) {
            ...
            int loadCount = configuration.unitLoadCountY();
            engine.exec("unitLoadConstruction", config=configuration,
                        ...
                        loadCount=loadCount,
                        directModify=true);
        }
    }
}

The new field noOfUnitLoadsInDepth is now used to control the number of unit loads populated depth-wise. The previous behavior was that it would populate loads until there was no more space to fit unit loads.

/**
 * Deep storage unit load constructional populate function.
 */
public class MhDeepstorageUnitLoadConstructionalPopulateFunction extends MhUnitLoadConstructionalPopulateFunction {

Old:
    /**
     * Add unit loads.
     */
    public void addUnitLoads() {
        ...
            while (populator.step(defaultEntry)) {
                ?MhEngineConstructionEntry entry = copy(defaultEntry);
                entry.move(populator.currentPos, update=update);
                childEntries << entry;
            }
        ...
    }

New:
    /**
     * Add unit loads.
     */
    public void addUnitLoads() {
        ...
            for (i in range(noOfUnitLoadsInDepth.?v)) {
                populator.step(defaultEntry);
                ?MhEngineConstructionEntry entry = copy(defaultEntry);
                entry.move(populator.currentPos, update=update);
                childEntries << entry;
            }
        ...
    }
}

You will now need to pass in a value for this field. Similarly to loadCount, it is also usually passed in from a levelConstruction function.

    /**
     * levelChildConstruction
     */
    public void levelChildConstruction(MhEngineConstructionEntry entry) {
        ...
	    engine.exec("unitLoadConstruction", config=configuration,
			...
			loadCount=loadCount,
			noOfUnitLoadsInDepth=noOfUnitLoadsInDepth,
			directModify=true);
        ...
    }

MhDeepstorageUnitLoadPopulateFunction changes

The following methods have been removed from this class:

/**
 * Unit load Populate engine.
 */
public class MhDeepstorageUnitLoadPopulateFunction extends MhUnitLoadPopulateFunction {
    /**
     * BedWidths
     */
    extend public double[] bedWidths(MhSystemEngineEnvironment env, MhEngineEntry edit) {
        ?double[] bedWidths = env.?getProp(edit.snapper, mhRollerBedWidthKey);
        if (bedWidths.empty) {
            init bedWidths();
            bedWidths << edit.w; //return super(..);
        } else {
            double[] newWidths();
            double div = edit.w/bedWidths.count;
            for (i in 1..bedWidths.count) {
                newWidths << div;
            }
            return newWidths;
        }

        return bedWidths;
    }


    /**
     * Easy populate loads.
     */
    public void easyPopulateLoads(MhEngineEntry edit, MhEngineEntry[] imported,
                                  MhEngineEntry[] children, MhPopulator populator,
                                  MhSystemEngineEnvironment env) {
        double[] bedWidths = bedWidths(env, edit);
        MhBedEngineEntryHolder[] beds = divideImportedInBeds(imported, reverse.?v);
        easyPopulateBeds(edit, imported, children, populator, env, bedWidths, beds);
    }


    /**
     * Easy populate beds.
     */
    extend public void easyPopulateBeds(MhEngineEntry edit, MhEngineEntry[] imported, MhEngineEntry[] children, MhPopulator populator, MhSystemEngineEnvironment env, double[] bedWidths, MhBedEngineEntryHolder[] beds) {
        point startPos = populator.currentPos;

        MhEngineSnapperEntry lastEntry;
        for (bedWidth in bedWidths, index=i) {
            if (!first) {
                populator.currentPos = nextPopulatorPos(edit, startPos, (bedWidths[i-1] + bedWidth)/2, env);
                if (populator as MhStepperPopulator) populator.currentStep = null;
                startPos = populator.currentPos;
            }

            range bedXRange(startPos.x-bedWidth/2, startPos.x+bedWidth/2);

            if (MhBedEngineEntryHolder bed = getValidBedEntryHolder(beds, bedXRange)) {
                beds.exclude(bed);
                for (MhEngineSnapperEntry entry in bed.list, reverse=reverse.?v) {
                    if (populator.step(entry)) {
                        MhEngineConstructionEntry newEntry = entry.toConstructionEntry();
                        if (entry as MhEngineConstructionEntry) newEntry.parent = entry.parent;

                        if (reverse.?v) {
                            point reversedPos =
                              (populator.currentPos.x, edit.d-populator.currentPos.y, populator.currentPos.z);
                            newEntry.move(reversedPos - entry.pos);
                        } else {
                            newEntry.move(populator.currentPos - entry.pos);
                        }

                        children.insert(children.indexOf(entry), newEntry);
                        children.exclude(entry);
                        lastEntry = newEntry;
                    } else {
                        children.exclude(entry);
                        lastEntry = null;
                    }
                }
            }

            if (lastEntry and populateMoreLoads) {
                while (populator.step(lastEntry)) {
                    MhEngineConstructionEntry e = lastEntry.?toConstructionEntry();
                    if (reverse.?v) {
                        point reversedPos =
                          (populator.currentPos.x, edit.d-populator.currentPos.y, populator.currentPos.z);
                        e.move(reversedPos - e.pos);
                    } else {
                        e.move(populator.currentPos - e.pos);
                    }

                    if (reverse.?v) {
                        children.insert(0, e);
                    } else {
                        children << e;
                    }
                }
            }
        }
    }


    /**
     * GetValidBedEntryHolder
     */
    extend public MhBedEngineEntryHolder getValidBedEntryHolder(MhBedEngineEntryHolder[] holders, range xRange) {
        if (holders.any) return holders.first;
        /* CUT THIS OUT  Mon Jan 16 08:19:08 2023 /danan
        for (holder in holders) {
            if (holder.insideBed(xRange)) return holder;
        }
        * CUT THIS OUT /danan */
        return null;
    }


    /**
     * Next populator pos.
     */
    extend public point nextPopulatorPos(MhEngineEntry edit, point startPos, double bedWidth, MhSystemEngineEnvironment env) {
        return startPos + (bedWidth, 0, 0);
    }
}

The above methods and override of easyPopulateLoads() were so that unit loads could be populated depth-wise for multiple "segments" that made up a bay. They are no longer required as we introduced MhUnitLoadArrangement which is able to handle populating unit loads in multiple directions.

If you have overridden this function and added more functionality in it, you could look into now overridding the MhUnitLoadArrangement used by this function and re-implementing your custom functionality there.

Alternatively you can return null for unitLoadArrangement() so that easyPopulateLoads() will be used again, and you can re-introduce the above removed methods into your custom function.

Runtime/Behavior Changes

MhDeepstorageUnitLoadConstructionalPopulateFunction changes

MhDeepstorageUnitLoadConstructionalPopulateFunction is now able to populate based on noOfUnitLoadsInDepth that is passed in as an argument. A new flag is added populateBasedOnNoUlDepth, so that you can decide whether to populate unit load based on the noOfUnitLoadsInDepth given or populate as many as possible.

public class MhDeepstorageUnitLoadConstructionalPopulateFunction extends MhUnitLoadConstructionalPopulateFunction {
- New: public Bool populateBasedOnNoUlDepth;
- New: public Int noOfUnitLoadsInDepth;