Skip to content

feat(neighborhoods): introduce coarse-grained generic moves - #2610

Open
triceo wants to merge 11 commits into
TimefoldAI:mainfrom
triceo:pillars
Open

feat(neighborhoods): introduce coarse-grained generic moves#2610
triceo wants to merge 11 commits into
TimefoldAI:mainfrom
triceo:pillars

Conversation

@triceo

@triceo triceo commented Aug 23, 2026

Copy link
Copy Markdown
Collaborator

Introduces:

  • Basic var pillar, subpillar and mass moves.
  • List var sublist and mass moves.
  • 2opt move and tail swap.

Documentation will only be written after we agree on all the things that are in here. The chances of having to redo the docs because of review changes are too big.

My recommendation for review: start with the moves and move providers. Understand them. Before we discuss the implementation, we need to be in agreement that we want these moves, and not some others. (The implementation is dictated by the requirements of the moves - therefore if we decide to change the moves, we will change the implementation.)

@triceo
triceo deployed to internal August 23, 2026 07:39 — with GitHub Actions Active
@triceo
triceo deployed to internal August 23, 2026 07:39 — with GitHub Actions Active
@triceo
triceo deployed to internal August 23, 2026 07:39 — with GitHub Actions Active
@triceo
triceo deployed to internal August 23, 2026 12:11 — with GitHub Actions Active
@triceo
triceo deployed to internal August 23, 2026 12:11 — with GitHub Actions Active
@triceo
triceo deployed to internal August 23, 2026 12:11 — with GitHub Actions Active
@triceo triceo changed the title feat(neighborhoods): Implement pillars+subpillars for basic vars feat(neighborhoods): introduce coarse-grained generic moves Aug 23, 2026
@triceo triceo self-assigned this Aug 23, 2026
@triceo triceo linked an issue Aug 23, 2026 that may be closed by this pull request
@triceo
triceo requested a lite review from Copilot August 23, 2026 12:22

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Introduces coarse-grained generic neighborhood moves for basic and list variables, with supporting preview APIs, migration recipes, tests, and documentation.

Changes:

  • Adds pillar, subpillar, mass, list, and sublist moves and providers.
  • Adds sampling, dataset, range, and neighborhood-stream infrastructure.
  • Adds preview migration support and upgrade documentation.

Four moderate findings remain unresolved.

Reviewed changes

Copilot reviewed 155 out of 155 changed files in this pull request and generated 4 comments.

Show a summary per file
File Reviewed change
tools/migration/src/test/java/ai/timefold/solver/migration/preview/NeighborhoodsMigrationRecipeTest.java Migration recipe tests
tools/migration/src/main/java/module-info.java Migration module exports
tools/migration/src/main/java/ai/timefold/solver/migration/v2/ToLatestV2Recipe.java V2 migration composition
tools/migration/src/main/java/ai/timefold/solver/migration/v1/ToLatestV1Recipe.java V1 migration composition
tools/migration/src/main/java/ai/timefold/solver/migration/ToLatestRecipe.java Aggregate migration composition
tools/migration/src/main/java/ai/timefold/solver/migration/preview/PreviewToLatestRecipe.java Preview migration aggregation
tools/migration/src/main/java/ai/timefold/solver/migration/preview/package-info.java Preview migration documentation
tools/migration/src/main/java/ai/timefold/solver/migration/preview/NeighborhoodsMigrationRecipe.java Neighborhood API migration
docs/src/modules/ROOT/pages/upgrading-timefold-solver/upgrade-to-latest.adoc Latest upgrade guide
docs/src/modules/ROOT/pages/upgrading-timefold-solver/upgrade-from-v1.adoc V1 upgrade documentation
docs/src/modules/ROOT/pages/upgrading-timefold-solver/backwards-compatibility.adoc Compatibility documentation
docs/src/modules/ROOT/pages/upgrading-timefold-solver/.upgrading-timefold-solver.adoc Upgrade page inclusion
docs/src/modules/ROOT/nav.adoc Documentation navigation
core/src/test/java/ai/timefold/solver/core/testutil/NeighborhoodTestUtils.java Neighborhood test utilities
core/src/test/java/ai/timefold/solver/core/testdomain/valuerange/entityproviding/multivar/TestdataAllowsUnassignedMultiVarEntityProvidingSolution.java Multivariable test data
core/src/test/java/ai/timefold/solver/core/preview/api/neighborhood/stream/dataset/sample/SampleTest.java Sample API tests
core/src/test/java/ai/timefold/solver/core/preview/api/neighborhood/stream/dataset/DatasetTest.java Dataset API tests
core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/SwapMoveTest.java Swap move tests
core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/SubPillarUnassignMoveProviderTest.java Subpillar unassignment tests
core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/SampleValueRangesBiasIT.java Value-range bias tests
core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/MassUnassignMoveProviderTest.java Mass unassignment tests
core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/MassAssignMoveProviderTest.java Mass assignment tests
core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/ListSwapMoveProviderTest.java List swap provider tests
core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/ListChangeMoveProviderTest.java List change provider tests
core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/ChangeMoveTest.java Change move tests
core/src/test/java/ai/timefold/solver/core/preview/api/move/builtin/ChangeMoveProviderTest.java Change provider tests
core/src/test/java/ai/timefold/solver/core/impl/util/TriangularNumbersTest.java Triangular-number tests
core/src/test/java/ai/timefold/solver/core/impl/util/TriangleElementFactoryTest.java Triangle factory tests
core/src/test/java/ai/timefold/solver/core/impl/neighborhood/bias/SamplingIteratorBiasIT.java Sampling bias tests
core/src/test/java/ai/timefold/solver/core/impl/neighborhood/bias/PairFairnessBiasIT.java Pair fairness tests
core/src/test/java/ai/timefold/solver/core/impl/neighborhood/bias/DatasetBucketBiasIT.java Dataset bucket bias tests
core/src/test/java/ai/timefold/solver/core/impl/neighborhood/bias/BiasReport.java Bias reporting
core/src/test/java/ai/timefold/solver/core/impl/neighborhood/bias/AbstractBiasIT.java Shared bias test support
core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/list/RandomSubListSwapMoveSelectorTest.java Random sublist swap selector tests
core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/move/generic/list/RandomSubListChangeMoveSelectorTest.java Random sublist change selector tests
core/src/test/java/ai/timefold/solver/core/impl/heuristic/selector/list/RandomSubListSelectorTest.java Random sublist selector tests
core/src/main/java/module-info.java Core module exports
core/src/main/java/ai/timefold/solver/core/preview/api/neighborhood/UniMoveConstructor.java Unary move construction
core/src/main/java/ai/timefold/solver/core/preview/api/neighborhood/stream/picking/UniPickingStream.java Unary picking stream
core/src/main/java/ai/timefold/solver/core/preview/api/neighborhood/stream/picking/PickingStream.java Picking stream API
core/src/main/java/ai/timefold/solver/core/preview/api/neighborhood/stream/picking/BiPickingStream.java Binary picking stream
core/src/main/java/ai/timefold/solver/core/preview/api/neighborhood/stream/MoveStreamFactory.java Move stream factory
core/src/main/java/ai/timefold/solver/core/preview/api/neighborhood/stream/enumerating/UniEnumeratingStream.java Unary enumeration stream
core/src/main/java/ai/timefold/solver/core/preview/api/neighborhood/stream/enumerating/BiEnumeratingStream.java Binary enumeration stream
core/src/main/java/ai/timefold/solver/core/preview/api/neighborhood/stream/dataset/UniDatasetInstance.java Unary dataset instances
core/src/main/java/ai/timefold/solver/core/preview/api/neighborhood/stream/dataset/sample/SubListSampler.java Sublist sampling
core/src/main/java/ai/timefold/solver/core/preview/api/neighborhood/stream/dataset/sample/Sampler.java Sampler API
core/src/main/java/ai/timefold/solver/core/preview/api/neighborhood/stream/dataset/sample/Sample.java Sample API
core/src/main/java/ai/timefold/solver/core/preview/api/neighborhood/stream/dataset/sample/Range.java Range API
core/src/main/java/ai/timefold/solver/core/preview/api/neighborhood/stream/dataset/sample/package-info.java Sample API documentation
core/src/main/java/ai/timefold/solver/core/preview/api/neighborhood/stream/dataset/sample/DefaultSample.java Sample implementation
core/src/main/java/ai/timefold/solver/core/preview/api/neighborhood/stream/dataset/sample/DefaultRange.java Range implementation
core/src/main/java/ai/timefold/solver/core/preview/api/neighborhood/stream/dataset/BiDatasetInstance.java Binary dataset instances
core/src/main/java/ai/timefold/solver/core/preview/api/move/MutableSolutionView.java Mutable solution access
core/src/main/java/ai/timefold/solver/core/preview/api/move/Move.java Move contract
core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/UnassignMoveProvider.java Unassignment provider
core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/SwapMoveProvider.java Swap move provider
core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/SwapMove.java Swap move implementation
core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/SubListUnassignMove.java Sublist unassignment
core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/SubListChangeMove.java Sublist change move
core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/PillarUnassignMoveProvider.java Pillar unassignment provider
core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/package-info.java Built-in move documentation
core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/MassUnassignMoveProvider.java Mass unassignment provider
core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/MassListUnassignMoveProvider.java Mass list unassignment provider
core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/MassListDestinationMoveIterator.java Mass list destination iteration
core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/MassListChangeMoveProvider.java Mass list change provider
core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/MassListChangeMove.java Mass list change move
core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/MassListAssignMoveProvider.java Mass list assignment provider
core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/MassChangeMoveProvider.java Mass change provider
core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/MassChangeMove.java Mass change move
core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/MassAssignMoveProvider.java Mass assignment provider
core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/ListUnassignMoveProvider.java List unassignment provider
core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/ListUnassignMove.java List unassignment move
core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/ListSwapMoveProvider.java List swap provider
core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/ListAssignMoveProvider.java List assignment provider
core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/ListAssignMove.java List assignment move
core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/ChangeMoveProvider.java Change move provider
core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/ChangeMove.java Change move implementation
core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/AssignMoveProvider.java Assignment provider
core/src/main/java/ai/timefold/solver/core/preview/api/domain/metamodel/VariableMetaModel.java Variable metadata
core/src/main/java/ai/timefold/solver/core/preview/api/domain/metamodel/ShadowVariableMetaModel.java Shadow variable metadata
core/src/main/java/ai/timefold/solver/core/preview/api/domain/metamodel/ShadowEntityMetaModel.java Shadow entity metadata
core/src/main/java/ai/timefold/solver/core/preview/api/domain/metamodel/PlanningEntityMetaModel.java Planning entity metadata
core/src/main/java/ai/timefold/solver/core/preview/api/domain/metamodel/GenuineVariableMetaModel.java Genuine variable metadata
core/src/main/java/ai/timefold/solver/core/preview/api/domain/metamodel/ElementPosition.java Element position metadata
core/src/main/java/ai/timefold/solver/core/impl/util/TriangularNumbers.java Triangular-number utilities
core/src/main/java/ai/timefold/solver/core/impl/util/TriangleElementFactory.java Triangle element factory
core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/sampling/InnerUniSamplingStream.java Unary sampling implementation
core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/sampling/InnerSamplingStream.java Sampling implementation
core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/picking/InnerUniPickingStream.java Unary picking implementation
core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/picking/InnerPickingStream.java Picking implementation
core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/picking/DefaultUniPickingStream.java Default unary picking
core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/picking/DefaultBiPickingStream.java Default binary picking
core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/enumerating/common/AbstractLeftDatasetInstance.java Dataset join support
core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/DefaultMoveStreamFactory.java Move stream construction
core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/dataset/sample/SampleAssembler.java Sample assembly
core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/dataset/JustInTimeBiDatasetInstance.java Just-in-time binary datasets
core/src/main/java/ai/timefold/solver/core/impl/neighborhood/stream/dataset/DefaultUniDatasetInstance.java Default unary datasets
core/src/main/java/ai/timefold/solver/core/impl/neighborhood/DefaultNeighborhoodTestContext.java Neighborhood test context
core/src/main/java/ai/timefold/solver/core/impl/neighborhood/DefaultNeighborhoodProvider.java Neighborhood provider
core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/list/TriangleElementFactory.java List selection factory
core/src/main/java/ai/timefold/solver/core/impl/heuristic/selector/list/RandomSubListSelector.java Random sublist selection
core/src/main/java/ai/timefold/solver/core/impl/domain/valuerange/NullAllowingValueRange.java Null-allowing value ranges
core/src/main/java/ai/timefold/solver/core/impl/domain/solution/descriptor/SolutionDescriptor.java Solution metadata
core/src/main/java/ai/timefold/solver/core/impl/domain/solution/descriptor/InnerPlanningEntityMetaModel.java Planning entity metadata construction
core/src/main/java/ai/timefold/solver/core/impl/domain/solution/descriptor/DefaultShadowVariableMetaModel.java Shadow variable metadata construction
core/src/main/java/ai/timefold/solver/core/impl/domain/solution/descriptor/DefaultShadowEntityMetaModel.java Shadow entity metadata construction
core/src/main/java/ai/timefold/solver/core/impl/domain/solution/descriptor/DefaultPlanningVariableMetaModel.java Planning variable metadata construction
core/src/main/java/ai/timefold/solver/core/impl/domain/solution/descriptor/DefaultPlanningListVariableMetaModel.java Planning list metadata construction
core/src/main/java/ai/timefold/solver/core/impl/domain/solution/descriptor/DefaultGenuineEntityMetaModel.java Genuine entity metadata construction
core/src/main/java/ai/timefold/solver/core/impl/bavet/common/index/RetiringRandomIterator.java Random iterator support
core/src/main/java/ai/timefold/solver/core/impl/bavet/common/index/MappingRetiringRandomIterator.java Mapped random iterator support
CONSTITUTION.md Repository guidance
Suppressed comments (7)

core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/MassListChangeMove.java:79

  • Sample explicitly allows null members, but this move dereferences every member here (and again in getPlanningValues()), so a valid Sample can make the public list mass-change move fail with an unhelpful NullPointerException; either reject null members when constructing the move or document a non-null-member precondition.
    core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/MoveProviderUtil.java:232
  • The provider groups all entities, including those whose variable is null, but containsInEvery is called on ranges with nullable wrappers removed, so legal swaps involving an unassigned value are always rejected; handle null as legal when variableMetaModel.allowsUnassigned() is true.
    core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/PillarChangeMoveProvider.java:42
  • The new Javadoc contains the truncated word w instead of would, making the explanation grammatically incorrect.
    core/src/main/java/ai/timefold/solver/core/preview/api/move/builtin/SampleValueRanges.java:126
  • ValueRange.getSize() is a long, but admittedCount is an int, so pickExactly overflows after 2^31−1 admitted values and eventually passes a non-positive bound to nextInt; use a long counter and nextLong.
    core/src/main/java/ai/timefold/solver/core/preview/api/neighborhood/stream/dataset/sample/DefaultSample.java:48
  • Sample documents value-based equality for any two samples, but this implementation only compares DefaultSample, so a valid custom Sample with the same members is considered unequal; compare against the Sample interface and preserve the same member-based hash contract.
    core/src/main/java/ai/timefold/solver/core/preview/api/neighborhood/stream/dataset/sample/Sample.java:45
  • first() is annotated nullable and DefaultSample returns null when null is the first member, but this Javadoc promises a never-null result, which gives callers an unsafe contract; document that the result may be null.
    docs/src/modules/ROOT/pages/upgrading-timefold-solver/upgrade-to-latest.adoc:9
  • This unconditional promise contradicts the preview API migration documented later on this page and the preview compatibility policy: users on preview APIs can be broken by exactly the sampling-to-picking rename; qualify the guarantee to stable APIs or explicitly exclude preview APIs.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@zepfred zepfred left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The review of the remaining code is complete and looks great to me. I have some minor comments and questions, but overall, the implementation of the building blocks for the move providers is solid, and the test coverage is adequate.

Please update the list of built-in moves, and we are good to go once the sonar and conflict are resolved.

@triceo

triceo commented Sep 4, 2026

Copy link
Copy Markdown
Collaborator Author

Comments resolved, docs pushed.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The migration “ToLatest” composition currently runs RemoveUnusedImports redundantly in multiple recipe layers, and the new module export of an internal move package broadens the module API surface in a way that should be explicitly justified or handled via test-only JPMS exports.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 189/231 changed files
  • Comments generated: 3
  • Review effort level: Lite

Comment thread core/src/main/java/module-info.java Outdated

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

The change set is large and touches core neighborhood/move-stream internals and preview APIs in ways that warrant careful human validation of behavioral and performance impacts.

Review details
  • Files reviewed: 189/231 changed files
  • Comments generated: 2
  • Review effort level: Lite

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

PendingListChangeTracker.clear() does not de-escalate from the overflow map, undermining the intended hot-path allocation/performance optimization after the first multi-entity list move.

Review details

Suppressed comments (1)

Previously missed (1) — in code that hasn't changed since the last review.

core/src/main/java/ai/timefold/solver/core/impl/move/PendingListChangeTracker.java:69

  • PendingListChangeTracker.clear() keeps overflowMap allocated after an escalation, which makes all subsequent single-entity brackets pay the map overhead and defeats the class’s “single-slot common case” optimization.
  • Files reviewed: 189/231 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

It introduces and refactors core Neighborhoods/move-generation APIs across many modules, requiring deeper correctness and performance validation than can be confidently automated here.

Review details

Suppressed comments (1)

core/src/main/java/ai/timefold/solver/core/api/domain/common/Lookup.java:38

  • Public API method Lookup#lookUpNonNullWorkingObject is missing the required @param/@return/@throws Javadoc tags (CONSTITUTION.md:16).
  • Files reviewed: 190/232 changed files
  • Comments generated: 3
  • Review effort level: Lite

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

It introduces broad new Neighborhoods APIs and move-generation behavior while refactoring multiple core subsystems (streams, iterators, metamodel ordering, and migrations), requiring careful human validation of design and correctness.

Review details

Suppressed comments (1)

core/src/main/java/ai/timefold/solver/core/api/domain/common/Lookup.java:38

  • The new public API method's Javadoc is missing the required @param/@return tags mandated by CONSTITUTION.md for public methods.
  • Files reviewed: 190/232 changed files
  • Comments generated: 1
  • Review effort level: Lite

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

A newly introduced migration recipe class violates the repo’s “classes must be final unless extensible” convention and should be made final before approval.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Review details
  • Files reviewed: 190/232 changed files
  • Comments generated: 1
  • Review effort level: Lite

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

It touches a broad set of core Neighborhoods APIs/implementations and introduces new move-generation primitives, requiring careful human validation beyond the few localized issues identified.

Review details

Suppressed comments (2)

Previously missed (1) — in code that hasn't changed since the last review.

core/src/main/java/ai/timefold/solver/core/impl/domain/valuerange/NullAllowingValueRange.java:66

  • This iterator can return null (see next() implementation), so its return type should be annotated to avoid leaking nulls through a non-null generic signature.

This issue also appears on line 96 of the same file.

core/src/main/java/ai/timefold/solver/core/impl/domain/valuerange/NullAllowingValueRange.java:96

  • This iterator can return null (via get(0)), so its return type should be annotated to avoid leaking nulls through a non-null generic signature.
  • Files reviewed: 190/232 changed files
  • Comments generated: 0 new
  • Review effort level: Lite

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔵 Needs a closer look

It introduces and rewires substantial core move-generation and preview API surface area changes, which are difficult to fully validate for correctness and performance without broader, human-led review.

Review details
  • Files reviewed: 195/239 changed files
  • Comments generated: 1
  • Review effort level: Lite

Comment on lines +63 to +69
void clear() {
singleEntity = null;
singleAction = null;
if (overflowMap != null) {
overflowMap.clear();
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Feat: Neighborhoods - Pillar move support

5 participants