Skip to content

Commit

Permalink
don't keep duplicating assets when pasting multiple times
Browse files Browse the repository at this point in the history
  • Loading branch information
riknoll committed Feb 12, 2025
1 parent 64b3c69 commit da44636
Show file tree
Hide file tree
Showing 2 changed files with 42 additions and 16 deletions.
21 changes: 13 additions & 8 deletions pxtblocks/fields/field_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -469,8 +469,6 @@ export function getAssetSaveState(asset: pxt.Asset) {
}


// TODO: we shouldn't keep duplicating the assets every time we paste into
// the same project
export function loadAssetFromSaveState(serialized: AssetSaveState) {
let newId = serialized.assetId;
serialized.jres = inflateJRes(serialized.jres);
Expand Down Expand Up @@ -499,14 +497,21 @@ export function loadAssetFromSaveState(serialized: AssetSaveState) {

const tempAsset = tempProject.lookupAsset(serialized.assetType, serialized.assetId);

// asset equals checks this field, so copy it over to the temp asset
tempAsset.meta.blockIDs = existing.meta.blockIDs;

if (pxt.assetEquals(tempAsset, existing)) {
if (pxt.assetEquals(tempAsset, existing, true)) {
return existing;
}
else {
// the asset ids collided! remap the id in the jres before loading
// the asset ids collided! first try to find another asset in the
// project that has the same value. for example, if the same code
// is copy/pasted multiple times then we will have already created
// a new asset for this code
const valueMatch = globalProject.lookupAssetByValue(tempAsset.type, tempAsset);

if (valueMatch) {
return valueMatch;
}

// no existing asset, so remap the id in the jres before loading
// it in the project. in the case of a tilemap, we only need to
// remap the tilemap id because loadTilemapJRes automatically remaps
// tile ids and resolves duplicates
Expand All @@ -515,8 +520,8 @@ export function loadAssetFromSaveState(serialized: AssetSaveState) {
const [key, entry] = findEntryInJres(serialized.jres, serialized.assetId);
delete serialized.jres[key];

// tilemap ids don't have namespaces
if (serialized.assetType === "tilemap") {
// tilemap ids don't have namespaces
entry.id = newId;
serialized.jres[newId] = entry;
}
Expand Down
37 changes: 29 additions & 8 deletions pxtlib/tilemap.ts
Original file line number Diff line number Diff line change
Expand Up @@ -197,6 +197,15 @@ namespace pxt {
return undefined;
}

getByValue(toFind: U) {
for (const asset of this.assets) {
if (assetEquals(toFind, asset, true)) {
return asset;
}
}
return undefined;
}

isIDTaken(id: string) {
return !!this.takenNames[id];
}
Expand Down Expand Up @@ -896,6 +905,16 @@ namespace pxt {
return getAssetCollection(this.state, assetType).getByDisplayName(name);
}

public lookupAssetByValue(assetType: AssetType.Image, toFind: ProjectImage): ProjectImage;
public lookupAssetByValue(assetType: AssetType.Tile, toFind: Tile): Tile;
public lookupAssetByValue(assetType: AssetType.Tilemap, toFind: ProjectTilemap): ProjectTilemap;
public lookupAssetByValue(assetType: AssetType.Animation, toFind: Animation): Animation;
public lookupAssetByValue(assetType: AssetType.Song, toFind: Song): Song;
public lookupAssetByValue(assetType: AssetType, toFind: Asset): Asset;
public lookupAssetByValue(assetType: AssetType, toFind: Asset) {
return getAssetCollection(this.state, assetType).getByValue(toFind);
}

public getAssets(type: AssetType.Image): ProjectImage[];
public getAssets(type: AssetType.Tile): Tile[];
public getAssets(type: AssetType.Tilemap): ProjectTilemap[];
Expand Down Expand Up @@ -1786,15 +1805,17 @@ namespace pxt {

}

export function assetEquals(a: Asset, b: Asset): boolean {
export function assetEquals(a: Asset, b: Asset, valueOnly = false): boolean {
if (a == b) return true;
if (!a && b || !b && a) return false;
if (a.id !== b.id || a.type !== b.type ||
!U.arrayEquals(a.meta.tags, b.meta.tags) ||
!U.arrayEquals(a.meta.blockIDs, b.meta.blockIDs) ||
a.meta.displayName !== b.meta.displayName
)
return false;
if (!a && b || !b && a || a.type !== b.type) return false;
if (!valueOnly) {
if (a.id !== b.id ||
!U.arrayEquals(a.meta.tags, b.meta.tags) ||
!U.arrayEquals(a.meta.blockIDs, b.meta.blockIDs) ||
a.meta.displayName !== b.meta.displayName
)
return false;
}

switch (a.type) {
case AssetType.Image:
Expand Down

0 comments on commit da44636

Please sign in to comment.