Init
This commit is contained in:
284
content/reference/buildertools/snapshots.en.md
Normal file
284
content/reference/buildertools/snapshots.en.md
Normal file
@@ -0,0 +1,284 @@
|
||||
---
|
||||
title: Snapshots
|
||||
type: docs
|
||||
weight: 5
|
||||
---
|
||||
|
||||
The snapshot system provides undo/redo functionality for builder tools by capturing and restoring state.
|
||||
|
||||
**Package:** `com.hypixel.hytale.builtin.buildertools.snapshot`
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
Snapshots
|
||||
├── Base
|
||||
│ └── SelectionSnapshot - Snapshot interface
|
||||
├── Block Snapshots
|
||||
│ └── BlockSelectionSnapshot - Block selection state
|
||||
├── Clipboard Snapshots
|
||||
│ ├── ClipboardSnapshot - Clipboard interface
|
||||
│ ├── ClipboardContentsSnapshot - Clipboard contents
|
||||
│ └── ClipboardBoundsSnapshot - Selection bounds
|
||||
└── Entity Snapshots
|
||||
├── EntitySnapshot - Entity interface
|
||||
├── EntityAddSnapshot - Track entity addition
|
||||
├── EntityRemoveSnapshot - Track entity removal
|
||||
└── EntityTransformSnapshot - Track transform changes
|
||||
```
|
||||
|
||||
## SelectionSnapshot Interface
|
||||
|
||||
Base interface for all snapshots:
|
||||
|
||||
```java
|
||||
public interface SelectionSnapshot<T extends SelectionSnapshot<?>> {
|
||||
// Restore to previous state
|
||||
// Returns inverse snapshot for redo
|
||||
T restore(Ref<EntityStore> ref, Player player, World world,
|
||||
ComponentAccessor<EntityStore> accessor);
|
||||
}
|
||||
```
|
||||
|
||||
### How Undo/Redo Works
|
||||
|
||||
The snapshot pattern creates inverse operations:
|
||||
1. Snapshot captures current state before operation
|
||||
2. Operation modifies the state
|
||||
3. Calling `restore()` reverts changes
|
||||
4. `restore()` returns new snapshot for redo
|
||||
|
||||
## Block Selection Snapshots
|
||||
|
||||
### BlockSelectionSnapshot
|
||||
|
||||
Captures block selection state:
|
||||
|
||||
```java
|
||||
public class BlockSelectionSnapshot implements SelectionSnapshot<BlockSelectionSnapshot> {
|
||||
private final BlockSelection selection;
|
||||
|
||||
public BlockSelection getBlockSelection();
|
||||
|
||||
// Create copy of selection
|
||||
public static BlockSelectionSnapshot copyOf(BlockSelection selection);
|
||||
}
|
||||
```
|
||||
|
||||
### Usage
|
||||
|
||||
```java
|
||||
// Before modifying selection
|
||||
BlockSelectionSnapshot snapshot = BlockSelectionSnapshot.copyOf(selection);
|
||||
|
||||
// Perform modifications...
|
||||
|
||||
// To undo - restore returns redo snapshot
|
||||
BlockSelectionSnapshot redoSnapshot = snapshot.restore(ref, player, world, accessor);
|
||||
```
|
||||
|
||||
## Clipboard Snapshots
|
||||
|
||||
### ClipboardSnapshot Interface
|
||||
|
||||
Extended interface for clipboard operations:
|
||||
|
||||
```java
|
||||
public interface ClipboardSnapshot<T extends SelectionSnapshot<?>>
|
||||
extends SelectionSnapshot<T> {
|
||||
|
||||
T restoreClipboard(Ref<EntityStore> ref, Player player, World world,
|
||||
BuilderToolsPlugin.BuilderState state,
|
||||
ComponentAccessor<EntityStore> accessor);
|
||||
}
|
||||
```
|
||||
|
||||
### ClipboardContentsSnapshot
|
||||
|
||||
Captures clipboard contents:
|
||||
|
||||
```java
|
||||
public class ClipboardContentsSnapshot implements ClipboardSnapshot<ClipboardContentsSnapshot> {
|
||||
private final BlockSelection selection;
|
||||
|
||||
// Create copy of clipboard contents
|
||||
public static ClipboardContentsSnapshot copyOf(BlockSelection selection);
|
||||
}
|
||||
```
|
||||
|
||||
### ClipboardBoundsSnapshot
|
||||
|
||||
Captures selection bounds only:
|
||||
|
||||
```java
|
||||
public class ClipboardBoundsSnapshot implements ClipboardSnapshot<ClipboardBoundsSnapshot> {
|
||||
public static final ClipboardBoundsSnapshot EMPTY;
|
||||
|
||||
private final Vector3i min;
|
||||
private final Vector3i max;
|
||||
|
||||
public ClipboardBoundsSnapshot(BlockSelection selection);
|
||||
public ClipboardBoundsSnapshot(Vector3i min, Vector3i max);
|
||||
|
||||
public Vector3i getMin();
|
||||
public Vector3i getMax();
|
||||
}
|
||||
```
|
||||
|
||||
## Entity Snapshots
|
||||
|
||||
### EntitySnapshot Interface
|
||||
|
||||
Interface for entity-related snapshots:
|
||||
|
||||
```java
|
||||
public interface EntitySnapshot<T extends SelectionSnapshot<?>>
|
||||
extends SelectionSnapshot<T> {
|
||||
|
||||
T restoreEntity(Player player, World world,
|
||||
ComponentAccessor<EntityStore> accessor);
|
||||
}
|
||||
```
|
||||
|
||||
Entity snapshots handle thread safety automatically, ensuring restoration runs on the world's tick thread.
|
||||
|
||||
### EntityAddSnapshot
|
||||
|
||||
Tracks entity creation (undo removes entity):
|
||||
|
||||
```java
|
||||
public class EntityAddSnapshot implements EntitySnapshot<EntityRemoveSnapshot> {
|
||||
private final Ref<EntityStore> entityRef;
|
||||
|
||||
public Ref<EntityStore> getEntityRef();
|
||||
|
||||
// Restore removes the entity
|
||||
// Returns EntityRemoveSnapshot for redo (re-add)
|
||||
}
|
||||
```
|
||||
|
||||
### EntityRemoveSnapshot
|
||||
|
||||
Tracks entity removal (undo adds entity back):
|
||||
|
||||
```java
|
||||
public class EntityRemoveSnapshot implements EntitySnapshot<EntityAddSnapshot> {
|
||||
private final Holder<EntityStore> holder;
|
||||
|
||||
public Holder<EntityStore> getHolder();
|
||||
|
||||
// Restore adds entity back
|
||||
// Returns EntityAddSnapshot for redo (remove again)
|
||||
}
|
||||
```
|
||||
|
||||
The `Holder<EntityStore>` stores a complete copy of the entity and its components.
|
||||
|
||||
### EntityTransformSnapshot
|
||||
|
||||
Tracks entity position and rotation:
|
||||
|
||||
```java
|
||||
public class EntityTransformSnapshot implements EntitySnapshot<EntityTransformSnapshot> {
|
||||
private final Ref<EntityStore> ref;
|
||||
private final Transform transform; // Position and rotation
|
||||
private final Vector3f headRotation; // Head direction
|
||||
|
||||
// Stores current transform state
|
||||
public EntityTransformSnapshot(Ref<EntityStore> ref,
|
||||
ComponentAccessor<EntityStore> accessor);
|
||||
|
||||
// Restore returns snapshot of current state before restoration
|
||||
}
|
||||
```
|
||||
|
||||
## Snapshot Pairs
|
||||
|
||||
Snapshots come in complementary pairs:
|
||||
|
||||
| Add Operation | Undo (Remove) | Redo (Add) |
|
||||
|---------------|---------------|------------|
|
||||
| `EntityAddSnapshot` | Removes entity | `EntityRemoveSnapshot` |
|
||||
| `EntityRemoveSnapshot` | Adds entity back | `EntityAddSnapshot` |
|
||||
|
||||
| Modification | Undo | Redo |
|
||||
|--------------|------|------|
|
||||
| `EntityTransformSnapshot` | Restores previous transform | Returns new snapshot |
|
||||
| `BlockSelectionSnapshot` | Restores previous blocks | Returns new snapshot |
|
||||
| `ClipboardContentsSnapshot` | Restores previous contents | Returns new snapshot |
|
||||
| `ClipboardBoundsSnapshot` | Restores previous bounds | Returns new snapshot |
|
||||
|
||||
## Edit History Integration
|
||||
|
||||
Snapshots integrate with the edit history system:
|
||||
|
||||
```java
|
||||
// History stores snapshots for each operation
|
||||
// /undo command restores from history
|
||||
// /redo command uses inverse snapshots
|
||||
|
||||
// Commands related to history:
|
||||
// /undo [count]
|
||||
// /redo [count]
|
||||
// /clearedithistory
|
||||
// /settoolhistorysize <size>
|
||||
```
|
||||
|
||||
## Thread Safety
|
||||
|
||||
Entity snapshots automatically handle world thread requirements:
|
||||
|
||||
```java
|
||||
// EntitySnapshot.restore() implementation
|
||||
default T restore(...) {
|
||||
if (!world.isInThread()) {
|
||||
// Run on world tick thread
|
||||
return CompletableFuture.supplyAsync(
|
||||
() -> this.restoreEntity(player, world, store),
|
||||
world
|
||||
).join();
|
||||
}
|
||||
return this.restoreEntity(player, world, store);
|
||||
}
|
||||
```
|
||||
|
||||
## API Usage
|
||||
|
||||
### Working with Block Snapshots
|
||||
|
||||
```java
|
||||
// Before operation
|
||||
BlockSelectionSnapshot before = BlockSelectionSnapshot.copyOf(selection);
|
||||
|
||||
// Perform operation that modifies blocks
|
||||
// ...
|
||||
|
||||
// Store snapshot in history for undo
|
||||
```
|
||||
|
||||
### Working with Entity Snapshots
|
||||
|
||||
```java
|
||||
// Before adding entity
|
||||
Ref<EntityStore> newEntity = world.spawnEntity(...);
|
||||
EntityAddSnapshot snapshot = new EntityAddSnapshot(newEntity);
|
||||
|
||||
// To undo (remove the entity)
|
||||
EntityRemoveSnapshot inverse = snapshot.restore(ref, player, world, accessor);
|
||||
|
||||
// To redo (add entity back)
|
||||
EntityAddSnapshot restored = inverse.restore(ref, player, world, accessor);
|
||||
```
|
||||
|
||||
### Working with Transform Snapshots
|
||||
|
||||
```java
|
||||
// Before moving entity
|
||||
EntityTransformSnapshot before = new EntityTransformSnapshot(entityRef, accessor);
|
||||
|
||||
// Move entity
|
||||
transformComponent.setPosition(newPosition);
|
||||
|
||||
// To undo (restore original position)
|
||||
EntityTransformSnapshot after = before.restore(player, world, accessor);
|
||||
```
|
||||
Reference in New Issue
Block a user