Skip to content

Commit 7815318

Browse files
committed
Merge branch 'last-Almost-stable' into drag-drop-new-objects
2 parents d1220f9 + 47049e3 commit 7815318

File tree

15 files changed

+758
-92
lines changed

15 files changed

+758
-92
lines changed

Extensions/LinkedObjects/linkedobjects.ts

Lines changed: 101 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ namespace gdjs {
4141
objA: gdjs.RuntimeObject
4242
): Map<string, gdjs.RuntimeObject[]> {
4343
if (!this._links.has(objA.id)) {
44-
this._links.set(objA.id, new IterableLinkedObjects());
44+
this._links.set(objA.id, new IterableLinkedObjects(objA));
4545
}
4646
return this._links.get(objA.id)!.linkedObjectMap;
4747
}
@@ -55,7 +55,7 @@ namespace gdjs {
5555
objA: gdjs.RuntimeObject
5656
): Iterable<gdjs.RuntimeObject> {
5757
if (!this._links.has(objA.id)) {
58-
this._links.set(objA.id, new IterableLinkedObjects());
58+
this._links.set(objA.id, new IterableLinkedObjects(objA));
5959
}
6060
return this._links.get(objA.id)!;
6161
}
@@ -159,15 +159,83 @@ namespace gdjs {
159159
}
160160
}
161161
}
162+
163+
clearAllLinks() {
164+
this._links.clear();
165+
}
166+
167+
/**
168+
* Serialize all links between objects that have a networkId,
169+
* so they can be persisted and restored later.
170+
* Each link is stored once as a pair of networkIds.
171+
*/
172+
getNetworkSyncData(): Array<[string, string]> {
173+
const linkedObjects: Array<[string, string]> = [];
174+
const serializedLinks = new Set<string>();
175+
176+
for (const iterableLinkedObjects of this._links.values()) {
177+
const objectA = iterableLinkedObjects.ownerObject;
178+
if (!objectA || !objectA.networkId) {
179+
continue;
180+
}
181+
182+
for (const objectB of iterableLinkedObjects) {
183+
if (!objectB.networkId) continue;
184+
const pairKey =
185+
objectA.networkId < objectB.networkId
186+
? `${objectA.networkId}|${objectB.networkId}`
187+
: `${objectB.networkId}|${objectA.networkId}`;
188+
if (serializedLinks.has(pairKey)) continue;
189+
serializedLinks.add(pairKey);
190+
191+
linkedObjects.push([objectA.networkId, objectB.networkId]);
192+
}
193+
}
194+
195+
return linkedObjects;
196+
}
197+
198+
/**
199+
* Restore links from serialized data. Objects must already exist
200+
* in the scene with their networkId set.
201+
*
202+
* Links for objects managed by the save state should be cleared
203+
* before calling this method, so that stale links are removed.
204+
* This method only adds the saved links back.
205+
*/
206+
updateFromNetworkSyncData(
207+
linksNetworkSyncData: Array<[string, string]>,
208+
runtimeScene: gdjs.RuntimeScene
209+
): void {
210+
if (!linksNetworkSyncData) return;
211+
212+
// Build a map from networkId to object instance for quick lookup.
213+
const objectsByNetworkId = new Map<string, gdjs.RuntimeObject>();
214+
for (const object of runtimeScene.getAdhocListOfAllInstances()) {
215+
if (object.networkId) {
216+
objectsByNetworkId.set(object.networkId, object);
217+
}
218+
}
219+
220+
for (const [networkIdA, networkIdB] of linksNetworkSyncData) {
221+
const objectA = objectsByNetworkId.get(networkIdA);
222+
const objectB = objectsByNetworkId.get(networkIdB);
223+
if (!objectA || !objectB) continue;
224+
225+
this.linkObjects(objectA, objectB);
226+
}
227+
}
162228
}
163229

164230
class IterableLinkedObjects implements Iterable<gdjs.RuntimeObject> {
231+
ownerObject: gdjs.RuntimeObject;
165232
linkedObjectMap: Map<string, gdjs.RuntimeObject[]>;
166233
static emptyItr: Iterator<gdjs.RuntimeObject> = {
167234
next: () => ({ value: undefined, done: true }),
168235
};
169236

170-
constructor() {
237+
constructor(ownerObject: gdjs.RuntimeObject) {
238+
this.ownerObject = ownerObject;
171239
this.linkedObjectMap = new Map<string, gdjs.RuntimeObject[]>();
172240
}
173241

@@ -201,6 +269,36 @@ namespace gdjs {
201269
}
202270
);
203271

272+
gdjs.registerRuntimeSceneGetSyncDataCallback(
273+
function (runtimeScene, currentLayoutSyncData, syncOptions) {
274+
if (!syncOptions.syncLinkedObjects) return;
275+
276+
currentLayoutSyncData.linkedObjects =
277+
LinksManager.getManager(runtimeScene).getNetworkSyncData();
278+
}
279+
);
280+
281+
gdjs.registerRuntimeSceneUpdateFromSyncDataCallback(
282+
function (runtimeScene, receivedSyncData, _syncOptions) {
283+
if (!receivedSyncData.linkedObjects) return;
284+
285+
const linksManager = LinksManager.getManager(runtimeScene);
286+
287+
// Clear links only for objects with a networkId (managed by save state).
288+
// DoNotSave objects don't have networkIds, so their links are preserved.
289+
for (const object of runtimeScene.getAdhocListOfAllInstances()) {
290+
if (object.networkId) {
291+
linksManager.removeAllLinksOf(object);
292+
}
293+
}
294+
295+
linksManager.updateFromNetworkSyncData(
296+
receivedSyncData.linkedObjects,
297+
runtimeScene
298+
);
299+
}
300+
);
301+
204302
export const linkObjects = function (
205303
instanceContainer: gdjs.RuntimeInstanceContainer,
206304
objA: gdjs.RuntimeObject | null,

Extensions/SaveState/SaveStateTools.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -218,6 +218,7 @@ namespace gdjs {
218218
syncAsyncTasks: true,
219219
syncSceneVisualProps: true,
220220
syncFullTileMaps: true,
221+
syncLinkedObjects: true,
221222
};
222223

223224
const shouldPersistGameData = checkIfIsPersistedInProfiles(

0 commit comments

Comments
 (0)