Created
June 24, 2025 17:28
-
-
Save agrancini-sc/2c9097ef28a52ee83bb7a8e2c2a73fec to your computer and use it in GitHub Desktop.
Sync Entity and Storage
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import {SessionController} from "SpectaclesSyncKit.lspkg/Core/SessionController" | |
import {StorageProperty} from "SpectaclesSyncKit.lspkg/Core/StorageProperty" | |
import {SyncEntity} from "SpectaclesSyncKit.lspkg/Core/SyncEntity" | |
@component | |
export class GridControllerTS extends BaseScriptComponent { | |
@input() | |
showLogs: boolean = true | |
// Grid properties | |
private height: number = 3 | |
private gridSyncEntity: SyncEntity | |
private gridReady: boolean = false | |
// Initialize the array of data (all zeroes on start) | |
private gridArray: vec2[] = [] | |
// Create a storage property for the gridSyncEntity | |
private gridData: StorageProperty<vec2[]> | |
onAwake() { | |
if (this.showLogs) { | |
print("GridControllerTS: onAwake started") | |
} | |
// Initialize the grid array properly | |
this.gridArray = [] | |
for (let i = 0; i < this.height * this.height; i++) { | |
this.gridArray.push(vec2.zero()) | |
} | |
if (this.showLogs) { | |
print("GridControllerTS: Grid array initialized with length: " + this.gridArray.length) | |
print("GridControllerTS: First element: " + this.gridArray[0]) | |
print("GridControllerTS: Elements are independent: " + (this.gridArray[0] !== this.gridArray[1])) | |
} | |
// Create the storage property after array initialization | |
this.gridData = StorageProperty.manualVec2Array("serverGrid", this.gridArray) | |
if (this.showLogs) { | |
print("GridControllerTS: Storage property created") | |
} | |
// Create new sync entity for this script (exactly like ControllerTS) | |
this.gridSyncEntity = new SyncEntity(this) | |
if (this.showLogs) { | |
print("GridControllerTS: Sync entity created") | |
} | |
// Add storage properties for grid data | |
this.gridSyncEntity.addStorageProperty(this.gridData) | |
if (this.showLogs) { | |
print("GridControllerTS: Storage property added to sync entity") | |
} | |
// Limit the grid to only send updates out 10 times per second | |
this.gridData.sendsPerSecondLimit = 10 | |
// Add change listener to debug storage property updates | |
this.gridData.onAnyChange.add((newVal: vec2[], oldVal: vec2[]) => { | |
if (this.showLogs) { | |
print("GridControllerTS: Grid data changed!") | |
print("GridControllerTS: New value length: " + (newVal ? newVal.length : "undefined")) | |
print("GridControllerTS: Old value length: " + (oldVal ? oldVal.length : "undefined")) | |
} | |
}) | |
if (this.showLogs) { | |
print("GridControllerTS: Change listener added") | |
} | |
// Set up the sync entity notify on ready callback (exactly like ControllerTS) | |
// Note: Only update the sync entity once it is ready | |
this.gridSyncEntity.notifyOnReady(() => this.onReady()) | |
if (this.showLogs) { | |
print("GridControllerTS: Notify on ready callback set") | |
} | |
// Fallback: if sync entity doesn't become ready within 5 seconds, force ready state | |
let fallbackEvent = this.createEvent("DelayedCallbackEvent") | |
fallbackEvent.bind((eventData) => { | |
if (!this.gridReady) { | |
if (this.showLogs) { | |
print("GridControllerTS: FALLBACK - Sync entity never became ready, forcing ready state") | |
} | |
this.onReady() | |
} | |
}) | |
fallbackEvent.reset(5) | |
if (this.showLogs) { | |
print("GridControllerTS: Fallback timer set for 5 seconds") | |
} | |
} | |
// Called when grid sync entity is ready (like ControllerTS.onReady) | |
onReady() { | |
if (this.showLogs) { | |
print("GridControllerTS: onReady called") | |
} | |
// Debug the storage property state | |
print("GridControllerTS: Grid array length: " + this.gridArray.length) | |
print("GridControllerTS: Grid data current value: " + this.gridData.currentValue) | |
print("GridControllerTS: Grid data current value length: " + (this.gridData.currentValue ? this.gridData.currentValue.length : "undefined")) | |
print("GridControllerTS: Grid data currentOrPendingValue: " + this.gridData.currentOrPendingValue) | |
print("GridControllerTS: Grid data currentOrPendingValue length: " + (this.gridData.currentOrPendingValue ? this.gridData.currentOrPendingValue.length : "undefined")) | |
// Make sure all cells are independent (this prints false, which is the desired outcome) | |
print("GridControllerTS: Elements are independent: " + (this.gridArray[0] === this.gridArray[1])) // Should be false if they're independent | |
// Set the pending value here | |
this.gridData.setPendingValue(this.gridArray) | |
// Set ready flag so grid can be used | |
this.gridReady = true | |
if (this.showLogs) { | |
print("GridControllerTS: Grid is ready!") | |
} | |
} | |
// SEND METHOD - Update a grid position | |
test() { | |
if (this.showLogs) { | |
print("GridControllerTS: TEST - Starting send test") | |
} | |
// Hardcoded test values (fixed to be within 3x3 grid bounds) | |
const testX = 1 | |
const testY = 1 | |
const newValue = new vec2(10, 20) | |
if (this.showLogs) { | |
print("GridControllerTS: TEST - Updating position (" + testX + ", " + testY + ") to " + newValue) | |
} | |
if (!this.gridReady) { | |
if (this.showLogs) { | |
print("GridControllerTS: TEST - Grid not ready, cannot send") | |
} | |
return | |
} | |
// Use currentOrPendingValue as recommended in documentation | |
const currentData = this.gridData.currentOrPendingValue | |
if (!currentData) { | |
if (this.showLogs) { | |
print("GridControllerTS: TEST - Grid data is null, cannot send") | |
} | |
return | |
} | |
let idx = this.height * testY + testX | |
if (idx < 0 || idx >= currentData.length) { | |
if (this.showLogs) { | |
print("GridControllerTS: TEST - Invalid index: " + idx) | |
} | |
return | |
} | |
// Create a copy of the current array | |
let newArray = [...currentData] | |
newArray[idx] = newValue | |
// Set the new value | |
this.gridData.setPendingValue(newArray) | |
if (this.showLogs) { | |
print("GridControllerTS: TEST - Successfully sent update") | |
} | |
} | |
// TEST RECEIVE METHOD - Test accessing grid data | |
testReceive() { | |
if (this.showLogs) { | |
print("GridControllerTS: TEST RECEIVE - Starting receive test") | |
} | |
// Hardcoded test values (fixed to be within 3x3 grid bounds) | |
const testX = 1 | |
const testY = 1 | |
if (this.showLogs) { | |
print("GridControllerTS: TEST RECEIVE - Testing position (" + testX + ", " + testY + ")") | |
} | |
if (!this.gridReady) { | |
if (this.showLogs) { | |
print("GridControllerTS: TEST RECEIVE - Grid not ready, cannot test") | |
} | |
return | |
} | |
// Calculate the array index based on x and y | |
let idx = this.height * testY + testX | |
// Use currentOrPendingValue as recommended in documentation | |
const currentData = this.gridData.currentOrPendingValue | |
if (this.showLogs) { | |
print("GridControllerTS: TEST RECEIVE - Calculated index: " + idx) | |
print("GridControllerTS: TEST RECEIVE - Grid data currentOrPendingValue: " + currentData) | |
print("GridControllerTS: TEST RECEIVE - Grid data currentOrPendingValue length: " + (currentData ? currentData.length : "undefined")) | |
} | |
if (!currentData) { | |
print("GridControllerTS: TEST RECEIVE - Grid data is null, cannot test") | |
return | |
} | |
// Check if index is OOB | |
if (idx < 0 || idx >= currentData.length) { | |
print("GridControllerTS: TEST RECEIVE - Invalid grid index: " + idx + " for x=" + testX + ", y=" + testY) | |
return | |
} | |
// This is the problem line. Index is valid but grid data always is undefined? | |
let cellVec = currentData[idx] | |
if (this.showLogs) { | |
print("GridControllerTS: TEST RECEIVE - Retrieved cellVec: " + cellVec) | |
} | |
if (cellVec === undefined) { | |
print("GridControllerTS: TEST RECEIVE - ERROR - cellVec is undefined at index " + idx) | |
} else { | |
print("GridControllerTS: TEST RECEIVE - SUCCESS - cellVec retrieved: " + cellVec) | |
} | |
} | |
// Convenience method to test the original receivePlayerData function | |
receivePlayerData(ID: number, xpos: number, ypos: number, zpos: number) { | |
if (this.showLogs) { | |
print("GridControllerTS: receivePlayerData called with ID=" + ID + ", x=" + xpos + ", y=" + ypos + ", z=" + zpos) | |
} | |
// Return early if grid is not ready | |
if (!this.gridReady) { | |
if (this.showLogs) { | |
print("GridControllerTS: Grid not ready, returning early") | |
} | |
return | |
} | |
// Calculate the array index based on x and y | |
let idx = this.height * ypos + xpos | |
// Use currentOrPendingValue as recommended in documentation | |
const currentData = this.gridData.currentOrPendingValue | |
if (this.showLogs) { | |
print("GridControllerTS: Calculated index: " + idx) | |
print("GridControllerTS: Grid data currentOrPendingValue: " + currentData) | |
print("GridControllerTS: Grid data currentOrPendingValue length: " + (currentData ? currentData.length : "undefined")) | |
} | |
if (!currentData) { | |
print("GridControllerTS: Grid data is null, cannot receive") | |
return | |
} | |
// Check if index is OOB | |
if (idx < 0 || idx >= currentData.length) { | |
print("GridControllerTS: Invalid grid index: " + idx + " for x=" + xpos + ", y=" + ypos) | |
return | |
} | |
// This is the problem line. Index is valid but grid data always is undefined? | |
let cellVec = currentData[idx] | |
if (this.showLogs) { | |
print("GridControllerTS: Retrieved cellVec: " + cellVec) | |
} | |
if (cellVec === undefined) { | |
print("GridControllerTS: ERROR - cellVec is undefined at index " + idx) | |
} else { | |
print("GridControllerTS: SUCCESS - cellVec retrieved: " + cellVec) | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment