Skip to content

Commit 66391a3

Browse files
committed
Handle assets with variants of several object types.
1 parent 8a4a019 commit 66391a3

File tree

8 files changed

+158
-59
lines changed

8 files changed

+158
-59
lines changed

Core/GDCore/Project/EventsBasedObjectVariant.cpp

+6-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,10 @@ EventsBasedObjectVariant::~EventsBasedObjectVariant() {}
1818

1919
void EventsBasedObjectVariant::SerializeTo(SerializerElement &element) const {
2020
element.SetAttribute("name", name);
21-
element.SetAttribute("assetStoreId", GetAssetStoreId());
21+
if (!GetAssetStoreAssetId().empty() && !GetAssetStoreOriginalName().empty()) {
22+
element.SetAttribute("assetStoreAssetId", GetAssetStoreAssetId());
23+
element.SetAttribute("assetStoreOriginalName", GetAssetStoreOriginalName());
24+
}
2225
element.SetIntAttribute("areaMinX", areaMinX);
2326
element.SetIntAttribute("areaMinY", areaMinY);
2427
element.SetIntAttribute("areaMinZ", areaMinZ);
@@ -39,7 +42,8 @@ void EventsBasedObjectVariant::SerializeTo(SerializerElement &element) const {
3942
void EventsBasedObjectVariant::UnserializeFrom(
4043
gd::Project &project, const SerializerElement &element) {
4144
name = element.GetStringAttribute("name");
42-
assetStoreId = element.GetStringAttribute("assetStoreId");
45+
assetStoreAssetId = element.GetStringAttribute("assetStoreAssetId");
46+
assetStoreOriginalName = element.GetStringAttribute("assetStoreOriginalName");
4347
areaMinX = element.GetIntAttribute("areaMinX", 0);
4448
areaMinY = element.GetIntAttribute("areaMinY", 0);
4549
areaMinZ = element.GetIntAttribute("areaMinZ", 0);

Core/GDCore/Project/EventsBasedObjectVariant.h

+23-6
Original file line numberDiff line numberDiff line change
@@ -178,15 +178,27 @@ class GD_CORE_API EventsBasedObjectVariant {
178178
void SetAreaMaxZ(int areaMaxZ_) { areaMaxZ = areaMaxZ_; }
179179
///@}
180180

181-
/** \brief Change the asset store id of the object.
181+
/** \brief Change the object asset store id of this variant.
182182
*/
183-
void SetAssetStoreId(const gd::String &assetStoreId_) {
184-
assetStoreId = assetStoreId_;
183+
void SetAssetStoreAssetId(const gd::String &assetStoreId_) {
184+
assetStoreAssetId = assetStoreId_;
185185
};
186186

187-
/** \brief Return the asset store id of the object.
187+
/** \brief Return the object asset store id of this variant.
188188
*/
189-
const gd::String &GetAssetStoreId() const { return assetStoreId; };
189+
const gd::String &GetAssetStoreAssetId() const { return assetStoreAssetId; };
190+
191+
/** \brief Change the original name of the variant in the asset.
192+
*/
193+
void SetAssetStoreOriginalName(const gd::String &assetStoreOriginalName_) {
194+
assetStoreOriginalName = assetStoreOriginalName_;
195+
};
196+
197+
/** \brief Return the original name of the variant in the asset.
198+
*/
199+
const gd::String &GetAssetStoreOriginalName() const {
200+
return assetStoreOriginalName;
201+
};
190202

191203
void SerializeTo(SerializerElement &element) const;
192204

@@ -206,7 +218,12 @@ class GD_CORE_API EventsBasedObjectVariant {
206218
/**
207219
* The ID of the asset if the object comes from the store.
208220
*/
209-
gd::String assetStoreId;
221+
gd::String assetStoreAssetId;
222+
/**
223+
* The original name of the variant in the asset if the object comes from the
224+
* store.
225+
*/
226+
gd::String assetStoreOriginalName;
210227
};
211228

212229
} // namespace gd

GDevelop.js/Bindings/Bindings.idl

+4-2
Original file line numberDiff line numberDiff line change
@@ -3194,8 +3194,10 @@ interface EventsBasedObjectVariant {
31943194
void SetAreaMaxX(double value);
31953195
void SetAreaMaxY(double value);
31963196
void SetAreaMaxZ(double value);
3197-
void SetAssetStoreId([Const] DOMString assetStoreId);
3198-
[Const, Ref] DOMString GetAssetStoreId();
3197+
void SetAssetStoreAssetId([Const] DOMString assetStoreAssetId);
3198+
[Const, Ref] DOMString GetAssetStoreAssetId();
3199+
void SetAssetStoreOriginalName([Const] DOMString assetStoreOriginalName);
3200+
[Const, Ref] DOMString GetAssetStoreOriginalName();
31993201

32003202
void SerializeTo([Ref] SerializerElement element);
32013203
void UnserializeFrom([Ref] Project project, [Const, Ref] SerializerElement element);

GDevelop.js/types.d.ts

+4-2
Original file line numberDiff line numberDiff line change
@@ -2314,8 +2314,10 @@ export class EventsBasedObjectVariant extends EmscriptenObject {
23142314
setAreaMaxX(value: number): void;
23152315
setAreaMaxY(value: number): void;
23162316
setAreaMaxZ(value: number): void;
2317-
setAssetStoreId(assetStoreId: string): void;
2318-
getAssetStoreId(): string;
2317+
setAssetStoreAssetId(assetStoreAssetId: string): void;
2318+
getAssetStoreAssetId(): string;
2319+
setAssetStoreOriginalName(assetStoreOriginalName: string): void;
2320+
getAssetStoreOriginalName(): string;
23192321
serializeTo(element: SerializerElement): void;
23202322
unserializeFrom(project: Project, element: SerializerElement): void;
23212323
}

GDevelop.js/types/gdeventsbasedobjectvariant.js

+4-2
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,10 @@ declare class gdEventsBasedObjectVariant {
1818
setAreaMaxX(value: number): void;
1919
setAreaMaxY(value: number): void;
2020
setAreaMaxZ(value: number): void;
21-
setAssetStoreId(assetStoreId: string): void;
22-
getAssetStoreId(): string;
21+
setAssetStoreAssetId(assetStoreAssetId: string): void;
22+
getAssetStoreAssetId(): string;
23+
setAssetStoreOriginalName(assetStoreOriginalName: string): void;
24+
getAssetStoreOriginalName(): string;
2325
serializeTo(element: gdSerializerElement): void;
2426
unserializeFrom(project: gdProject, element: gdSerializerElement): void;
2527
delete(): void;

newIDE/app/src/AssetStore/InstallAsset.js

+100-36
Original file line numberDiff line numberDiff line change
@@ -157,11 +157,15 @@ export type InstallAssetArgs = {|
157157

158158
const findVariant = (
159159
container: gdEventsBasedObjectVariantsContainer,
160-
assetStoreId: string
160+
assetStoreAssetId: string,
161+
assetStoreOriginalName: string
161162
): gdEventsBasedObjectVariant | null => {
162163
for (let index = 0; index < container.getVariantsCount(); index++) {
163164
const variant = container.getVariantAt(index);
164-
if (variant.getAssetStoreId()) {
165+
if (
166+
variant.getAssetStoreAssetId() === assetStoreAssetId &&
167+
variant.getAssetStoreOriginalName() === assetStoreOriginalName
168+
) {
165169
return variant;
166170
}
167171
}
@@ -183,34 +187,86 @@ export const addAssetToProject = async ({
183187
const type: ?string = objectAsset.object.type;
184188
if (!type) throw new Error('An object has no type specified');
185189

186-
let variantName: string | null = null;
187-
const serializedVariant = objectAsset.variant;
188-
const isCustomObjectWithVariant =
189-
serializedVariant && project.hasEventsBasedObject(type);
190-
if (isCustomObjectWithVariant && serializedVariant) {
191-
const eventsBasedObject = project.getEventsBasedObject(type);
192-
const variants = eventsBasedObject.getVariants();
193-
variantName = serializedVariant.name;
194-
let variant = findVariant(variants, serializedVariant.assetStoreId);
195-
if (!variant) {
196-
// TODO Forbid name with `::`
197-
const uniqueNewName = newNameGenerator(variantName, tentativeNewName =>
198-
variants.hasVariantNamed(tentativeNewName)
199-
);
200-
variant = variants.insertNewVariant(
201-
uniqueNewName,
202-
variants.getVariantsCount()
203-
);
204-
variantName = uniqueNewName;
190+
const variantRenamings: Array<{
191+
objectType: string,
192+
oldVariantName: string,
193+
newVariantName: string,
194+
}> = [];
195+
const serializedVariants = objectAsset.variants;
196+
if (serializedVariants) {
197+
// Install variants
198+
for (const {
199+
objectType,
200+
variant: serializedVariant,
201+
} of serializedVariants) {
202+
if (project.hasEventsBasedObject(objectType)) {
203+
const eventsBasedObject = project.getEventsBasedObject(objectType);
204+
const variants = eventsBasedObject.getVariants();
205+
let variant = findVariant(variants, asset.id, serializedVariant.name);
206+
if (!variant) {
207+
// TODO Forbid name with `::`
208+
const uniqueNewName = newNameGenerator(
209+
serializedVariant.name,
210+
tentativeNewName => variants.hasVariantNamed(tentativeNewName)
211+
);
212+
variant = variants.insertNewVariant(
213+
uniqueNewName,
214+
variants.getVariantsCount()
215+
);
216+
const variantName = variant.getName();
217+
unserializeFromJSObject(
218+
variant,
219+
serializedVariant,
220+
'unserializeFrom',
221+
project
222+
);
223+
variant.setName(variantName);
224+
variant.setAssetStoreAssetId(asset.id);
225+
variant.setAssetStoreOriginalName(serializedVariant.name);
226+
}
227+
if (variant.getName() !== serializedVariant.name) {
228+
variantRenamings.push({
229+
objectType,
230+
oldVariantName: serializedVariant.name,
231+
newVariantName: variant.getName(),
232+
});
233+
}
234+
}
235+
}
236+
// Update variant names into variants object configurations.
237+
for (const {
238+
objectType,
239+
variant: serializedVariant,
240+
} of serializedVariants) {
241+
if (project.hasEventsBasedObject(objectType)) {
242+
const eventsBasedObject = project.getEventsBasedObject(objectType);
243+
const variants = eventsBasedObject.getVariants();
244+
let variant = findVariant(variants, asset.id, serializedVariant.name);
245+
if (variant) {
246+
for (
247+
let index = 0;
248+
index < variant.getObjects().getObjectsCount();
249+
index++
250+
) {
251+
const object = variant.getObjects().getObjectAt(index);
252+
253+
if (project.hasEventsBasedObject(object.getType())) {
254+
const customObjectConfiguration = gd.asCustomObjectConfiguration(
255+
object.getConfiguration()
256+
);
257+
const customObjectVariantRenaming = variantRenamings.find(
258+
renaming => renaming.objectType === object.getType()
259+
);
260+
if (customObjectVariantRenaming) {
261+
customObjectConfiguration.setVariantName(
262+
customObjectVariantRenaming.newVariantName
263+
);
264+
}
265+
}
266+
}
267+
}
268+
}
205269
}
206-
unserializeFromJSObject(
207-
variant,
208-
serializedVariant,
209-
'unserializeFrom',
210-
project
211-
);
212-
variant.setName(variantName);
213-
variant.setAssetStoreId(asset.id);
214270
}
215271

216272
// Insert the object
@@ -247,19 +303,27 @@ export const addAssetToProject = async ({
247303
'unserializeFrom',
248304
project
249305
);
250-
306+
// The name was overwritten after unserialization.
307+
object.setName(newName);
251308
object.setAssetStoreId(asset.id);
252-
if (isCustomObjectWithVariant && variantName) {
309+
if (project.hasEventsBasedObject(object.getType())) {
253310
const customObjectConfiguration = gd.asCustomObjectConfiguration(
254311
object.getConfiguration()
255312
);
256-
customObjectConfiguration.setVariantName(variantName);
257-
customObjectConfiguration.setMarkedAsOverridingEventsBasedObjectChildrenConfiguration(
258-
false
313+
if (customObjectConfiguration.getVariantName()) {
314+
customObjectConfiguration.setMarkedAsOverridingEventsBasedObjectChildrenConfiguration(
315+
false
316+
);
317+
}
318+
const customObjectVariantRenaming = variantRenamings.find(
319+
renaming => renaming.objectType === object.getType()
259320
);
321+
if (customObjectVariantRenaming) {
322+
customObjectConfiguration.setVariantName(
323+
customObjectVariantRenaming.newVariantName
324+
);
325+
}
260326
}
261-
// The name was overwritten after unserialization.
262-
object.setName(newName);
263327

264328
// Add resources used by the object
265329
objectAsset.resources.forEach(serializedResource => {

newIDE/app/src/ObjectEditor/Editors/CustomObjectPropertiesEditor/index.js

+13-8
Original file line numberDiff line numberDiff line change
@@ -78,13 +78,15 @@ const getVariant = (
7878
eventBasedObject: gdEventsBasedObject,
7979
customObjectConfiguration: gdCustomObjectConfiguration
8080
): gdEventsBasedObjectVariant => {
81-
const variantName = getVariantName(eventBasedObject, customObjectConfiguration);
81+
const variantName = getVariantName(
82+
eventBasedObject,
83+
customObjectConfiguration
84+
);
8285
const variants = eventBasedObject.getVariants();
8386
return variantName
84-
? variants.getVariant(variantName)
85-
: eventBasedObject.getDefaultVariant();
86-
}
87-
87+
? variants.getVariant(variantName)
88+
: eventBasedObject.getDefaultVariant();
89+
};
8890

8991
type Props = EditorProps;
9092

@@ -241,7 +243,8 @@ const CustomObjectPropertiesEditor = (props: Props) => {
241243
project
242244
);
243245
newVariant.setName(uniqueNewName);
244-
newVariant.setAssetStoreId('');
246+
newVariant.setAssetStoreAssetId('');
247+
newVariant.setAssetStoreOriginalName('');
245248
customObjectConfiguration.setVariantName(uniqueNewName);
246249
setNewVariantDialogOpen(false);
247250
forceUpdate();
@@ -257,6 +260,7 @@ const CustomObjectPropertiesEditor = (props: Props) => {
257260
const variants = eventBasedObject.getVariants();
258261
const selectedVariantName = customObjectConfiguration.getVariantName();
259262
if (variants.hasVariantNamed(selectedVariantName)) {
263+
// TODO Close the variant tabs before deleting it.
260264
customObjectConfiguration.setVariantName('');
261265
variants.removeVariant(selectedVariantName);
262266
forceUpdate();
@@ -344,10 +348,11 @@ const CustomObjectPropertiesEditor = (props: Props) => {
344348
label={<Trans>Edit</Trans>}
345349
onClick={editVariant}
346350
disabled={
347-
!eventBasedObject || getVariant(
351+
!eventBasedObject ||
352+
getVariant(
348353
eventBasedObject,
349354
customObjectConfiguration
350-
).getAssetStoreId() !== ''
355+
).getAssetStoreAssetId() !== ''
351356
}
352357
/>
353358
<FlatButton

newIDE/app/src/Utils/GDevelopServices/Asset.js

+4-1
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,10 @@ export type ExtensionDependency = {|
4545
export type ObjectAsset = {|
4646
object: any /*(serialized gdObjectConfiguration)*/,
4747
resources: Array<any /*(serialized gdResource)*/>,
48-
variant?: any /*(serialized gdEventsBasedObjectVariant)*/,
48+
variants?: Array<{
49+
objectType: string,
50+
variant: any /*(serialized gdEventsBasedObjectVariant)*/,
51+
}>,
4952
// TODO This can become mandatory after the migration of the asset repository.
5053
requiredExtensions?: Array<ExtensionDependency>,
5154
|};

0 commit comments

Comments
 (0)