Skip to content
Draft
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
9 changes: 9 additions & 0 deletions Core/GDCore/IDE/Events/UsedExtensionsFinder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,15 @@ const UsedExtensionsResult UsedExtensionsFinder::ScanProject(gd::Project& projec
return worker.result;
};

const UsedExtensionsResult UsedExtensionsFinder::ScanEventsFunctionsExtension(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension) {
UsedExtensionsFinder worker(project);
gd::ProjectBrowserHelper::ExposeEventsFunctionsExtensionEvents(
project, eventsFunctionsExtension, worker);
return worker.result;
}

// Objects scanner

void UsedExtensionsFinder::DoVisitObject(gd::Object &object) {
Expand Down
5 changes: 4 additions & 1 deletion Core/GDCore/IDE/Events/UsedExtensionsFinder.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,8 +80,11 @@ class GD_CORE_API UsedExtensionsFinder
public ExpressionParser2NodeWorker {
public:
static const UsedExtensionsResult ScanProject(gd::Project& project);
static const UsedExtensionsResult ScanEventsFunctionsExtension(
gd::Project &project,
const gd::EventsFunctionsExtension &eventsFunctionsExtension);

private:
private:
UsedExtensionsFinder(gd::Project& project_) : project(project_){};
gd::Project& project;
gd::String rootType;
Expand Down
3 changes: 3 additions & 0 deletions GDevelop.js/Bindings/Bindings.idl
Original file line number Diff line number Diff line change
Expand Up @@ -2864,6 +2864,9 @@ interface UsedExtensionsResult {

interface UsedExtensionsFinder {
[Value] UsedExtensionsResult STATIC_ScanProject([Ref] Project project);
[Value] UsedExtensionsResult STATIC_ScanEventsFunctionsExtension(
[Ref] Project project, [Const, Ref]
EventsFunctionsExtension eventsFunctionsExtension);
};

interface ExampleExtensionUsagesFinder {
Expand Down
1 change: 1 addition & 0 deletions GDevelop.js/Bindings/Wrapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -825,6 +825,7 @@ typedef std::vector<gd::PropertyDescriptorChoice> VectorPropertyDescriptorChoice
#define STATIC_GetNodeAtPosition GetNodeAtPosition

#define STATIC_ScanProject ScanProject
#define STATIC_ScanEventsFunctionsExtension ScanEventsFunctionsExtension
#define STATIC_GetUsedExtensions GetUsedExtensions

#define STATIC_ApplyTranslation ApplyTranslation
Expand Down
1 change: 1 addition & 0 deletions GDevelop.js/types.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2044,6 +2044,7 @@ export class UsedExtensionsResult extends EmscriptenObject {

export class UsedExtensionsFinder extends EmscriptenObject {
static scanProject(project: Project): UsedExtensionsResult;
static scanEventsFunctionsExtension(project: Project, eventsFunctionsExtension: EventsFunctionsExtension): UsedExtensionsResult;
}

export class ExampleExtensionUsagesFinder extends EmscriptenObject {
Expand Down
1 change: 1 addition & 0 deletions GDevelop.js/types/gdusedextensionsfinder.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
// Automatically generated by GDevelop.js/scripts/generate-types.js
declare class gdUsedExtensionsFinder {
static scanProject(project: gdProject): gdUsedExtensionsResult;
static scanEventsFunctionsExtension(project: gdProject, eventsFunctionsExtension: gdEventsFunctionsExtension): gdUsedExtensionsResult;
delete(): void;
ptr: number;
};
66 changes: 39 additions & 27 deletions newIDE/app/src/AiGeneration/UseEnsureExtensionInstalled.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,13 @@
import * as React from 'react';
import { type I18n as I18nType } from '@lingui/core';
import { ExtensionStoreContext } from '../AssetStore/ExtensionStore/ExtensionStoreContext';
import EventsFunctionsExtensionsContext from '../EventsFunctionsExtensionsLoader/EventsFunctionsExtensionsContext';
import { installExtension } from '../AssetStore/ExtensionStore/InstallExtension';
import {
useInstallExtension,
checkRequiredExtensionsUpdate,
getRequiredExtensions,
getExtensionHeader,
} from '../AssetStore/ExtensionStore/InstallExtension';
import { type ExtensionShortHeader } from '../Utils/GDevelopServices/Extension';

type EnsureExtensionInstalledOptions = {|
extensionName: string,
Expand All @@ -16,39 +21,46 @@ export const useEnsureExtensionInstalled = ({
project: ?gdProject,
i18n: I18nType,
|}) => {
const { translatedExtensionShortHeadersByName } = React.useContext(
ExtensionStoreContext
);
const eventsFunctionsExtensionsState = React.useContext(
EventsFunctionsExtensionsContext
);
const {
translatedExtensionShortHeadersByName: extensionShortHeadersByName,
} = React.useContext(ExtensionStoreContext);
const installExtension = useInstallExtension();

return {
ensureExtensionInstalled: React.useCallback(
async ({ extensionName }: EnsureExtensionInstalledOptions) => {
if (!project) return;
if (project.getCurrentPlatform().isExtensionLoaded(extensionName))
return;

const extensionShortHeader =
translatedExtensionShortHeadersByName[extensionName];
if (!extensionShortHeader) {
throw new Error(`Can't find extension named ${extensionName}.`);
}

await installExtension(
i18n,
project,
eventsFunctionsExtensionsState,
extensionShortHeader
const extensionShortHeader = getExtensionHeader(
extensionShortHeadersByName,
extensionName
);
const extensionShortHeaders: Array<ExtensionShortHeader> = [
extensionShortHeader,
];
const requiredExtensions = getRequiredExtensions(extensionShortHeaders);
requiredExtensions.push({
extensionName: extensionShortHeader.name,
extensionVersion: extensionShortHeader.version,
});
const requiredExtensionInstallation = await checkRequiredExtensionsUpdate(
{
requiredExtensions,
project,
extensionShortHeadersByName,
}
);
await installExtension({
project,
requiredExtensionInstallation,
userSelectedExtensionNames: [],
importedSerializedExtensions: [],
// TODO
onExtensionInstalled: () => {},
updateMode: 'safeOnly',
});
},
[
eventsFunctionsExtensionsState,
i18n,
project,
translatedExtensionShortHeadersByName,
]
[extensionShortHeadersByName, installExtension, project]
),
};
};
52 changes: 21 additions & 31 deletions newIDE/app/src/AssetStore/AssetPackInstallDialog.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,10 @@ import RaisedButtonWithSplitMenu from '../UI/RaisedButtonWithSplitMenu';
import { Column, Line } from '../UI/Grid';
import {
checkRequiredExtensionsUpdateForAssets,
installRequiredExtensions,
installPublicAsset,
type RequiredExtensionInstallation,
complyVariantsToEventsBasedObjectOf,
} from './InstallAsset';
import EventsFunctionsExtensionsContext from '../EventsFunctionsExtensionsLoader/EventsFunctionsExtensionsContext';
import { useInstallExtension } from './ExtensionStore/InstallExtension';
import { showErrorBox } from '../UI/Messages/MessageBox';
import LinearProgress from '../UI/LinearProgress';
import PrivateAssetsAuthorizationContext from './PrivateAssets/PrivateAssetsAuthorizationContext';
Expand All @@ -32,12 +30,10 @@ import RadioGroup from '@material-ui/core/RadioGroup';
import { mapFor } from '../Utils/MapFor';
import FormControlLabel from '@material-ui/core/FormControlLabel';
import AlertMessage from '../UI/AlertMessage';
import {
useExtensionUpdateAlertDialog,
useFetchAssets,
} from './NewObjectDialog';
import { useFetchAssets } from './NewObjectDialog';
import { type InstallAssetOutput } from './InstallAsset';
import { type ObjectFolderOrObjectWithContext } from '../ObjectsList/EnumerateObjectFolderOrObject';
import { ExtensionStoreContext } from './ExtensionStore/ExtensionStoreContext';

// We limit the number of assets that can be installed at once to avoid
// timeouts especially with premium packs.
Expand Down Expand Up @@ -94,15 +90,15 @@ const AssetPackInstallDialog = ({
[resourceManagementProps]
);

const eventsFunctionsExtensionsState = React.useContext(
EventsFunctionsExtensionsContext
);
const { installPrivateAsset } = React.useContext(
PrivateAssetsAuthorizationContext
);
const {
translatedExtensionShortHeadersByName: extensionShortHeadersByName,
} = React.useContext(ExtensionStoreContext);
const installExtension = useInstallExtension();

const fetchAssets = useFetchAssets();
const showExtensionUpdateConfirmation = useExtensionUpdateAlertDialog();

const [selectedLayoutName, setSelectedLayoutName] = React.useState<string>(
''
Expand Down Expand Up @@ -155,31 +151,25 @@ const AssetPackInstallDialog = ({
setAreAssetsBeingInstalled(true);
try {
const assets = await fetchAssets(assetShortHeaders);
const requiredExtensionInstallation: RequiredExtensionInstallation = await checkRequiredExtensionsUpdateForAssets(

const requiredExtensionInstallation = await checkRequiredExtensionsUpdateForAssets(
{
assets,
project,
extensionShortHeadersByName,
}
);
const extensionUpdateAction =
requiredExtensionInstallation.outOfDateExtensionShortHeaders
.length === 0
? 'skip'
: await showExtensionUpdateConfirmation({
project,
outOfDateExtensionShortHeaders:
requiredExtensionInstallation.outOfDateExtensionShortHeaders,
});
if (extensionUpdateAction === 'abort') {
return;
}
await installRequiredExtensions({
requiredExtensionInstallation,
shouldUpdateExtension: extensionUpdateAction === 'update',
eventsFunctionsExtensionsState,
const wasExtensionsInstalled = await installExtension({
project,
requiredExtensionInstallation,
userSelectedExtensionNames: [],
importedSerializedExtensions: [],
onExtensionInstalled,
updateMode: 'all',
});
if (!wasExtensionsInstalled) {
return;
}

// Use a pool to avoid installing an unbounded amount of assets at the same time.
const { errors, results } = await PromisePool.withConcurrency(6)
Expand Down Expand Up @@ -252,11 +242,11 @@ const AssetPackInstallDialog = ({
[
fetchAssets,
project,
showExtensionUpdateConfirmation,
eventsFunctionsExtensionsState,
extensionShortHeadersByName,
installExtension,
onExtensionInstalled,
resourceManagementProps,
onAssetsAdded,
onExtensionInstalled,
installPrivateAsset,
targetObjectsContainer,
targetObjectFolderOrObjectWithContext,
Expand Down
Loading