diff --git a/examples/react-phaser-example/src/dojo/createNetworkLayer.ts b/examples/react-phaser-example/src/dojo/createNetworkLayer.ts index fbb828b0..5d6a3f34 100644 --- a/examples/react-phaser-example/src/dojo/createNetworkLayer.ts +++ b/examples/react-phaser-example/src/dojo/createNetworkLayer.ts @@ -2,6 +2,7 @@ import { world } from "./world"; import { setup } from "./setup"; import { Account, RpcProvider } from "starknet"; import { BurnerManager } from "@dojoengine/create-burner"; +import { SyncManager } from "@dojoengine/react"; export type NetworkLayer = Awaited>; @@ -27,6 +28,20 @@ export const createNetworkLayer = async () => { // TODO: Currently if you change wallets in the UI, phaser will not update. burnerManager.init(); + if (burnerManager.account) { + // sync manager to active address + new SyncManager(network.torii_client, [ + { + model: network.contractComponents.Position, + keys: [burnerManager.account?.address], + }, + { + model: network.contractComponents.Moves as any, + keys: [burnerManager.account?.address], + }, + ]); + } + return { world, components, diff --git a/examples/react-phaser-example/src/hooks/useDojo.tsx b/examples/react-phaser-example/src/hooks/useDojo.tsx index 36e8382e..9528d619 100644 --- a/examples/react-phaser-example/src/hooks/useDojo.tsx +++ b/examples/react-phaser-example/src/hooks/useDojo.tsx @@ -18,8 +18,6 @@ export const useDojo = () => { burnerManager: networkLayer.burnerManager, }); - console.log("account", account); - return { networkLayer: networkLayer as NetworkLayer, phaserLayer: phaserLayer as PhaserLayer, @@ -33,5 +31,7 @@ export const useDojo = () => { isDeploying, }, systemCalls: networkLayer.systemCalls, + toriiClient: networkLayer.network.torii_client, + contractComponents: networkLayer.network.contractComponents, }; }; diff --git a/packages/react/src/index.ts b/packages/react/src/index.ts index 2d430d5b..fcd91e45 100644 --- a/packages/react/src/index.ts +++ b/packages/react/src/index.ts @@ -3,3 +3,4 @@ export * from "./useSync"; export * from "./useComponentValue"; export * from "./usePromise"; export * from "./usePromise"; +export * from "./syncManager"; diff --git a/packages/react/src/syncManager/index.ts b/packages/react/src/syncManager/index.ts new file mode 100644 index 00000000..c019356a --- /dev/null +++ b/packages/react/src/syncManager/index.ts @@ -0,0 +1 @@ +export { SyncManager } from "./syncManager"; diff --git a/packages/react/src/syncManager/syncManager.ts b/packages/react/src/syncManager/syncManager.ts new file mode 100644 index 00000000..4940a03b --- /dev/null +++ b/packages/react/src/syncManager/syncManager.ts @@ -0,0 +1,85 @@ +import { Client } from "@dojoengine/torii-client"; +import { + Component, + Schema, + Metadata, + Entity, + setComponent, +} from "@dojoengine/recs"; +import { getEntityIdFromKeys } from "@dojoengine/utils"; +import { convertValues } from "../utils"; + +// type KeyType = any; // Replace 'any' with your actual key type +type ModelEntry = { + model: Component; + keys: any[]; +}; + +export class SyncManager { + private client: Client; + private modelEntries: ModelEntry[]; + private isMounted: boolean; + + constructor(client: Client, modelEntries: ModelEntry[]) { + this.client = client; + this.modelEntries = modelEntries; + this.isMounted = true; + + console.log("init"); + this.init(); + } + + private async fetchAndSetModelValue( + modelEntry: ModelEntry + ): Promise { + const { model, keys } = modelEntry; + const componentName = model.metadata?.name as string; + const keysToStrings = keys.map((key) => key.toString()); + const entityIndex: Entity = + keys.length === 1 ? keys[0].toString() : getEntityIdFromKeys(keys); + + try { + if (this.isMounted) { + const modelValue = await this.client.getModelValue( + componentName, + keysToStrings + ); + const convertedValue = convertValues(model.schema, modelValue); + setComponent(model, entityIndex, convertedValue as any); + } + } catch (error) { + console.error("Failed to fetch or set model value:", error); + } + } + + private init(): void { + this.modelEntries.forEach((modelEntry) => { + this.fetchAndSetModelValue(modelEntry); + this.client.addEntitiesToSync([ + { + model: modelEntry.model.metadata?.name as string, + keys: modelEntry.keys.map((k) => k.toString()), + }, + ]); + }); + } + + public cleanup(): void { + this.isMounted = false; + this.modelEntries.forEach((modelEntry) => { + this.client + .removeEntitiesToSync([ + { + model: modelEntry.model.metadata?.name as string, + keys: modelEntry.keys.map((k) => k.toString()), + }, + ]) + .catch((error) => { + console.error( + "Failed to remove entities on cleanup", + error + ); + }); + }); + } +}