Skip to content

fix: entity sync #252

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Aug 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ jobs:
run: git submodule update --init --recursive

- run: curl -L https://install.dojoengine.org | bash
- run: /home/runner/.config/.dojo/bin/dojoup -v v1.0.0-alpha.3
- run: /home/runner/.config/.dojo/bin/dojoup -v v1.0.0-alpha.5
- run: |
cd examples/dojo-starter
/home/runner/.config/.dojo/bin/sozo build
Expand Down
14 changes: 1 addition & 13 deletions examples/react/react-app/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,7 @@ function App() {
account,
} = useDojo();

useQuerySync(toriiClient, contractComponents as any, [
{
Keys: {
keys: [BigInt(account?.account.address).toString()],
models: [
"dojo_starter-Position",
"dojo_starter-Moves",
"dojo_starter-DirectionsAvailable",
],
pattern_matching: "FixedLen",
},
},
]);
useQuerySync(toriiClient, contractComponents as any, []);

const [clipboardStatus, setClipboardStatus] = useState({
message: "",
Expand Down
50 changes: 25 additions & 25 deletions examples/react/react-app/src/dojo/createSystemCalls.ts
Original file line number Diff line number Diff line change
Expand Up @@ -82,28 +82,28 @@ export function createSystemCalls(
]) as Entity;

// Update the state before the transaction
const positionId = uuid();
Position.addOverride(positionId, {
entity: entityId,
value: {
player: BigInt(entityId),
vec: updatePositionWithDirection(
direction,
getComponentValue(Position, entityId) as any
).vec,
},
});
// const positionId = uuid();
// Position.addOverride(positionId, {
// entity: entityId,
// value: {
// player: BigInt(entityId),
// vec: updatePositionWithDirection(
// direction,
// getComponentValue(Position, entityId) as any
// ).vec,
// },
// });

// Update the state before the transaction
const movesId = uuid();
Moves.addOverride(movesId, {
entity: entityId,
value: {
player: BigInt(entityId),
remaining:
(getComponentValue(Moves, entityId)?.remaining || 0) - 1,
},
});
// // Update the state before the transaction
// const movesId = uuid();
// Moves.addOverride(movesId, {
// entity: entityId,
// value: {
// player: BigInt(entityId),
// remaining:
// (getComponentValue(Moves, entityId)?.remaining || 0) - 1,
// },
// });

try {
await client.actions.move({
Expand All @@ -127,11 +127,11 @@ export function createSystemCalls(
});
} catch (e) {
console.log(e);
Position.removeOverride(positionId);
Moves.removeOverride(movesId);
// Position.removeOverride(positionId);
// Moves.removeOverride(movesId);
} finally {
Position.removeOverride(positionId);
Moves.removeOverride(movesId);
// Position.removeOverride(positionId);
// Moves.removeOverride(movesId);
}
};

Expand Down
1 change: 0 additions & 1 deletion examples/react/react-app/src/dojo/generated/setup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,5 @@ export async function setup({ ...config }: DojoConfig) {
dojoProvider,
burnerManager,
toriiClient,
// sync,
};
}
4 changes: 2 additions & 2 deletions packages/react/src/useQuerySync.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { Component, Metadata, Schema } from "@dojoengine/recs";
import { useCallback, useEffect } from "react";
import {
Client,
ToriiClient,
EntityKeysClause,
Subscription,
} from "@dojoengine/torii-client";
Expand All @@ -28,7 +28,7 @@ import { getSyncEntities } from "@dojoengine/state";
* ]);
*/
export function useQuerySync<S extends Schema>(
toriiClient: Client,
toriiClient: ToriiClient,
components: Component<S, Metadata, undefined>[],
entityKeyClause: EntityKeysClause[]
) {
Expand Down
16 changes: 8 additions & 8 deletions packages/state/src/recs/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ import {
} from "@dojoengine/recs";
import {
Clause,
Client,
ToriiClient,
EntityKeysClause,
PatternMatching,
} from "@dojoengine/torii-client";
Expand Down Expand Up @@ -40,7 +40,7 @@ import { convertValues } from "../utils";
* the batch size of each request.
*/
export const getSyncEntities = async <S extends Schema>(
client: Client,
client: ToriiClient,
components: Component<S, Metadata, undefined>[],
entityKeyClause: EntityKeysClause[],
limit: number = 100
Expand All @@ -62,7 +62,7 @@ export const getSyncEntities = async <S extends Schema>(
* This function performs paginated queries to fetch all entities and their components.
*/
export const getEntities = async <S extends Schema>(
client: Client,
client: ToriiClient,
components: Component<S, Metadata, undefined>[],
limit: number = 100
) => {
Expand Down Expand Up @@ -109,7 +109,7 @@ export const getEntities = async <S extends Schema>(
* to control the batch size of each request.
*/
export const getEntitiesQuery = async <S extends Schema>(
client: Client,
client: ToriiClient,
components: Component<S, Metadata, undefined>[],
entityKeyClause: EntityKeysClause,
patternMatching: PatternMatching = "FixedLen",
Expand Down Expand Up @@ -137,7 +137,7 @@ export const getEntitiesQuery = async <S extends Schema>(
const fetchedEntities = await client.getEntities({
limit,
offset: cursor,
clause,
clause: clause || undefined,
});

setEntities(fetchedEntities, components);
Expand All @@ -163,14 +163,14 @@ export const getEntitiesQuery = async <S extends Schema>(
* sync.cancel(); // cancel the subscription
*/
export const syncEntities = async <S extends Schema>(
client: Client,
client: ToriiClient,
components: Component<S, Metadata, undefined>[],
entityKeyClause: EntityKeysClause[]
) => {
return await client.onEntityUpdated(
entityKeyClause,
(fetchedEntities: any) => {
setEntities(fetchedEntities, components);
(fetchedEntities: any, data: any) => {
setEntities({ [fetchedEntities]: data }, components);
}
);
};
Expand Down
143 changes: 74 additions & 69 deletions packages/state/src/utils/index.ts
Original file line number Diff line number Diff line change
@@ -1,83 +1,88 @@
import { Type as RecsType, Schema, ComponentValue } from "@dojoengine/recs";
import { Type as RecsType, Schema } from "@dojoengine/recs";

export function convertValues(schema: Schema, values: any): ComponentValue {
return Object.keys(schema).reduce<any>(
(acc: ComponentValue, key: string) => {
if (!acc) {
acc = {}; // Ensure acc is initialized
}
const schemaType = schema[key];
const value = values[key];
export function convertValues(schema: Schema, values: any) {
return Object.keys(schema).reduce<any>((acc, key) => {
if (!acc) {
acc = {};
}
const schemaType = schema[key];
const value = values[key];

if (value === null || value === undefined) {
acc[key] = value;
return acc;
}
if (value === null || value === undefined) {
acc[key] = value;
return acc;
}

if (value.type === "enum") {
acc[key] = value.value.option;
return acc;
}
if (value.type === "enum") {
acc[key] = value.value.option;
return acc;
}

switch (schemaType) {
case RecsType.StringArray:
if (
value.type === "array" &&
value.value[0].type === "enum"
) {
acc[key] = value.value.map(
(item: any) => item.value.option
);
} else {
acc[key] = value.value.map((a: any) => {
try {
return BigInt(a.value);
} catch (error) {
console.warn(
`Failed to convert ${a.value} to BigInt. Using string value instead.`
);
return a.value;
}
});
}
break;
switch (schemaType) {
case RecsType.StringArray:
if (value.type === "array" && value.value[0].type === "enum") {
acc[key] = value.value.map(
(item: any) => item.value.option
);
} else {
acc[key] = value.value.map((a: any) => {
try {
return BigInt(a.value);
} catch (error) {
console.warn(
`Failed to convert ${a.value} to BigInt. Using string value instead.`
);
return a.value;
}
});
}
break;

case RecsType.String:
acc[key] = value.value;
break;
case RecsType.String:
acc[key] = value.value;
break;

case RecsType.BigInt:
try {
acc[key] = BigInt(value.value);
} catch (error) {
console.warn(
`Failed to convert ${value.value} to BigInt. Using string value instead.`
);
case RecsType.BigInt:
try {
acc[key] = BigInt(value.value);
} catch (error) {
console.warn(
`Failed to convert ${value.value} to BigInt. Using string value instead.`
);

acc[key] = BigInt(`0x${value.value}`);
}
break;
acc[key] = BigInt(`0x${value.value}`);
}
break;

case RecsType.Boolean:
acc[key] = value.value;
break;
case RecsType.Boolean:
acc[key] = value.value;
break;

case RecsType.Number:
acc[key] = Number(value.value);
break;
case RecsType.Number:
acc[key] = Number(value.value);
break;

default:
if (
typeof schemaType === "object" &&
typeof value === "object"
) {
default:
if (typeof schemaType === "object" && value.type === "struct") {
if (value.value instanceof Map) {
const structValues = Object.fromEntries(value.value);
acc[key] = convertValues(schemaType, structValues);
} else {
acc[key] = convertValues(schemaType, value.value);
}
break;
}
} else if (
Array.isArray(schemaType) &&
value.type === "array"
) {
acc[key] = value.value.map((item: any) =>
convertValues(schemaType[0], item)
);
} else {
acc[key] = value.value;
}
break;
}

return acc;
},
{}
);
return acc;
}, {});
}
Loading