mirror of
https://github.com/Heretek-AI/GDevelop.git
synced 2026-08-24 22:31:30 -04:00
Fix logic to createOrReplaceObject when no object type is given
This commit is contained in:
@@ -76,11 +76,11 @@ export const useSearchAndInstallAsset = ({
|
||||
}
|
||||
|
||||
if (!assetShortHeader) {
|
||||
if (!objectType && !exactOrPartialAssetId) {
|
||||
if (!assetSearchOptions.searchTerms && !exactOrPartialAssetId) {
|
||||
return {
|
||||
status: 'error',
|
||||
message:
|
||||
'Cannot search for an asset without an object type. Specify either `object_type` or `asset_id`.',
|
||||
'Cannot search for an asset without either `searchTerms` or `exactOrPartialAssetId`.',
|
||||
createdObjects: [],
|
||||
assetShortHeader: null,
|
||||
isTheFirstOfItsTypeInProject: false,
|
||||
|
||||
@@ -113,7 +113,7 @@ describe('editorFunctions', () => {
|
||||
project.delete();
|
||||
});
|
||||
|
||||
it('creates a new object (from the asset store)', async () => {
|
||||
it('creates a new object (from scratch, because only object_type was provided)', async () => {
|
||||
// $FlowFixMe[underconstrained-implicit-instantiation]
|
||||
const onObjectsModifiedOutsideEditor = jest.fn();
|
||||
|
||||
@@ -129,6 +129,33 @@ describe('editorFunctions', () => {
|
||||
}
|
||||
);
|
||||
|
||||
expect(result.message).toMatchInlineSnapshot(
|
||||
`"Created a new object (from scratch) called \\"MyNewTextObject\\" of type \\"TextObject::Text\\" in scene \\"TestScene\\". It has the following properties: bold: false (boolean), characterSize: 20 (Pixel), color: 0;0;0 (color), font: (resource), isOutlineEnabled: false (boolean), isShadowEnabled: false (boolean), italic: false (boolean), lineHeight: 0 (Pixel), outlineColor: 255;255;255 (color), outlineThickness: 2 (Pixel), shadowAngle: 90 (DegreeAngle), shadowBlurRadius: 2 (Pixel), shadowColor: 0;0;0 (color), shadowDistance: 4 (Pixel), shadowOpacity: 127 (Pixel), text: Text (multilinestring), textAlignment: left (choice, one of: [\\"left\\", \\"center\\", \\"right\\"]), verticalTextAlignment: top (choice, one of: [\\"top\\", \\"center\\", \\"bottom\\"])."`
|
||||
);
|
||||
expect(result.success).toBe(true);
|
||||
expect(onObjectsModifiedOutsideEditor).toHaveBeenCalledWith({
|
||||
scene: testScene,
|
||||
isNewObjectTypeUsed: true,
|
||||
});
|
||||
});
|
||||
|
||||
it('creates a new object (from the asset store, with search_terms and object_type provided)', async () => {
|
||||
// $FlowFixMe[underconstrained-implicit-instantiation]
|
||||
const onObjectsModifiedOutsideEditor = jest.fn();
|
||||
|
||||
const result: EditorFunctionGenericOutput = await editorFunctions.create_or_replace_object.launchFunction(
|
||||
{
|
||||
...makeFakeLaunchFunctionOptionsWithProject(project),
|
||||
args: {
|
||||
scene_name: 'TestScene',
|
||||
object_type: 'TextObject::Text',
|
||||
object_name: 'MyNewTextObject',
|
||||
search_terms: 'Very cool text object',
|
||||
},
|
||||
onObjectsModifiedOutsideEditor,
|
||||
}
|
||||
);
|
||||
|
||||
expect(result.message).toMatchInlineSnapshot(
|
||||
`"Created (from the asset store) object \\"MyNewTextObject\\" of type \\"TextObject::Text\\" in scene \\"TestScene\\". It has the following properties: bold: false (boolean), characterSize: 20 (Pixel), color: 0;0;0 (color), font: (resource), isOutlineEnabled: false (boolean), isShadowEnabled: false (boolean), italic: false (boolean), lineHeight: 0 (Pixel), outlineColor: 255;255;255 (color), outlineThickness: 2 (Pixel), shadowAngle: 90 (DegreeAngle), shadowBlurRadius: 2 (Pixel), shadowColor: 0;0;0 (color), shadowDistance: 4 (Pixel), shadowOpacity: 127 (Pixel), text: Text (multilinestring), textAlignment: left (choice, one of: [\\"left\\", \\"center\\", \\"right\\"]), verticalTextAlignment: top (choice, one of: [\\"top\\", \\"center\\", \\"bottom\\"])."`
|
||||
);
|
||||
@@ -139,7 +166,33 @@ describe('editorFunctions', () => {
|
||||
});
|
||||
});
|
||||
|
||||
it('creates a new object (from scratch if not found in the asset store)', async () => {
|
||||
it('creates a new object (from the asset store, with search_terms but without any specified object type)', async () => {
|
||||
// $FlowFixMe[underconstrained-implicit-instantiation]
|
||||
const onObjectsModifiedOutsideEditor = jest.fn();
|
||||
|
||||
const result: EditorFunctionGenericOutput = await editorFunctions.create_or_replace_object.launchFunction(
|
||||
{
|
||||
...makeFakeLaunchFunctionOptionsWithProject(project),
|
||||
args: {
|
||||
scene_name: 'TestScene',
|
||||
object_name: 'SomeNewObject',
|
||||
search_terms: 'A very cool sprite for my player in my game',
|
||||
},
|
||||
onObjectsModifiedOutsideEditor,
|
||||
}
|
||||
);
|
||||
|
||||
expect(result.message).toMatchInlineSnapshot(
|
||||
`"Created (from the asset store) object \\"SomeNewObject\\" of type \\"Sprite\\" in scene \\"TestScene\\". It has the following properties: ."`
|
||||
);
|
||||
expect(result.success).toBe(true);
|
||||
expect(onObjectsModifiedOutsideEditor).toHaveBeenCalledWith({
|
||||
scene: testScene,
|
||||
isNewObjectTypeUsed: false,
|
||||
});
|
||||
});
|
||||
|
||||
it('creates a new object (from scratch, fallback if not found in the asset store)', async () => {
|
||||
// $FlowFixMe[underconstrained-implicit-instantiation]
|
||||
const onObjectsModifiedOutsideEditor = jest.fn();
|
||||
|
||||
@@ -556,7 +609,7 @@ describe('editorFunctions', () => {
|
||||
expect(testScene.getObjects().hasObjectNamed('MyAssetObject')).toBe(true);
|
||||
});
|
||||
|
||||
it('fails when creating a new object without object_type nor asset_id', async () => {
|
||||
it('fails when creating a new object without object_type, search_terms nor asset_id', async () => {
|
||||
const result: EditorFunctionGenericOutput = await editorFunctions.create_or_replace_object.launchFunction(
|
||||
{
|
||||
...makeFakeLaunchFunctionOptionsWithProject(project),
|
||||
@@ -569,7 +622,7 @@ describe('editorFunctions', () => {
|
||||
|
||||
expect(result.success).toBe(false);
|
||||
expect(result.message).toMatchInlineSnapshot(
|
||||
`"Cannot create object \\"MyAssetObject\\": specify either \\"object_type\\" or \\"asset_id\\"."`
|
||||
`"No search_terms or asset_id were provided to create the object \\"MyAssetObject\\". This object was not created."`
|
||||
);
|
||||
});
|
||||
|
||||
|
||||
@@ -811,98 +811,103 @@ const createOrReplaceObject: EditorFunction = {
|
||||
);
|
||||
}
|
||||
|
||||
if (!candidateType && !asset_id) {
|
||||
return makeGenericFailure(
|
||||
`Cannot create object "${targetObjectName}": specify either "object_type" or "asset_id".`
|
||||
);
|
||||
}
|
||||
|
||||
const targetObjectsContainer =
|
||||
target_object_scope === 'global' ? globalObjects : layoutObjects;
|
||||
|
||||
// First try to search and install an object from the asset store.
|
||||
try {
|
||||
const {
|
||||
status,
|
||||
message,
|
||||
createdObjects,
|
||||
assetShortHeader,
|
||||
isTheFirstOfItsTypeInProject,
|
||||
} = await searchAndInstallAsset({
|
||||
objectsContainer: targetObjectsContainer,
|
||||
objectName: targetObjectName,
|
||||
objectType: candidateType,
|
||||
searchTerms: search_terms || '',
|
||||
description: description || '',
|
||||
twoDimensionalViewKind: two_dimensional_view_kind || '',
|
||||
exactOrPartialAssetId: asset_id || null,
|
||||
relatedAiRequestId,
|
||||
...getRelatedAiRequestLastMessages(),
|
||||
});
|
||||
|
||||
if (status === 'error') {
|
||||
if (candidateType && !search_terms && !asset_id) {
|
||||
// Do nothing: there is nothing given apart from an object type,
|
||||
// which we can still use to fallback to create from scratch.
|
||||
} else {
|
||||
if (!search_terms && !asset_id) {
|
||||
return makeGenericFailure(
|
||||
`Unable to search and install object (${message}).`
|
||||
`No search_terms or asset_id were provided to create the object "${targetObjectName}". This object was not created.`
|
||||
);
|
||||
} else if (status === 'asset-installed') {
|
||||
// Update behaviors shared data for the scene where the object was created.
|
||||
// Assets from the store can come with behaviors that have shared data.
|
||||
if (target_object_scope === 'global') {
|
||||
gd.WholeProjectRefactorer.updateBehaviorsSharedData(project);
|
||||
} else {
|
||||
layout.updateBehaviorsSharedData(project);
|
||||
}
|
||||
}
|
||||
|
||||
// /!\ Tell the editor that some objects have potentially been modified (and even removed).
|
||||
// This will force the objects panel to refresh.
|
||||
onObjectsModifiedOutsideEditor({
|
||||
scene: layout,
|
||||
isNewObjectTypeUsed: isTheFirstOfItsTypeInProject,
|
||||
// First try to search and install an object from the asset store.
|
||||
try {
|
||||
const {
|
||||
status,
|
||||
message,
|
||||
createdObjects,
|
||||
assetShortHeader,
|
||||
isTheFirstOfItsTypeInProject,
|
||||
} = await searchAndInstallAsset({
|
||||
objectsContainer: targetObjectsContainer,
|
||||
objectName: targetObjectName,
|
||||
objectType: candidateType,
|
||||
searchTerms: search_terms || '',
|
||||
description: description || '',
|
||||
twoDimensionalViewKind: two_dimensional_view_kind || '',
|
||||
exactOrPartialAssetId: asset_id || null,
|
||||
relatedAiRequestId,
|
||||
...getRelatedAiRequestLastMessages(),
|
||||
});
|
||||
|
||||
if (createdObjects.length === 1) {
|
||||
const object = createdObjects[0];
|
||||
const result: EditorFunctionGenericOutput = {
|
||||
success: true,
|
||||
message: [
|
||||
`Created (from the asset store) object "${object.getName()}" of type "${object.getType()}" in scene "${scene_name}".`,
|
||||
getPropertiesText(object),
|
||||
].join(' '),
|
||||
objectSizeInfo: {
|
||||
[object.getName()]: getObjectSizeInfo(
|
||||
object,
|
||||
project,
|
||||
PixiResourcesLoader,
|
||||
assetShortHeader
|
||||
),
|
||||
},
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
return makeGenericSuccess(
|
||||
`Created (from the asset store) ${createdObjects
|
||||
.map(
|
||||
object =>
|
||||
`object "${object.getName()}" of type "${object.getType()}"`
|
||||
)
|
||||
.join(', ')} in scene "${scene_name}".`
|
||||
);
|
||||
} else {
|
||||
if (asset_id) {
|
||||
if (status === 'error') {
|
||||
return makeGenericFailure(
|
||||
`No asset found with id "${asset_id}". The object was not created.`
|
||||
`Unable to search and install object (${message}).`
|
||||
);
|
||||
}
|
||||
} else if (status === 'asset-installed') {
|
||||
// Update behaviors shared data for the scene where the object was created.
|
||||
// Assets from the store can come with behaviors that have shared data.
|
||||
if (target_object_scope === 'global') {
|
||||
gd.WholeProjectRefactorer.updateBehaviorsSharedData(project);
|
||||
} else {
|
||||
layout.updateBehaviorsSharedData(project);
|
||||
}
|
||||
|
||||
// No asset found - we'll create an object from scratch.
|
||||
// /!\ Tell the editor that some objects have potentially been modified (and even removed).
|
||||
// This will force the objects panel to refresh.
|
||||
onObjectsModifiedOutsideEditor({
|
||||
scene: layout,
|
||||
isNewObjectTypeUsed: isTheFirstOfItsTypeInProject,
|
||||
});
|
||||
|
||||
if (createdObjects.length === 1) {
|
||||
const object = createdObjects[0];
|
||||
const result: EditorFunctionGenericOutput = {
|
||||
success: true,
|
||||
message: [
|
||||
`Created (from the asset store) object "${object.getName()}" of type "${object.getType()}" in scene "${scene_name}".`,
|
||||
getPropertiesText(object),
|
||||
].join(' '),
|
||||
objectSizeInfo: {
|
||||
[object.getName()]: getObjectSizeInfo(
|
||||
object,
|
||||
project,
|
||||
PixiResourcesLoader,
|
||||
assetShortHeader
|
||||
),
|
||||
},
|
||||
};
|
||||
return result;
|
||||
}
|
||||
|
||||
return makeGenericSuccess(
|
||||
`Created (from the asset store) ${createdObjects
|
||||
.map(
|
||||
object =>
|
||||
`object "${object.getName()}" of type "${object.getType()}"`
|
||||
)
|
||||
.join(', ')} in scene "${scene_name}".`
|
||||
);
|
||||
} else {
|
||||
if (asset_id) {
|
||||
return makeGenericFailure(
|
||||
`No asset found with id "${asset_id}". The object was not created.`
|
||||
);
|
||||
}
|
||||
|
||||
// No asset found - we'll create an object from scratch.
|
||||
}
|
||||
} catch (error) {
|
||||
return makeGenericFailure(
|
||||
`An unexpected error happened while search and installing objects (${
|
||||
error.message
|
||||
}).`
|
||||
);
|
||||
}
|
||||
} catch (error) {
|
||||
return makeGenericFailure(
|
||||
`An unexpected error happened while search and installing objects (${
|
||||
error.message
|
||||
}).`
|
||||
);
|
||||
}
|
||||
|
||||
// Create an object from scratch: this requires a known object type.
|
||||
|
||||
Reference in New Issue
Block a user