Compare commits

...

2 Commits

Author SHA1 Message Date
Florian Rival
ac97470140 Run autoformatting with the latest Prettier
cd newIDE/app && npm run format
cd newIDE/electron-app && npm run format
cd GDJS && npm run format
2022-05-21 14:00:46 +00:00
Florian Rival
bde4e9254d Update to latest Prettier 2022-05-21 11:20:19 +00:00
621 changed files with 7656 additions and 8484 deletions

View File

@@ -19,7 +19,8 @@ namespace gdjs {
constructor(runtimeScene, behaviorData, owner) {
super(runtimeScene, behaviorData, owner);
this._relativeToOriginalWindowSize = !!behaviorData.relativeToOriginalWindowSize;
this._relativeToOriginalWindowSize =
!!behaviorData.relativeToOriginalWindowSize;
this._leftEdgeAnchor = behaviorData.leftEdgeAnchor;
this._rightEdgeAnchor = behaviorData.rightEdgeAnchor;
this._topEdgeAnchor = behaviorData.topEdgeAnchor;

View File

@@ -95,10 +95,11 @@ namespace gdjs {
}
updateFontFamily(): void {
this._pixiObject.textStyles.default.fontFamily = this._object._runtimeScene
.getGame()
.getFontManager()
.getFontFamily(this._object._fontFamily);
this._pixiObject.textStyles.default.fontFamily =
this._object._runtimeScene
.getGame()
.getFontManager()
.getFontFamily(this._object._fontFamily);
this._pixiObject.dirty = true;
}

View File

@@ -169,5 +169,6 @@ namespace gdjs {
return this._pixiObject.textHeight * this.getScale();
}
}
export const BitmapTextRuntimeObjectRenderer = BitmapTextRuntimeObjectPixiRenderer;
export const BitmapTextRuntimeObjectRenderer =
BitmapTextRuntimeObjectPixiRenderer;
}

View File

@@ -414,9 +414,8 @@ namespace gdjs {
return;
}
if (this.dialogueData.select) {
this.selectedOption = gdjs.dialogueTree._normalizedOptionIndex(
optionIndex
);
this.selectedOption =
gdjs.dialogueTree._normalizedOptionIndex(optionIndex);
this.selectedOptionUpdated = true;
}
};

View File

@@ -52,9 +52,8 @@ namespace gdjs {
const inputManager = runtimeScene.getGame().getInputManager();
//Try mouse
const mouseDraggableManager = DraggableManager.getMouseManager(
runtimeScene
);
const mouseDraggableManager =
DraggableManager.getMouseManager(runtimeScene);
if (
inputManager.isMouseButtonPressed(0) &&
!mouseDraggableManager.isDragging(this)
@@ -107,9 +106,8 @@ namespace gdjs {
}
doStepPostEvents(runtimeScene) {
const mouseDraggableManager = DraggableManager.getMouseManager(
runtimeScene
);
const mouseDraggableManager =
DraggableManager.getMouseManager(runtimeScene);
mouseDraggableManager.leftPressedLastFrame = runtimeScene
.getGame()
.getInputManager()
@@ -174,9 +172,8 @@ namespace gdjs {
if (!runtimeScene.touchDraggableManagers[touchId]) {
//Create the shared manager if necessary.
// @ts-ignore
runtimeScene.touchDraggableManagers[
touchId
] = new TouchDraggableManager(runtimeScene, touchId);
runtimeScene.touchDraggableManagers[touchId] =
new TouchDraggableManager(runtimeScene, touchId);
}
// @ts-ignore
return runtimeScene.touchDraggableManagers[touchId];

View File

@@ -6,7 +6,8 @@ namespace gdjs {
},
updatePreRender: function (filter, target) {},
updateDoubleParameter: function (filter, parameterName, value) {
const adjustmentFilter = (filter as unknown) as PIXI.filters.AdjustmentFilter;
const adjustmentFilter =
filter as unknown as PIXI.filters.AdjustmentFilter;
if (parameterName === 'gamma') {
adjustmentFilter.gamma = value;
} else if (parameterName === 'saturation') {

View File

@@ -6,7 +6,8 @@ namespace gdjs {
},
updatePreRender: function (filter, target) {},
updateDoubleParameter: function (filter, parameterName, value) {
const advancedBloomFilter = (filter as unknown) as PIXI.filters.AdvancedBloomFilter;
const advancedBloomFilter =
filter as unknown as PIXI.filters.AdvancedBloomFilter;
if (parameterName === 'threshold') {
advancedBloomFilter.threshold = value;
} else if (parameterName === 'bloomScale') {

View File

@@ -6,7 +6,7 @@ namespace gdjs {
},
updatePreRender: function (filter, target) {},
updateDoubleParameter: function (filter, parameterName, value) {
const asciiFilter = (filter as unknown) as PIXI.filters.AsciiFilter;
const asciiFilter = filter as unknown as PIXI.filters.AsciiFilter;
if (parameterName === 'size') {
asciiFilter.size = value;
}

View File

@@ -6,7 +6,7 @@ namespace gdjs {
},
updatePreRender: function (filter, target) {},
updateDoubleParameter: function (filter, parameterName, value) {
const bevelFilter = (filter as unknown) as PIXI.filters.BevelFilter;
const bevelFilter = filter as unknown as PIXI.filters.BevelFilter;
if (parameterName === 'rotation') {
bevelFilter.rotation = value;
} else if (parameterName === 'thickness') {
@@ -21,16 +21,14 @@ namespace gdjs {
}
},
updateStringParameter: function (filter, parameterName, value) {
const bevelFilter = (filter as unknown) as PIXI.filters.BevelFilter;
const bevelFilter = filter as unknown as PIXI.filters.BevelFilter;
if (parameterName === 'lightColor') {
bevelFilter.lightColor = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(
value
);
bevelFilter.lightColor =
gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value);
}
if (parameterName === 'shadowColor') {
bevelFilter.shadowColor = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(
value
);
bevelFilter.shadowColor =
gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value);
}
},
updateBooleanParameter: function (filter, parameterName, value) {},

View File

@@ -9,7 +9,7 @@ namespace gdjs {
updatePreRender: function (filter, target) {},
updateDoubleParameter: function (filter, parameterName, value) {
// @ts-ignore - unsure why PIXI.filters is not recognised.
const colorMatrix = (filter as unknown) as PIXI.filters.ColorMatrixFilter;
const colorMatrix = filter as unknown as PIXI.filters.ColorMatrixFilter;
if (parameterName !== 'opacity') {
return;
}

View File

@@ -8,7 +8,7 @@ namespace gdjs {
updatePreRender: function (filter, target) {},
updateDoubleParameter: function (filter, parameterName, value) {
// @ts-ignore - unsure why PIXI.filters is not recognised.
const blendingModeFilter = (filter as unknown) as PIXI.filters.AlphaFilter;
const blendingModeFilter = filter as unknown as PIXI.filters.AlphaFilter;
if (parameterName === 'alpha') {
blendingModeFilter.alpha = value;
} else if (parameterName === 'blendmode') {

View File

@@ -9,7 +9,8 @@ namespace gdjs {
updatePreRender: function (filter, target) {},
updateDoubleParameter: function (filter, parameterName, value) {
// @ts-ignore - unsure why PIXI.filters is not recognised.
const brightnessFilter = (filter as unknown) as PIXI.filters.ColorMatrixFilter;
const brightnessFilter =
filter as unknown as PIXI.filters.ColorMatrixFilter;
if (parameterName !== 'brightness') {
return;
}

View File

@@ -6,7 +6,8 @@ namespace gdjs {
},
updatePreRender: function (filter, target) {},
updateDoubleParameter: function (filter, parameterName, value) {
const bulgePinchFilter = (filter as unknown) as PIXI.filters.BulgePinchFilter;
const bulgePinchFilter =
filter as unknown as PIXI.filters.BulgePinchFilter;
if (parameterName === 'centerX') {
bulgePinchFilter.center[0] = value;
} else if (parameterName === 'centerY') {

View File

@@ -19,7 +19,7 @@ namespace gdjs {
},
updatePreRender: function (filter, target) {},
updateDoubleParameter: function (filter, parameterName, value) {
const colorMapFilter = (filter as unknown) as PIXI.filters.ColorMapFilter;
const colorMapFilter = filter as unknown as PIXI.filters.ColorMapFilter;
if (parameterName === 'mix') {
colorMapFilter.mix = gdjs.PixiFiltersTools.clampValue(
value / 100,
@@ -30,7 +30,7 @@ namespace gdjs {
},
updateStringParameter: function (filter, parameterName, value) {},
updateBooleanParameter: function (filter, parameterName, value) {
const colorMapFilter = (filter as unknown) as PIXI.filters.ColorMapFilter;
const colorMapFilter = filter as unknown as PIXI.filters.ColorMapFilter;
if (parameterName === 'nearest') {
colorMapFilter.nearest = value;
}

View File

@@ -6,21 +6,21 @@ namespace gdjs {
},
updatePreRender: function (filter, target) {},
updateDoubleParameter: function (filter, parameterName, value) {
const colorReplaceFilter = (filter as unknown) as PIXI.filters.ColorReplaceFilter;
const colorReplaceFilter =
filter as unknown as PIXI.filters.ColorReplaceFilter;
if (parameterName === 'epsilon') {
colorReplaceFilter.epsilon = value;
}
},
updateStringParameter: function (filter, parameterName, value) {
const colorReplaceFilter = (filter as unknown) as PIXI.filters.ColorReplaceFilter;
const colorReplaceFilter =
filter as unknown as PIXI.filters.ColorReplaceFilter;
if (parameterName === 'originalColor') {
colorReplaceFilter.originalColor = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(
value
);
colorReplaceFilter.originalColor =
gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value);
} else if (parameterName === 'newColor') {
colorReplaceFilter.newColor = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(
value
);
colorReplaceFilter.newColor =
gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value);
}
},
updateBooleanParameter: function (filter, parameterName, value) {},

View File

@@ -17,7 +17,8 @@ namespace gdjs {
updatePreRender: function (filter, target) {},
updateDoubleParameter: function (filter, parameterName, value) {
// @ts-ignore - unsure why PIXI.filters is not recognised.
const displacementFilter = (filter as unknown) as PIXI.filters.DisplacementFilter;
const displacementFilter =
filter as unknown as PIXI.filters.DisplacementFilter;
if (parameterName === 'scaleX') {
displacementFilter.scale.x = value;
}

View File

@@ -6,7 +6,7 @@ namespace gdjs {
},
updatePreRender: function (filter, target) {},
updateDoubleParameter: function (filter, parameterName, value) {
const dotFilter = (filter as unknown) as PIXI.filters.DotFilter;
const dotFilter = filter as unknown as PIXI.filters.DotFilter;
if (parameterName === 'scale') {
dotFilter.scale = value;
} else if (parameterName === 'angle') {

View File

@@ -6,7 +6,8 @@ namespace gdjs {
},
updatePreRender: function (filter, target) {},
updateDoubleParameter: function (filter, parameterName, value) {
const dropShadowFilter = (filter as unknown) as PIXI.filters.DropShadowFilter;
const dropShadowFilter =
filter as unknown as PIXI.filters.DropShadowFilter;
if (parameterName === 'blur') {
dropShadowFilter.blur = value;
} else if (parameterName === 'quality') {
@@ -22,15 +23,16 @@ namespace gdjs {
}
},
updateStringParameter: function (filter, parameterName, value) {
const dropShadowFilter = (filter as unknown) as PIXI.filters.DropShadowFilter;
const dropShadowFilter =
filter as unknown as PIXI.filters.DropShadowFilter;
if (parameterName === 'color') {
dropShadowFilter.color = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(
value
);
dropShadowFilter.color =
gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value);
}
},
updateBooleanParameter: function (filter, parameterName, value) {
const dropShadowFilter = (filter as unknown) as PIXI.filters.DropShadowFilter;
const dropShadowFilter =
filter as unknown as PIXI.filters.DropShadowFilter;
if (parameterName === 'shadowOnly') {
dropShadowFilter.shadowOnly = value;
}

View File

@@ -6,7 +6,7 @@ namespace gdjs {
},
updatePreRender: function (filter, target) {},
updateDoubleParameter: function (filter, parameterName, value) {
const glowFilter = (filter as unknown) as PIXI.filters.GlowFilter;
const glowFilter = filter as unknown as PIXI.filters.GlowFilter;
if (parameterName === 'innerStrength') {
glowFilter.innerStrength = value;
} else if (parameterName === 'outerStrength') {
@@ -17,7 +17,7 @@ namespace gdjs {
}
},
updateStringParameter: function (filter, parameterName, value) {
const glowFilter = (filter as unknown) as PIXI.filters.GlowFilter;
const glowFilter = filter as unknown as PIXI.filters.GlowFilter;
if (parameterName === 'color') {
glowFilter.color = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value);
}

View File

@@ -6,7 +6,8 @@ namespace gdjs {
},
updatePreRender: function (filter, target) {},
updateDoubleParameter: function (filter, parameterName, value) {
const kawaseBlurFilter = (filter as unknown) as PIXI.filters.KawaseBlurFilter;
const kawaseBlurFilter =
filter as unknown as PIXI.filters.KawaseBlurFilter;
if (parameterName === 'pixelizeX') {
// @ts-ignore: fix these wrong parameters
kawaseBlurFilter.pixelizeX = value;

View File

@@ -8,7 +8,7 @@ namespace gdjs {
updatePreRender: function (filter, target) {},
updateDoubleParameter: function (filter, parameterName, value) {
// @ts-ignore - unsure why PIXI.filters is not recognised.
const noiseFilter = (filter as unknown) as PIXI.filters.NoiseFilter;
const noiseFilter = filter as unknown as PIXI.filters.NoiseFilter;
if (parameterName !== 'noise') {
return;
}

View File

@@ -6,7 +6,7 @@ namespace gdjs {
},
updatePreRender: function (filter, target) {},
updateDoubleParameter: function (filter, parameterName, value) {
const outlineFilter = (filter as unknown) as PIXI.filters.OutlineFilter;
const outlineFilter = filter as unknown as PIXI.filters.OutlineFilter;
if (parameterName === 'thickness') {
outlineFilter.thickness = value;
} else if (parameterName === 'padding') {
@@ -14,7 +14,7 @@ namespace gdjs {
}
},
updateStringParameter: function (filter, parameterName, value) {
const outlineFilter = (filter as unknown) as PIXI.filters.OutlineFilter;
const outlineFilter = filter as unknown as PIXI.filters.OutlineFilter;
if (parameterName === 'color') {
outlineFilter.color = gdjs.PixiFiltersTools.rgbOrHexToHexNumber(value);
}

View File

@@ -8,7 +8,7 @@ namespace gdjs {
},
updatePreRender: function (filter, target) {},
updateDoubleParameter: function (filter, parameterName, value) {
const pixelateFilter = (filter as unknown) as PIXI.filters.PixelateFilter;
const pixelateFilter = filter as unknown as PIXI.filters.PixelateFilter;
if (parameterName === 'size') {
pixelateFilter.size = value;
}

View File

@@ -5,7 +5,8 @@ namespace gdjs {
return radialBlurFilter;
},
updatePreRender: function (filter, target) {
const radialBlurFilter = (filter as unknown) as PIXI.filters.RadialBlurFilter;
const radialBlurFilter =
filter as unknown as PIXI.filters.RadialBlurFilter;
radialBlurFilter.center[0] = Math.round(
// @ts-ignore - extra properties are stored on the filter.
radialBlurFilter._centerX * target.getWidth()
@@ -16,7 +17,8 @@ namespace gdjs {
);
},
updateDoubleParameter: function (filter, parameterName, value) {
const radialBlurFilter = (filter as unknown) as PIXI.filters.RadialBlurFilter;
const radialBlurFilter =
filter as unknown as PIXI.filters.RadialBlurFilter;
if (parameterName === 'radius') {
radialBlurFilter.radius = value < 0 ? -1 : value;
} else if (parameterName === 'angle') {

View File

@@ -6,7 +6,7 @@ namespace gdjs {
},
updatePreRender: function (filter, target) {},
updateDoubleParameter: function (filter, parameterName, value) {
const rgbSplitFilter = (filter as unknown) as PIXI.filters.RGBSplitFilter;
const rgbSplitFilter = filter as unknown as PIXI.filters.RGBSplitFilter;
if (parameterName === 'redX') {
rgbSplitFilter.red.x = value;
} else if (parameterName === 'redY') {

View File

@@ -9,7 +9,8 @@ namespace gdjs {
updatePreRender: function (filter, target) {},
updateDoubleParameter: function (filter, parameterName, value) {
// @ts-ignore - unsure why PIXI.filters is not recognised.
const colorMatrixFilter = (filter as unknown) as PIXI.filters.ColorMatrixFilter;
const colorMatrixFilter =
filter as unknown as PIXI.filters.ColorMatrixFilter;
if (parameterName !== 'opacity') {
return;
}

View File

@@ -6,7 +6,7 @@ namespace gdjs {
},
updatePreRender: function (filter, target) {},
updateDoubleParameter: function (filter, parameterName, value) {
const tiltShiftFilter = (filter as unknown) as PIXI.filters.TiltShiftFilter;
const tiltShiftFilter = filter as unknown as PIXI.filters.TiltShiftFilter;
if (parameterName === 'blur') {
tiltShiftFilter.blur = value;
} else if (parameterName === 'gradientBlur') {

View File

@@ -11,7 +11,7 @@ namespace gdjs {
return twistFilter;
},
updatePreRender: function (filter, target) {
const twistFilter = (filter as unknown) as PIXI.filters.TwistFilter;
const twistFilter = filter as unknown as PIXI.filters.TwistFilter;
twistFilter.offset.x = Math.round(
// @ts-ignore - extra properties are stored on the filter.
twistFilter._offsetX * target.getWidth()
@@ -22,7 +22,7 @@ namespace gdjs {
);
},
updateDoubleParameter: function (filter, parameterName, value) {
const twistFilter = (filter as unknown) as PIXI.filters.TwistFilter;
const twistFilter = filter as unknown as PIXI.filters.TwistFilter;
if (parameterName === 'radius') {
twistFilter.radius = value;
} else if (parameterName === 'angle') {

View File

@@ -5,7 +5,7 @@ namespace gdjs {
return zoomBlurFilter;
},
updatePreRender: function (filter, target) {
const zoomBlurFilter = (filter as unknown) as PIXI.filters.ZoomBlurFilter;
const zoomBlurFilter = filter as unknown as PIXI.filters.ZoomBlurFilter;
zoomBlurFilter.center[0] = Math.round(
// @ts-ignore - extra properties are stored on the filter.
zoomBlurFilter._centerX * target.getWidth()
@@ -16,7 +16,7 @@ namespace gdjs {
);
},
updateDoubleParameter: function (filter, parameterName, value) {
const zoomBlurFilter = (filter as unknown) as PIXI.filters.ZoomBlurFilter;
const zoomBlurFilter = filter as unknown as PIXI.filters.ZoomBlurFilter;
if (parameterName === 'centerX') {
// @ts-ignore - extra properties are stored on the filter.
zoomBlurFilter._centerX = value;

View File

@@ -49,12 +49,12 @@ namespace gdjs {
// `effectData.booleanParameters.someBoolean`
logger.info(
'The PIXI texture found for the Dummy Effect (not actually used):',
(layer
.getRuntimeScene()
.getGame()
.getImageManager() as gdjs.PixiImageManager).getPIXITexture(
effectData.stringParameters.someImage
)
(
layer
.getRuntimeScene()
.getGame()
.getImageManager() as gdjs.PixiImageManager
).getPIXITexture(effectData.stringParameters.someImage)
);
return filter;
},

View File

@@ -148,17 +148,22 @@ namespace gdjs {
gdjs.evtTools.facebookInstantGames._preloadedInterstitialLoading = true;
FBInstant.getInterstitialAdAsync(adPlacementId)
.then(function (interstitial) {
gdjs.evtTools.facebookInstantGames._preloadedInterstitial = interstitial;
gdjs.evtTools.facebookInstantGames._preloadedInterstitial =
interstitial;
return interstitial.loadAsync();
})
.then(function () {
gdjs.evtTools.facebookInstantGames._preloadedInterstitialLoading = false;
gdjs.evtTools.facebookInstantGames._preloadedInterstitialLoaded = true;
gdjs.evtTools.facebookInstantGames._preloadedInterstitialLoading =
false;
gdjs.evtTools.facebookInstantGames._preloadedInterstitialLoaded =
true;
logger.info('Facebook Instant Games interstitial preloaded.');
})
.catch(function (err) {
gdjs.evtTools.facebookInstantGames._preloadedInterstitialLoading = false;
gdjs.evtTools.facebookInstantGames._preloadedInterstitialLoaded = false;
gdjs.evtTools.facebookInstantGames._preloadedInterstitialLoading =
false;
gdjs.evtTools.facebookInstantGames._preloadedInterstitialLoaded =
false;
logger.error('Interstitial failed to preload: ' + err.message);
errorVariable.setString(err.message || 'Unknown error');
});
@@ -181,7 +186,8 @@ namespace gdjs {
errorVariable.setString(err.message || 'Unknown error');
})
.then(function () {
gdjs.evtTools.facebookInstantGames._preloadedInterstitialLoaded = false;
gdjs.evtTools.facebookInstantGames._preloadedInterstitialLoaded =
false;
});
};
@@ -199,20 +205,26 @@ namespace gdjs {
) {
return;
}
gdjs.evtTools.facebookInstantGames._preloadedRewardedVideoLoading = true;
gdjs.evtTools.facebookInstantGames._preloadedRewardedVideoLoading =
true;
FBInstant.getRewardedVideoAsync(adPlacementId)
.then(function (rewardedVideo) {
gdjs.evtTools.facebookInstantGames._preloadedRewardedVideo = rewardedVideo;
gdjs.evtTools.facebookInstantGames._preloadedRewardedVideo =
rewardedVideo;
return rewardedVideo.loadAsync();
})
.then(function () {
gdjs.evtTools.facebookInstantGames._preloadedRewardedVideoLoading = false;
gdjs.evtTools.facebookInstantGames._preloadedRewardedVideoLoaded = true;
gdjs.evtTools.facebookInstantGames._preloadedRewardedVideoLoading =
false;
gdjs.evtTools.facebookInstantGames._preloadedRewardedVideoLoaded =
true;
logger.info('Facebook Instant Games rewarded video preloaded.');
})
.catch(function (err) {
gdjs.evtTools.facebookInstantGames._preloadedRewardedVideoLoading = false;
gdjs.evtTools.facebookInstantGames._preloadedRewardedVideoLoaded = false;
gdjs.evtTools.facebookInstantGames._preloadedRewardedVideoLoading =
false;
gdjs.evtTools.facebookInstantGames._preloadedRewardedVideoLoaded =
false;
logger.error('Rewarded video failed to preload: ' + err.message);
errorVariable.setString(err.message || 'Unknown error');
});
@@ -235,7 +247,8 @@ namespace gdjs {
errorVariable.setString(err.message || 'Unknown error');
})
.then(function () {
gdjs.evtTools.facebookInstantGames._preloadedRewardedVideoLoaded = false;
gdjs.evtTools.facebookInstantGames._preloadedRewardedVideoLoaded =
false;
});
};

View File

@@ -4303,7 +4303,8 @@ declare namespace firebase.auth {
* @hidden
*/
class RecaptchaVerifier_Instance
implements firebase.auth.ApplicationVerifier {
implements firebase.auth.ApplicationVerifier
{
constructor(
container: any | string,
parameters?: Object | null,
@@ -9255,9 +9256,9 @@ declare namespace firebase.firestore {
* `exists` property will always be true and `data()` will never return
* 'undefined'.
*/
export class QueryDocumentSnapshot<T = DocumentData> extends DocumentSnapshot<
T
> {
export class QueryDocumentSnapshot<
T = DocumentData
> extends DocumentSnapshot<T> {
private constructor();
/**

View File

@@ -10,7 +10,8 @@ namespace gdjs {
* Set the interval between auto-config updates.
*/
export const setAutoUpdateInterval = (interval: integer) => {
firebase.remoteConfig().settings.minimumFetchIntervalMillis = interval;
firebase.remoteConfig().settings.minimumFetchIntervalMillis =
interval;
};
/**

View File

@@ -518,9 +518,9 @@ describeIfOnline('Firebase extension end-to-end tests', function () {
// Delete the temporary namespace to not bloat the DB
after(async () =>
(
await firebase.firestore().collection(namespace).get()
).forEach(({ ref }) => ref.delete())
(await firebase.firestore().collection(namespace).get()).forEach(
({ ref }) => ref.delete()
)
);
});

View File

@@ -552,9 +552,8 @@ namespace gdjs {
resetLeaderboardDisplayErrorTimeout(runtimeScene);
_leaderboardViewIframe = computeLeaderboardDisplayingIframe(
targetUrl
);
_leaderboardViewIframe =
computeLeaderboardDisplayingIframe(targetUrl);
if (typeof window !== 'undefined') {
_leaderboardViewClosingCallback = (event: MessageEvent) => {
receiveMessageFromLeaderboardView(

View File

@@ -70,9 +70,8 @@ namespace gdjs {
searchArea.maxX = x + radius;
// @ts-ignore
searchArea.maxY = y + radius;
const nearbyObstacles: gdjs.BehaviorRBushAABB<
gdjs.LightObstacleRuntimeBehavior
>[] = this._obstacleRBush.search(searchArea);
const nearbyObstacles: gdjs.BehaviorRBushAABB<gdjs.LightObstacleRuntimeBehavior>[] =
this._obstacleRBush.search(searchArea);
result.length = 0;
nearbyObstacles.forEach((nearbyObstacle) =>
result.push(nearbyObstacle.behavior)
@@ -85,9 +84,8 @@ namespace gdjs {
_oldY: float = 0;
_oldWidth: float = 0;
_oldHeight: float = 0;
currentRBushAABB: gdjs.BehaviorRBushAABB<
LightObstacleRuntimeBehavior
> | null = null;
currentRBushAABB: gdjs.BehaviorRBushAABB<LightObstacleRuntimeBehavior> | null =
null;
_manager: any;
_registeredInManager: boolean = false;

View File

@@ -198,11 +198,11 @@ namespace gdjs {
const texture = this._object.getTexture();
this._texture =
texture !== ''
? (this._runtimeScene
.getGame()
.getImageManager() as gdjs.PixiImageManager).getPIXITexture(
texture
)
? (
this._runtimeScene
.getGame()
.getImageManager() as gdjs.PixiImageManager
).getPIXITexture(texture)
: null;
}
@@ -467,35 +467,38 @@ namespace gdjs {
const xdiff = flattenVertices[i][0] - this._object.x;
const ydiff = flattenVertices[i][1] - this._object.y;
const angle = Math.atan2(ydiff, xdiff);
const closestVertex = LightRuntimeObjectPixiRenderer._computeClosestIntersectionPoint(
this._object,
angle,
obstaclePolygons,
boundingSquareHalfDiag
);
const closestVertex =
LightRuntimeObjectPixiRenderer._computeClosestIntersectionPoint(
this._object,
angle,
obstaclePolygons,
boundingSquareHalfDiag
);
if (closestVertex) {
closestVertices.push({ vertex: closestVertex, angle: angle });
}
// TODO: Check whether we need to raycast these two extra rays or not.
const closestVertexOffsetLeft = LightRuntimeObjectPixiRenderer._computeClosestIntersectionPoint(
this._object,
angle + 0.0001,
obstaclePolygons,
boundingSquareHalfDiag
);
const closestVertexOffsetLeft =
LightRuntimeObjectPixiRenderer._computeClosestIntersectionPoint(
this._object,
angle + 0.0001,
obstaclePolygons,
boundingSquareHalfDiag
);
if (closestVertexOffsetLeft) {
closestVertices.push({
vertex: closestVertexOffsetLeft,
angle: angle + 0.0001,
});
}
const closestVertexOffsetRight = LightRuntimeObjectPixiRenderer._computeClosestIntersectionPoint(
this._object,
angle - 0.0001,
obstaclePolygons,
boundingSquareHalfDiag
);
const closestVertexOffsetRight =
LightRuntimeObjectPixiRenderer._computeClosestIntersectionPoint(
this._object,
angle - 0.0001,
obstaclePolygons,
boundingSquareHalfDiag
);
if (closestVertexOffsetRight) {
closestVertices.push({
vertex: closestVertexOffsetRight,

View File

@@ -39,9 +39,8 @@ namespace gdjs {
this._color = gdjs.rgbOrHexToRGBColor(lightObjectData.content.color);
this._debugMode = lightObjectData.content.debugMode;
this._texture = lightObjectData.content.texture;
this._obstaclesManager = gdjs.LightObstaclesManager.getManager(
runtimeScene
);
this._obstaclesManager =
gdjs.LightObstaclesManager.getManager(runtimeScene);
this._renderer = new gdjs.LightRuntimeObjectRenderer(this, runtimeScene);
this._runtimeScene = runtimeScene;

View File

@@ -229,9 +229,8 @@ namespace gdjs {
if (obj === null) {
return false;
}
const linkedObjectMap = LinksManager.getManager(
runtimeScene
)._getMapOfObjectsLinkedWith(obj);
const linkedObjectMap =
LinksManager.getManager(runtimeScene)._getMapOfObjectsLinkedWith(obj);
let pickedSomething = false;
for (const contextObjectName in objectsLists.items) {

View File

@@ -25,11 +25,9 @@ namespace gdjs {
tiled: boolean
) {
this._object = runtimeObject;
const texture = (runtimeScene
.getGame()
.getImageManager() as gdjs.PixiImageManager).getPIXITexture(
textureName
);
const texture = (
runtimeScene.getGame().getImageManager() as gdjs.PixiImageManager
).getPIXITexture(textureName);
const StretchedSprite = !tiled ? PIXI.Sprite : PIXI.TilingSprite;
this._spritesContainer = new PIXI.Container();
this._wrapperContainer = new PIXI.Container();
@@ -384,6 +382,8 @@ namespace gdjs {
}
}
export const PanelSpriteRuntimeObjectRenderer = PanelSpriteRuntimeObjectPixiRenderer;
export type PanelSpriteRuntimeObjectRenderer = PanelSpriteRuntimeObjectPixiRenderer;
export const PanelSpriteRuntimeObjectRenderer =
PanelSpriteRuntimeObjectPixiRenderer;
export type PanelSpriteRuntimeObjectRenderer =
PanelSpriteRuntimeObjectPixiRenderer;
}

View File

@@ -40,11 +40,9 @@ namespace gdjs {
);
} else if (objectData.textureParticleName) {
const sprite = new PIXI.Sprite(
(runtimeScene
.getGame()
.getImageManager() as gdjs.PixiImageManager).getPIXITexture(
objectData.textureParticleName
)
(
runtimeScene.getGame().getImageManager() as gdjs.PixiImageManager
).getPIXITexture(objectData.textureParticleName)
);
sprite.width = objectData.rendererParam1;
sprite.height = objectData.rendererParam2;
@@ -251,10 +249,8 @@ namespace gdjs {
setFlow(flow: number, tank: number): void {
this.emitter.frequency = flow < 0 ? 0.0001 : 1.0 / flow;
this.emitter.emitterLifetime = ParticleEmitterObjectPixiRenderer.computeLifetime(
flow,
tank
);
this.emitter.emitterLifetime =
ParticleEmitterObjectPixiRenderer.computeLifetime(flow, tank);
}
resetEmission(flow: number, tank: number): void {
@@ -326,6 +322,7 @@ namespace gdjs {
}
// @ts-ignore - Register the class to let the engine use it.
export const ParticleEmitterObjectRenderer = ParticleEmitterObjectPixiRenderer;
export const ParticleEmitterObjectRenderer =
ParticleEmitterObjectPixiRenderer;
export type ParticleEmitterObjectRenderer = ParticleEmitterObjectPixiRenderer;
}

View File

@@ -274,9 +274,21 @@ namespace gdjs {
// Consider every state dirty as the renderer was just re-created, so it needs
// to be repositioned, angle updated, etc...
this._posDirty = this._angleDirty = this._forceDirty = this._zoneRadiusDirty = true;
this._lifeTimeDirty = this._gravityDirty = this._colorDirty = this._sizeDirty = true;
this._alphaDirty = this._flowDirty = this._tankDirty = this._textureDirty = true;
this._posDirty =
this._angleDirty =
this._forceDirty =
this._zoneRadiusDirty =
true;
this._lifeTimeDirty =
this._gravityDirty =
this._colorDirty =
this._sizeDirty =
true;
this._alphaDirty =
this._flowDirty =
this._tankDirty =
this._textureDirty =
true;
}
return true;
}
@@ -326,9 +338,21 @@ namespace gdjs {
if (this._textureDirty) {
this._renderer.setTextureName(this.texture, runtimeScene);
}
this._posDirty = this._angleDirty = this._forceDirty = this._zoneRadiusDirty = false;
this._lifeTimeDirty = this._gravityDirty = this._colorDirty = this._sizeDirty = false;
this._alphaDirty = this._flowDirty = this._textureDirty = this._tankDirty = false;
this._posDirty =
this._angleDirty =
this._forceDirty =
this._zoneRadiusDirty =
false;
this._lifeTimeDirty =
this._gravityDirty =
this._colorDirty =
this._sizeDirty =
false;
this._alphaDirty =
this._flowDirty =
this._textureDirty =
this._tankDirty =
false;
this._renderer.update(this.getElapsedTime(runtimeScene) / 1000.0);
if (
this._renderer.hasStarted() &&

View File

@@ -28,9 +28,8 @@ namespace gdjs {
static getManager(runtimeScene) {
if (!runtimeScene.pathfindingObstaclesManager) {
//Create the shared manager if necessary.
runtimeScene.pathfindingObstaclesManager = new gdjs.PathfindingObstaclesManager(
runtimeScene
);
runtimeScene.pathfindingObstaclesManager =
new gdjs.PathfindingObstaclesManager(runtimeScene);
}
return runtimeScene.pathfindingObstaclesManager;
}
@@ -44,9 +43,8 @@ namespace gdjs {
if (pathfindingObstacleBehavior.currentRBushAABB)
pathfindingObstacleBehavior.currentRBushAABB.updateAABBFromOwner();
else
pathfindingObstacleBehavior.currentRBushAABB = new gdjs.BehaviorRBushAABB(
pathfindingObstacleBehavior
);
pathfindingObstacleBehavior.currentRBushAABB =
new gdjs.BehaviorRBushAABB(pathfindingObstacleBehavior);
this._obstaclesRBush.insert(pathfindingObstacleBehavior.currentRBushAABB);
}
@@ -83,9 +81,8 @@ namespace gdjs {
searchArea.maxX = x + radius;
// @ts-ignore
searchArea.maxY = y + radius;
const nearbyObstacles: gdjs.BehaviorRBushAABB<
gdjs.PathfindingObstacleRuntimeBehavior
>[] = this._obstaclesRBush.search(searchArea);
const nearbyObstacles: gdjs.BehaviorRBushAABB<gdjs.PathfindingObstacleRuntimeBehavior>[] =
this._obstaclesRBush.search(searchArea);
result.length = 0;
nearbyObstacles.forEach((nearbyObstacle) =>
result.push(nearbyObstacle.behavior)
@@ -106,9 +103,8 @@ namespace gdjs {
_oldHeight: float = 0;
_manager: PathfindingObstaclesManager;
_registeredInManager: boolean = false;
currentRBushAABB: gdjs.BehaviorRBushAABB<
PathfindingObstacleRuntimeBehavior
> | null = null;
currentRBushAABB: gdjs.BehaviorRBushAABB<PathfindingObstacleRuntimeBehavior> | null =
null;
constructor(
runtimeScene: gdjs.RuntimeScene,

View File

@@ -47,10 +47,12 @@ namespace gdjs {
}
// Get associated behaviors
const behaviorA = contact.GetFixtureA().GetBody()
.gdjsAssociatedBehavior;
const behaviorB = contact.GetFixtureB().GetBody()
.gdjsAssociatedBehavior;
const behaviorA = contact
.GetFixtureA()
.GetBody().gdjsAssociatedBehavior;
const behaviorB = contact
.GetFixtureB()
.GetBody().gdjsAssociatedBehavior;
// Let each behavior know about the contact against the other
behaviorA.currentContacts.push(behaviorB);
@@ -69,10 +71,12 @@ namespace gdjs {
}
// Get associated behaviors
const behaviorA = contact.GetFixtureA().GetBody()
.gdjsAssociatedBehavior;
const behaviorB = contact.GetFixtureB().GetBody()
.gdjsAssociatedBehavior;
const behaviorA = contact
.GetFixtureA()
.GetBody().gdjsAssociatedBehavior;
const behaviorB = contact
.GetFixtureB()
.GetBody().gdjsAssociatedBehavior;
// Remove each other contact
let i = behaviorA.currentContacts.indexOf(behaviorB);
@@ -93,9 +97,8 @@ namespace gdjs {
static getSharedData(runtimeScene, behaviorName) {
// Create one if needed
if (!runtimeScene.physics2SharedData) {
const initialData = runtimeScene.getInitialSharedDataForBehavior(
behaviorName
);
const initialData =
runtimeScene.getInitialSharedDataForBehavior(behaviorName);
runtimeScene.physics2SharedData = new gdjs.Physics2SharedData(
runtimeScene,
initialData

View File

@@ -48,8 +48,9 @@ namespace gdjs {
) {
return;
}
const behaviorA = contact.GetFixtureA().GetBody()
.gdjsAssociatedBehavior,
const behaviorA = contact
.GetFixtureA()
.GetBody().gdjsAssociatedBehavior,
behaviorB = contact.GetFixtureB().GetBody().gdjsAssociatedBehavior;
behaviorA.currentContacts.push(behaviorB);
behaviorB.currentContacts.push(behaviorA);
@@ -68,8 +69,9 @@ namespace gdjs {
) {
return;
}
const behaviorA = contact.GetFixtureA().GetBody()
.gdjsAssociatedBehavior,
const behaviorA = contact
.GetFixtureA()
.GetBody().gdjsAssociatedBehavior,
behaviorB = contact.GetFixtureB().GetBody().gdjsAssociatedBehavior;
let i = behaviorA.currentContacts.indexOf(behaviorB);
if (i !== -1) {

View File

@@ -541,9 +541,10 @@ namespace gdjs {
? -this._xGrabTolerance
: this._xGrabTolerance)
);
const collidingPlatforms: gdjs.PlatformRuntimeBehavior[] = gdjs.staticArray(
PlatformerObjectRuntimeBehavior.prototype._checkGrabPlatform
);
const collidingPlatforms: gdjs.PlatformRuntimeBehavior[] =
gdjs.staticArray(
PlatformerObjectRuntimeBehavior.prototype._checkGrabPlatform
);
collidingPlatforms.length = 0;
for (const platform of this._potentialCollidingObjects) {
if (this._isCollidingWith(platform) && this._canGrab(platform)) {
@@ -1749,14 +1750,12 @@ namespace gdjs {
const deltaMaxY = Math.abs(
behavior._requestedDeltaX * behavior._slopeClimbingFactor
);
const {
highestGround,
isCollidingAnyPlatform,
} = behavior._findHighestFloorAndMoveOnTop(
behavior._potentialCollidingObjects,
-deltaMaxY,
deltaMaxY
);
const { highestGround, isCollidingAnyPlatform } =
behavior._findHighestFloorAndMoveOnTop(
behavior._potentialCollidingObjects,
-deltaMaxY,
deltaMaxY
);
if (highestGround && highestGround !== this._floorPlatform) {
behavior._setOnFloor(highestGround);
}
@@ -1804,14 +1803,13 @@ namespace gdjs {
// 1. Try to move 1 pixel on the X axis to climb the junction.
object.setX(object.getX() + Math.sign(requestedDeltaX));
const {
highestGround: highestGroundAtJunction,
} = behavior._findHighestFloorAndMoveOnTop(
behavior._potentialCollidingObjects,
// Look up from at least 1 pixel to bypass not perfectly aligned floors.
Math.min(-1, -1 * behavior._slopeClimbingFactor),
0
);
const { highestGround: highestGroundAtJunction } =
behavior._findHighestFloorAndMoveOnTop(
behavior._potentialCollidingObjects,
// Look up from at least 1 pixel to bypass not perfectly aligned floors.
Math.min(-1, -1 * behavior._slopeClimbingFactor),
0
);
if (highestGroundAtJunction) {
// The obstacle 1st pixel can be climbed.
// Now that the character is on the obstacle,
@@ -1824,14 +1822,13 @@ namespace gdjs {
Math.abs(remainingDeltaX) - 1
);
object.setX(object.getX() + deltaX);
const {
highestGround: highestGroundOnObstacle,
} = behavior._findHighestFloorAndMoveOnTop(
behavior._potentialCollidingObjects,
// Do an exact slope angle check.
-Math.abs(deltaX) * behavior._slopeClimbingFactor,
0
);
const { highestGround: highestGroundOnObstacle } =
behavior._findHighestFloorAndMoveOnTop(
behavior._potentialCollidingObjects,
// Do an exact slope angle check.
-Math.abs(deltaX) * behavior._slopeClimbingFactor,
0
);
if (highestGroundOnObstacle) {
// The obstacle slope can be climbed.
if (Math.abs(remainingDeltaX) >= 2) {
@@ -1840,18 +1837,17 @@ namespace gdjs {
// We went too far in order to check that.
// Now, find the right position on the obstacles.
object.setPosition(oldX + requestedDeltaX, beforeObstacleY);
const {
highestGround: highestGroundOnObstacle,
} = behavior._findHighestFloorAndMoveOnTop(
behavior._potentialCollidingObjects,
// requestedDeltaX can be small when the object start moving.
// So, look up from at least 1 pixel to bypass not perfectly aligned floors.
Math.min(
-1,
-Math.abs(remainingDeltaX) * behavior._slopeClimbingFactor
),
0
);
const { highestGround: highestGroundOnObstacle } =
behavior._findHighestFloorAndMoveOnTop(
behavior._potentialCollidingObjects,
// requestedDeltaX can be small when the object start moving.
// So, look up from at least 1 pixel to bypass not perfectly aligned floors.
Math.min(
-1,
-Math.abs(remainingDeltaX) * behavior._slopeClimbingFactor
),
0
);
// Should always be true
if (highestGroundOnObstacle) {
behavior._setOnFloor(highestGroundOnObstacle);
@@ -2194,7 +2190,8 @@ namespace gdjs {
* A context used to search for a floor.
*/
class FollowConstraintContext {
static readonly instance: FollowConstraintContext = new FollowConstraintContext();
static readonly instance: FollowConstraintContext =
new FollowConstraintContext();
/**
* Character right side
*

View File

@@ -82,9 +82,8 @@ namespace gdjs {
searchArea.minY = y - oh / 2 - maxMovementLength;
searchArea.maxX = x + ow / 2 + maxMovementLength;
searchArea.maxY = y + oh / 2 + maxMovementLength;
const nearbyPlatforms: gdjs.BehaviorRBushAABB<
PlatformRuntimeBehavior
>[] = this._platformRBush.search(searchArea);
const nearbyPlatforms: gdjs.BehaviorRBushAABB<PlatformRuntimeBehavior>[] =
this._platformRBush.search(searchArea);
result.length = 0;
@@ -125,9 +124,8 @@ namespace gdjs {
_oldWidth: float = 0;
_oldHeight: float = 0;
_oldAngle: float = 0;
currentRBushAABB: gdjs.BehaviorRBushAABB<
PlatformRuntimeBehavior
> | null = null;
currentRBushAABB: gdjs.BehaviorRBushAABB<PlatformRuntimeBehavior> | null =
null;
_manager: gdjs.PlatformObjectsManager;
_registeredInManager: boolean = false;

View File

@@ -302,9 +302,8 @@ describe(`gdjs.PlatformerObjectRuntimeBehavior.findHighestFloorAndMoveOnTop`, fu
platform.setCustomWidthAndHeight(300, 300);
platform.setPosition(position[0], position[1]);
const platformBehavior = platform.getBehavior('Platform');
const platformObstaclesManager = gdjs.PlatformObjectsManager.getManager(
runtimeScene
);
const platformObstaclesManager =
gdjs.PlatformObjectsManager.getManager(runtimeScene);
platformObstaclesManager.addPlatform(platformBehavior);
it('can detect a platform away downward', function () {
@@ -374,9 +373,8 @@ describe(`gdjs.PlatformerObjectRuntimeBehavior.findHighestFloorAndMoveOnTop`, fu
platform.setCustomWidthAndHeight(300, 300);
platform.setPosition(position[0], position[1]);
const platformBehavior = platform.getBehavior('Platform');
const platformObstaclesManager = gdjs.PlatformObjectsManager.getManager(
runtimeScene
);
const platformObstaclesManager =
gdjs.PlatformObjectsManager.getManager(runtimeScene);
platformObstaclesManager.addPlatform(platformBehavior);
it('can detect an obstacle overlapping the top', function () {
@@ -404,9 +402,8 @@ describe(`gdjs.PlatformerObjectRuntimeBehavior.findHighestFloorAndMoveOnTop`, fu
platform.setCustomWidthAndHeight(200, 200);
platform.setPosition(250, -250);
const platformBehavior = platform.getBehavior('Platform');
const platformObstaclesManager = gdjs.PlatformObjectsManager.getManager(
runtimeScene
);
const platformObstaclesManager =
gdjs.PlatformObjectsManager.getManager(runtimeScene);
platformObstaclesManager.addPlatform(platformBehavior);
it('can detect a tunnel ceiling', function () {
@@ -458,9 +455,8 @@ describe(`gdjs.PlatformerObjectRuntimeBehavior.findHighestFloorAndMoveOnTop`, fu
collisionMasks.verticalTunnel
);
const platformBehavior = platform.getBehavior('Platform');
const platformObstaclesManager = gdjs.PlatformObjectsManager.getManager(
runtimeScene
);
const platformObstaclesManager =
gdjs.PlatformObjectsManager.getManager(runtimeScene);
platformObstaclesManager.addPlatform(platformBehavior);
it('can fell inside a vertical tunnel that fit the character', function () {
@@ -495,9 +491,8 @@ describe(`gdjs.PlatformerObjectRuntimeBehavior.findHighestFloorAndMoveOnTop`, fu
const platform = addPlatform(runtimeScene, collisionMasks.square);
const platformBehavior = platform.getBehavior('Platform');
const platformObstaclesManager = gdjs.PlatformObjectsManager.getManager(
runtimeScene
);
const platformObstaclesManager =
gdjs.PlatformObjectsManager.getManager(runtimeScene);
platformObstaclesManager.addPlatform(platformBehavior);
it('can detect a platform at its exact position', function () {

View File

@@ -487,6 +487,8 @@ namespace gdjs {
}
}
export const ShapePainterRuntimeObjectRenderer = ShapePainterRuntimeObjectPixiRenderer;
export type ShapePainterRuntimeObjectRenderer = ShapePainterRuntimeObjectPixiRenderer;
export const ShapePainterRuntimeObjectRenderer =
ShapePainterRuntimeObjectPixiRenderer;
export type ShapePainterRuntimeObjectRenderer =
ShapePainterRuntimeObjectPixiRenderer;
}

View File

@@ -752,8 +752,8 @@ namespace gdjs {
const centerY = this.getCenterY();
const vertices = this.hitBoxes[0].vertices;
if (this._customCollisionMask) {
const customCollisionMaskVertices = this._customCollisionMask[0]
.vertices;
const customCollisionMaskVertices =
this._customCollisionMask[0].vertices;
for (let i = 0; i < 4; i++) {
const point = this.transformToScene(
customCollisionMaskVertices[i][0],

View File

@@ -75,6 +75,8 @@ namespace gdjs {
}
}
export const TextEntryRuntimeObjectRenderer = TextEntryRuntimeObjectPixiRenderer;
export type TextEntryRuntimeObjectRenderer = TextEntryRuntimeObjectPixiRenderer;
export const TextEntryRuntimeObjectRenderer =
TextEntryRuntimeObjectPixiRenderer;
export type TextEntryRuntimeObjectRenderer =
TextEntryRuntimeObjectPixiRenderer;
}

View File

@@ -83,11 +83,8 @@ describe('gdjs.TextInputRuntimeObject (using a PixiJS RuntimeGame with DOM eleme
};
it('creates the DOM element', async () => {
const {
runtimeScene,
gameDomElementContainer,
object,
} = await setupObjectAndGetDomElementContainer();
const { runtimeScene, gameDomElementContainer, object } =
await setupObjectAndGetDomElementContainer();
// Check the default size.
expect(object.getWidth()).to.be(300);
@@ -108,11 +105,8 @@ describe('gdjs.TextInputRuntimeObject (using a PixiJS RuntimeGame with DOM eleme
});
it('destroys the DOM element when the scene is paused/resumed/stopped', async () => {
const {
runtimeScene,
gameDomElementContainer,
object,
} = await setupObjectAndGetDomElementContainer();
const { runtimeScene, gameDomElementContainer, object } =
await setupObjectAndGetDomElementContainer();
expect(gameDomElementContainer.querySelector('input')).not.to.be(null);
@@ -131,11 +125,8 @@ describe('gdjs.TextInputRuntimeObject (using a PixiJS RuntimeGame with DOM eleme
});
it('changes the DOM element when the object type is updated', async () => {
const {
runtimeScene,
gameDomElementContainer,
object,
} = await setupObjectAndGetDomElementContainer();
const { runtimeScene, gameDomElementContainer, object } =
await setupObjectAndGetDomElementContainer();
expect(gameDomElementContainer.querySelector('input')).not.to.be(null);
@@ -156,11 +147,8 @@ describe('gdjs.TextInputRuntimeObject (using a PixiJS RuntimeGame with DOM eleme
});
it('hides the DOM element when the object or layer is hidden', async () => {
const {
runtimeScene,
gameDomElementContainer,
object,
} = await setupObjectAndGetDomElementContainer();
const { runtimeScene, gameDomElementContainer, object } =
await setupObjectAndGetDomElementContainer();
const inputElement = gameDomElementContainer.querySelector('input');
if (!inputElement) throw new Error('Expected input element to be found');
@@ -195,11 +183,8 @@ describe('gdjs.TextInputRuntimeObject (using a PixiJS RuntimeGame with DOM eleme
});
it('hides the DOM element when the object is far from the camera', async () => {
const {
runtimeScene,
gameDomElementContainer,
object,
} = await setupObjectAndGetDomElementContainer();
const { runtimeScene, gameDomElementContainer, object } =
await setupObjectAndGetDomElementContainer();
const inputElement = gameDomElementContainer.querySelector('input');
if (!inputElement) throw new Error('Expected input element to be found');

View File

@@ -153,12 +153,14 @@ namespace gdjs {
}
// Position the input on the container on top of the canvas.
const topLeftPageCoordinates = runtimeGameRenderer.convertCanvasToDomElementContainerCoords(
topLeftCanvasCoordinates
);
const bottomRightPageCoordinates = runtimeGameRenderer.convertCanvasToDomElementContainerCoords(
bottomRightCanvasCoordinates
);
const topLeftPageCoordinates =
runtimeGameRenderer.convertCanvasToDomElementContainerCoords(
topLeftCanvasCoordinates
);
const bottomRightPageCoordinates =
runtimeGameRenderer.convertCanvasToDomElementContainerCoords(
bottomRightCanvasCoordinates
);
const widthInContainer =
bottomRightPageCoordinates[0] - topLeftPageCoordinates[0];
@@ -267,6 +269,8 @@ namespace gdjs {
}
}
export const TextInputRuntimeObjectRenderer = TextInputRuntimeObjectPixiRenderer;
export type TextInputRuntimeObjectRenderer = TextInputRuntimeObjectPixiRenderer;
export const TextInputRuntimeObjectRenderer =
TextInputRuntimeObjectPixiRenderer;
export type TextInputRuntimeObjectRenderer =
TextInputRuntimeObjectPixiRenderer;
}

View File

@@ -157,5 +157,6 @@ namespace gdjs {
}
export const TileMapRuntimeObjectRenderer =
gdjs.TileMapRuntimeObjectPixiRenderer;
export type TileMapRuntimeObjectRenderer = gdjs.TileMapRuntimeObjectPixiRenderer;
export type TileMapRuntimeObjectRenderer =
gdjs.TileMapRuntimeObjectPixiRenderer;
}

View File

@@ -126,6 +126,8 @@ namespace gdjs {
}
}
export const TiledSpriteRuntimeObjectRenderer = TiledSpriteRuntimeObjectPixiRenderer;
export type TiledSpriteRuntimeObjectRenderer = TiledSpriteRuntimeObjectPixiRenderer;
export const TiledSpriteRuntimeObjectRenderer =
TiledSpriteRuntimeObjectPixiRenderer;
export type TiledSpriteRuntimeObjectRenderer =
TiledSpriteRuntimeObjectPixiRenderer;
}

View File

@@ -117,17 +117,20 @@ namespace gdjs {
setViewpoint(viewpoint: string, customIsometryAngle: float): void {
if (viewpoint === 'PixelIsometry') {
this._basisTransformation = new gdjs.TopDownMovementRuntimeBehavior.IsometryTransformation(
Math.atan(0.5)
);
this._basisTransformation =
new gdjs.TopDownMovementRuntimeBehavior.IsometryTransformation(
Math.atan(0.5)
);
} else if (viewpoint === 'TrueIsometry') {
this._basisTransformation = new gdjs.TopDownMovementRuntimeBehavior.IsometryTransformation(
Math.PI / 6
);
this._basisTransformation =
new gdjs.TopDownMovementRuntimeBehavior.IsometryTransformation(
Math.PI / 6
);
} else if (viewpoint === 'CustomIsometry') {
this._basisTransformation = new gdjs.TopDownMovementRuntimeBehavior.IsometryTransformation(
(customIsometryAngle * Math.PI) / 180
);
this._basisTransformation =
new gdjs.TopDownMovementRuntimeBehavior.IsometryTransformation(
(customIsometryAngle * Math.PI) / 180
);
} else {
this._basisTransformation = null;
}
@@ -525,7 +528,8 @@ namespace gdjs {
}
export class IsometryTransformation
implements gdjs.TopDownMovementRuntimeBehavior.BasisTransformation {
implements gdjs.TopDownMovementRuntimeBehavior.BasisTransformation
{
private _screen: float[][];
/**

View File

@@ -83,7 +83,8 @@ namespace gdjs {
}
updateLoop(): void {
this._pixiObject._texture.baseTexture.resource.source.loop = this._object._loop;
this._pixiObject._texture.baseTexture.resource.source.loop =
this._object._loop;
}
updateVolume(): void {

View File

@@ -165,8 +165,10 @@ namespace gdjs {
const newRuntimeGameOptions: RuntimeGameOptions =
gdjs.runtimeGameOptions;
const newScriptFiles = newRuntimeGameOptions.scriptFiles as RuntimeGameOptionsScriptFile[];
const projectDataOnlyExport = !!newRuntimeGameOptions.projectDataOnlyExport;
const newScriptFiles =
newRuntimeGameOptions.scriptFiles as RuntimeGameOptionsScriptFile[];
const projectDataOnlyExport =
!!newRuntimeGameOptions.projectDataOnlyExport;
// Reload the changed scripts, which will have the side effects of re-running
// the new scripts, potentially replacing the code of the free functions from
@@ -179,10 +181,11 @@ namespace gdjs {
projectDataOnlyExport
)
.then(() => {
const changedRuntimeBehaviors = this._computeChangedRuntimeBehaviors(
oldBehaviorConstructors,
gdjs.behaviorsTypes.items
);
const changedRuntimeBehaviors =
this._computeChangedRuntimeBehaviors(
oldBehaviorConstructors,
gdjs.behaviorsTypes.items
);
return this._hotReloadRuntimeGame(
oldProjectData,
newProjectData,

View File

@@ -30,15 +30,18 @@ namespace gdjs {
runtimeObject: gdjs.RuntimeObject
) => void;
export const callbacksFirstRuntimeSceneLoaded: Array<RuntimeSceneCallback> = [];
export const callbacksFirstRuntimeSceneLoaded: Array<RuntimeSceneCallback> =
[];
export const callbacksRuntimeSceneLoaded: Array<RuntimeSceneCallback> = [];
export const callbacksRuntimeScenePreEvents: Array<RuntimeSceneCallback> = [];
export const callbacksRuntimeScenePostEvents: Array<RuntimeSceneCallback> = [];
export const callbacksRuntimeScenePostEvents: Array<RuntimeSceneCallback> =
[];
export const callbacksRuntimeScenePaused: Array<RuntimeSceneCallback> = [];
export const callbacksRuntimeSceneResumed: Array<RuntimeSceneCallback> = [];
export const callbacksRuntimeSceneUnloading: Array<RuntimeSceneCallback> = [];
export const callbacksRuntimeSceneUnloaded: Array<RuntimeSceneCallback> = [];
export const callbacksObjectDeletedFromScene: Array<RuntimeSceneRuntimeObjectCallback> = [];
export const callbacksObjectDeletedFromScene: Array<RuntimeSceneRuntimeObjectCallback> =
[];
/** Base64 encoded logo of GDevelop for the splash screen. */
export let gdevelopLogo: string = '';

View File

@@ -378,9 +378,8 @@ namespace gdjs {
* @deprecated
*/
popStartedTouch(): integer | undefined {
const publicIdentifier = this._startedTouches[
this._lastStartedTouchIndex
];
const publicIdentifier =
this._startedTouches[this._lastStartedTouchIndex];
this._lastStartedTouchIndex++;
return publicIdentifier;
}

View File

@@ -52,7 +52,8 @@ namespace gdjs {
// without a canvas.
return;
}
this._pixiRenderer.backgroundColor = this._loadingScreenData.backgroundColor;
this._pixiRenderer.backgroundColor =
this._loadingScreenData.backgroundColor;
const backgroundTexture = imageManager.getPIXITexture(
loadingScreenData.backgroundImageResourceName
@@ -151,18 +152,18 @@ namespace gdjs {
this._startLoadingScreen();
}
} else if (this._state == LoadingScreenState.STARTED) {
const backgroundFadeInDuration = this._loadingScreenData
.backgroundFadeInDuration;
const backgroundFadeInDuration =
this._loadingScreenData.backgroundFadeInDuration;
fadeIn(this._backgroundSprite, backgroundFadeInDuration, deltaTimeInMs);
if (hasFadedIn(this._backgroundSprite)) {
if (!this._backgroundReadyTimeInMs)
this._backgroundReadyTimeInMs = timeInMs;
const logoAndProgressFadeInDuration = this._loadingScreenData
.logoAndProgressFadeInDuration;
const logoAndProgressLogoFadeInDelay = this._loadingScreenData
.logoAndProgressLogoFadeInDelay;
const logoAndProgressFadeInDuration =
this._loadingScreenData.logoAndProgressFadeInDuration;
const logoAndProgressLogoFadeInDelay =
this._loadingScreenData.logoAndProgressLogoFadeInDelay;
if (
timeInMs - this._backgroundReadyTimeInMs >

View File

@@ -175,7 +175,8 @@ namespace gdjs {
}
if (this._pixiBitmapFontsToUninstall.length > uninstallCacheSize) {
// Remove the first font (i.e: the oldest one)
const oldestUnloadedPixiBitmapFontName = this._pixiBitmapFontsToUninstall.shift() as string;
const oldestUnloadedPixiBitmapFontName =
this._pixiBitmapFontsToUninstall.shift() as string;
PIXI.BitmapFont.uninstall(oldestUnloadedPixiBitmapFontName);
logger.log(

View File

@@ -53,7 +53,11 @@ namespace gdjs {
this._forceFullscreen = forceFullscreen;
//If set to true, the canvas will always be displayed as fullscreen, even if _isFullscreen == false.
this._marginLeft = this._marginTop = this._marginRight = this._marginBottom = 0;
this._marginLeft =
this._marginTop =
this._marginRight =
this._marginBottom =
0;
this._setupOrientation();
}

View File

@@ -57,7 +57,8 @@ namespace gdjs {
// this._renderProfileText(); //Uncomment to display profiling times
// render the PIXI container of the scene
this._pixiRenderer.backgroundColor = this._runtimeScene.getBackgroundColor();
this._pixiRenderer.backgroundColor =
this._runtimeScene.getBackgroundColor();
this._pixiRenderer.render(this._pixiContainer);
}
@@ -305,9 +306,8 @@ namespace gdjs {
// Clean any point text from an object that is not rendered.
for (const objectID in this._debugDrawRenderedObjectsPoints) {
const renderedObjectPoints = this._debugDrawRenderedObjectsPoints[
objectID
];
const renderedObjectPoints =
this._debugDrawRenderedObjectsPoints[objectID];
if (renderedObjectPoints.wasRendered) continue;
const points = renderedObjectPoints.points;
@@ -359,10 +359,8 @@ namespace gdjs {
setLayerIndex(layer: gdjs.Layer, index: float): void {
const layerPixiRenderer: gdjs.LayerPixiRenderer = layer.getRenderer();
let layerPixiObject:
| PIXI.Container
| PIXI.Sprite
| null = layerPixiRenderer.getRendererObject();
let layerPixiObject: PIXI.Container | PIXI.Sprite | null =
layerPixiRenderer.getRendererObject();
if (layer.isLightingLayer()) {
layerPixiObject = layerPixiRenderer.getLightingSprite();
}

View File

@@ -136,13 +136,12 @@ namespace gdjs {
for (const sectionName in section.subsections) {
if (section.subsections.hasOwnProperty(sectionName)) {
const destinationSubsections = destinationSection.subsections;
const destinationSubsection = (destinationSubsections[
sectionName
] = destinationSubsections[sectionName] || {
parent: destinationSection,
time: 0,
subsections: {},
});
const destinationSubsection = (destinationSubsections[sectionName] =
destinationSubsections[sectionName] || {
parent: destinationSection,
time: 0,
subsections: {},
});
Profiler._addAverageSectionTimes(
section.subsections[sectionName],
destinationSubsection,

View File

@@ -119,7 +119,8 @@ namespace gdjs {
this._originalWidth = this._gameResolutionWidth;
this._originalHeight = this._gameResolutionHeight;
this._resizeMode = this._data.properties.sizeOnStartupMode;
this._adaptGameResolutionAtRuntime = this._data.properties.adaptGameResolutionAtRuntime;
this._adaptGameResolutionAtRuntime =
this._data.properties.adaptGameResolutionAtRuntime;
this._scaleMode = data.properties.scaleMode || 'linear';
this._pixelsRounding = this._data.properties.pixelsRounding;
this._renderer = new gdjs.RuntimeGameRenderer(
@@ -353,8 +354,10 @@ namespace gdjs {
gdjs.RuntimeGameRenderer.getWindowInnerWidth &&
gdjs.RuntimeGameRenderer.getWindowInnerHeight
) {
const windowInnerWidth = gdjs.RuntimeGameRenderer.getWindowInnerWidth();
const windowInnerHeight = gdjs.RuntimeGameRenderer.getWindowInnerHeight();
const windowInnerWidth =
gdjs.RuntimeGameRenderer.getWindowInnerWidth();
const windowInnerHeight =
gdjs.RuntimeGameRenderer.getWindowInnerHeight();
// Enlarge either the width or the eight to fill the inner window space.
let width = this._gameResolutionWidth;

View File

@@ -664,9 +664,8 @@ namespace gdjs {
if (object.isHidden()) {
rendererObject.visible = false;
} else {
const cameraCoords = this._layersCameraCoordinates[
object.getLayer()
];
const cameraCoords =
this._layersCameraCoordinates[object.getLayer()];
if (!cameraCoords) {
continue;
}

View File

@@ -105,9 +105,8 @@ namespace gdjs {
// Optionally create the objects from an external layout.
if (externalLayoutName) {
const externalLayoutData = this._runtimeGame.getExternalLayoutData(
externalLayoutName
);
const externalLayoutData =
this._runtimeGame.getExternalLayoutData(externalLayoutName);
if (externalLayoutData) {
newScene.createObjectsFrom(
externalLayoutData.instances,

View File

@@ -454,9 +454,10 @@ namespace gdjs {
) {
return;
}
const direction = this._animations[this._currentAnimation].directions[
this._currentDirection
];
const direction =
this._animations[this._currentAnimation].directions[
this._currentDirection
];
const oldFrame = this._currentFrame;
//*Optimization*: Animation is finished, don't change the current frame
@@ -525,9 +526,10 @@ namespace gdjs {
this._currentDirection <
this._animations[this._currentAnimation].directions.length
) {
const direction = this._animations[this._currentAnimation].directions[
this._currentDirection
];
const direction =
this._animations[this._currentAnimation].directions[
this._currentDirection
];
if (this._currentFrame < direction.frames.length) {
this._animationFrame = direction.frames[this._currentFrame];
if (this._animationFrame !== null) {
@@ -586,9 +588,8 @@ namespace gdjs {
this.hitBoxes[i].vertices[j]
);
}
this.hitBoxes[i].vertices.length = this._animationFrame.customHitBoxes[
i
].vertices.length;
this.hitBoxes[i].vertices.length =
this._animationFrame.customHitBoxes[i].vertices.length;
}
this.hitBoxes.length = this._animationFrame.customHitBoxes.length;
}
@@ -715,9 +716,10 @@ namespace gdjs {
) {
return;
}
const direction = this._animations[this._currentAnimation].directions[
this._currentDirection
];
const direction =
this._animations[this._currentAnimation].directions[
this._currentDirection
];
if (
newFrame >= 0 &&
newFrame < direction.frames.length &&
@@ -748,9 +750,10 @@ namespace gdjs {
) {
return true;
}
const direction = this._animations[this._currentAnimation].directions[
this._currentDirection
];
const direction =
this._animations[this._currentAnimation].directions[
this._currentDirection
];
if (direction.loop) {
return false;
}

View File

@@ -465,7 +465,7 @@ namespace gdjs {
return this._type === 'structure'
? this._children
: this._type === 'array'
? ((Object.assign({}, this._childrenArray) as unknown) as Children)
? (Object.assign({}, this._childrenArray) as unknown as Children)
: {};
}

17
GDJS/package-lock.json generated
View File

@@ -20,7 +20,7 @@
"minimist": "^1.2.5",
"patch-package": "^6.4.7",
"pixi.js": "^6.1.2",
"prettier": "2.1.2",
"prettier": "2.6.2",
"recursive-readdir": "^2.2.2",
"shelljs": "^0.8.4",
"typedoc": "^0.22.11",
@@ -2967,15 +2967,18 @@
}
},
"node_modules/prettier": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.1.2.tgz",
"integrity": "sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg==",
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz",
"integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==",
"dev": true,
"bin": {
"prettier": "bin-prettier.js"
},
"engines": {
"node": ">=10.13.0"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/private": {
@@ -6289,9 +6292,9 @@
"dev": true
},
"prettier": {
"version": "2.1.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.1.2.tgz",
"integrity": "sha512-16c7K+x4qVlJg9rEbXl7HEGmQyZlG4R9AgP+oHKRMsMsuk8s+ATStlf1NpDqyBI1HpVyfjLOeMhH2LvuNvV5Vg==",
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz",
"integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==",
"dev": true
},
"private": {

View File

@@ -16,7 +16,7 @@
"minimist": "^1.2.5",
"patch-package": "^6.4.7",
"pixi.js": "^6.1.2",
"prettier": "2.1.2",
"prettier": "2.6.2",
"recursive-readdir": "^2.2.2",
"shelljs": "^0.8.4",
"typedoc": "^0.22.11",

View File

@@ -78,7 +78,7 @@
"follow-redirects": "^1.2.3",
"iso-639-1": "^2.0.3",
"minimist": "1.2.5",
"prettier": "1.15.3",
"prettier": "2.6.2",
"react-error-overlay": "^6.0.9",
"react-scripts": "4.0.3",
"recursive-copy": "^2.0.10",
@@ -32926,15 +32926,18 @@
}
},
"node_modules/prettier": {
"version": "1.15.3",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-1.15.3.tgz",
"integrity": "sha512-gAU9AGAPMaKb3NNSUUuhhFAS7SCO4ALTN4nRIn6PJ075Qd28Yn2Ig2ahEJWdJwJmlEBTUfC7mMUSFy8MwsOCfg==",
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz",
"integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==",
"dev": true,
"bin": {
"prettier": "bin-prettier.js"
},
"engines": {
"node": ">=4"
"node": ">=10.13.0"
},
"funding": {
"url": "https://github.com/prettier/prettier?sponsor=1"
}
},
"node_modules/pretty-bytes": {
@@ -67540,9 +67543,9 @@
"dev": true
},
"prettier": {
"version": "1.15.3",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-1.15.3.tgz",
"integrity": "sha512-gAU9AGAPMaKb3NNSUUuhhFAS7SCO4ALTN4nRIn6PJ075Qd28Yn2Ig2ahEJWdJwJmlEBTUfC7mMUSFy8MwsOCfg==",
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/prettier/-/prettier-2.6.2.tgz",
"integrity": "sha512-PkUpF+qoXTqhOeWL9fu7As8LXsIUZ1WYaJiY/a7McAQzxjk82OF0tibkFXVCDImZtWxbvojFjerkiLb0/q8mew==",
"dev": true
},
"pretty-bytes": {

View File

@@ -18,7 +18,7 @@
"follow-redirects": "^1.2.3",
"iso-639-1": "^2.0.3",
"minimist": "1.2.5",
"prettier": "1.15.3",
"prettier": "2.6.2",
"react-error-overlay": "^6.0.9",
"react-scripts": "4.0.3",
"recursive-copy": "^2.0.10",

View File

@@ -96,40 +96,31 @@ export const AssetDetails = ({
const { authors, licenses } = React.useContext(AssetStoreContext);
const [asset, setAsset] = React.useState<?Asset>(null);
const [error, setError] = React.useState<?Error>(null);
const loadAsset = React.useCallback(
() => {
(async () => {
try {
const loadedAsset = await getAsset(assetShortHeader);
setAsset(loadedAsset);
} catch (error) {
console.log('Error while loading asset:', error);
setError(error);
}
})();
},
[assetShortHeader]
);
const loadAsset = React.useCallback(() => {
(async () => {
try {
const loadedAsset = await getAsset(assetShortHeader);
setAsset(loadedAsset);
} catch (error) {
console.log('Error while loading asset:', error);
setError(error);
}
})();
}, [assetShortHeader]);
React.useEffect(
() => {
loadAsset();
},
[loadAsset]
);
React.useEffect(() => {
loadAsset();
}, [loadAsset]);
const canAddAsset = canInstall && !isBeingInstalled && !!asset;
const onAddAsset = React.useCallback(
() => {
if (canAddAsset) onAdd();
},
[onAdd, canAddAsset]
);
const onAddAsset = React.useCallback(() => {
if (canAddAsset) onAdd();
}, [onAdd, canAddAsset]);
const assetAuthors: ?Array<Author> =
asset && authors
? asset.authors
.map(authorName => {
.map((authorName) => {
return authors.find(({ name }) => name === authorName);
})
.filter(Boolean)
@@ -166,7 +157,7 @@ export const AssetDetails = ({
<Column expand noMargin>
<ResponsiveLineStackLayout noMargin>
<ResponsiveWindowMeasurer>
{windowWidth => (
{(windowWidth) => (
<div
style={{
...styles.previewBackground,
@@ -204,7 +195,7 @@ export const AssetDetails = ({
)}
</div>
<span>
{assetShortHeader.tags.map(tag => (
{assetShortHeader.tags.map((tag) => (
<Chip size="small" style={styles.chip} label={tag} key={tag} />
))}
</span>
@@ -213,7 +204,7 @@ export const AssetDetails = ({
<Text size="body">
<Trans>By:</Trans>{' '}
{!!assetAuthors &&
assetAuthors.map(author => {
assetAuthors.map((author) => {
return (
<Link
key={author.name}

View File

@@ -24,7 +24,7 @@ type AssetStoreState = {|
fetchAssetsAndFilters: () => void,
error: ?Error,
searchText: string,
setSearchText: string => void,
setSearchText: (string) => void,
filtersState: FiltersState,
|};
@@ -77,66 +77,54 @@ export const AssetStoreStateProvider = ({
const [searchText, setSearchText] = React.useState(defaultSearchText);
const filtersState = useFilters();
const fetchAssetsAndFilters = React.useCallback(
() => {
// Don't attempt to load again assets and filters if they
// were loaded already.
if (assetShortHeadersById || isLoading.current) return;
const fetchAssetsAndFilters = React.useCallback(() => {
// Don't attempt to load again assets and filters if they
// were loaded already.
if (assetShortHeadersById || isLoading.current) return;
(async () => {
setError(null);
isLoading.current = true;
(async () => {
setError(null);
isLoading.current = true;
try {
const {
assetShortHeaders,
filters,
assetPacks,
} = await listAllAssets();
const authors = await listAllAuthors();
const licenses = await listAllLicenses();
try {
const { assetShortHeaders, filters, assetPacks } =
await listAllAssets();
const authors = await listAllAuthors();
const licenses = await listAllLicenses();
const assetShortHeadersById = {};
assetShortHeaders.forEach(assetShortHeader => {
assetShortHeadersById[assetShortHeader.id] = assetShortHeader;
});
const assetShortHeadersById = {};
assetShortHeaders.forEach((assetShortHeader) => {
assetShortHeadersById[assetShortHeader.id] = assetShortHeader;
});
console.info(
`Loaded ${assetShortHeaders.length} assets from the asset store.`
);
setAssetShortHeadersById(assetShortHeadersById);
setFilters(filters);
setAssetPacks(assetPacks);
setAuthors(authors);
setLicenses(licenses);
} catch (error) {
console.error(
`Unable to load the assets from the asset store:`,
error
);
setError(error);
}
console.info(
`Loaded ${assetShortHeaders.length} assets from the asset store.`
);
setAssetShortHeadersById(assetShortHeadersById);
setFilters(filters);
setAssetPacks(assetPacks);
setAuthors(authors);
setLicenses(licenses);
} catch (error) {
console.error(`Unable to load the assets from the asset store:`, error);
setError(error);
}
isLoading.current = false;
})();
},
[assetShortHeadersById, isLoading]
);
isLoading.current = false;
})();
}, [assetShortHeadersById, isLoading]);
React.useEffect(
() => {
// Don't attempt to load again assets and filters if they
// were loaded already.
if (assetShortHeadersById || isLoading.current) return;
React.useEffect(() => {
// Don't attempt to load again assets and filters if they
// were loaded already.
if (assetShortHeadersById || isLoading.current) return;
const timeoutId = setTimeout(() => {
console.info('Pre-fetching assets from asset store...');
fetchAssetsAndFilters();
}, 6000);
return () => clearTimeout(timeoutId);
},
[fetchAssetsAndFilters, assetShortHeadersById, isLoading]
);
const timeoutId = setTimeout(() => {
console.info('Pre-fetching assets from asset store...');
fetchAssetsAndFilters();
}, 6000);
return () => clearTimeout(timeoutId);
}, [fetchAssetsAndFilters, assetShortHeadersById, isLoading]);
const { chosenCategory, chosenFilters } = filtersState;
const searchResults: ?Array<AssetShortHeader> = useSearchItem(

View File

@@ -45,7 +45,7 @@ const styles = {
},
};
const useStylesForGridListItem = makeStyles(theme =>
const useStylesForGridListItem = makeStyles((theme) =>
createStyles({
root: {
'&:focus': {
@@ -59,7 +59,7 @@ const useStylesForGridListItem = makeStyles(theme =>
type Props = {|
assetPacks: AssetPacks,
onPackSelection: string => void,
onPackSelection: (string) => void,
|};
export const AssetsHome = ({

View File

@@ -50,25 +50,19 @@ export function ExampleDialog({
const [error, setError] = React.useState<?Error>(null);
const [example, setExample] = React.useState<?Example>(null);
const loadExample = React.useCallback(
async () => {
setError(null);
try {
const example = await getExample(exampleShortHeader);
setExample(example);
} catch (error) {
setError(error);
}
},
[exampleShortHeader]
);
const loadExample = React.useCallback(async () => {
setError(null);
try {
const example = await getExample(exampleShortHeader);
setExample(example);
} catch (error) {
setError(error);
}
}, [exampleShortHeader]);
React.useEffect(
() => {
loadExample();
},
[loadExample]
);
React.useEffect(() => {
loadExample();
}, [loadExample]);
const isCompatible = isCompatibleWithAsset(
getIDEVersion(),
@@ -77,12 +71,9 @@ export function ExampleDialog({
const hasIcon = exampleShortHeader.previewImageUrls.length > 0;
const canOpenExample = !isOpening && isCompatible;
const onOpenExample = React.useCallback(
() => {
if (canOpenExample) onOpen();
},
[onOpen, canOpenExample]
);
const onOpenExample = React.useCallback(() => {
if (canOpenExample) onOpen();
}, [onOpen, canOpenExample]);
return (
<Dialog
@@ -106,7 +97,7 @@ export function ExampleDialog({
primary
onClick={onOpenExample}
disabled={!canOpenExample}
buildMenuTemplate={i18n => [
buildMenuTemplate={(i18n) => [
{
label: electron
? i18n._(t`Open in the web-app`)
@@ -146,7 +137,7 @@ export function ExampleDialog({
</Line>
{exampleShortHeader.authors && (
<Line>
{exampleShortHeader.authors.map(author => (
{exampleShortHeader.authors.map((author) => (
<UserPublicProfileChip
user={author}
key={author.id}

View File

@@ -27,7 +27,7 @@ export const ExampleIcon = ({ exampleShortHeader, size }: Props) => {
<CorsAwareImage
style={{ ...styles.icon, height: size }}
src={
exampleShortHeader.previewImageUrls.find(url =>
exampleShortHeader.previewImageUrls.find((url) =>
url.endsWith('thumbnail.png')
) || exampleShortHeader.previewImageUrls[0]
}

View File

@@ -41,7 +41,7 @@ type Props = {|
isOpening: boolean,
onChoose: () => void,
onOpen: () => void,
onHeightComputed: number => void,
onHeightComputed: (number) => void,
|};
export const ExampleListItem = ({
@@ -87,7 +87,7 @@ export const ExampleListItem = ({
const originalField = exampleShortHeader[field];
if (!matches) return originalField;
const nameMatches = matches.filter(match => match.key === field);
const nameMatches = matches.filter((match) => match.key === field);
if (nameMatches.length === 0) return originalField;
return (
@@ -109,7 +109,7 @@ export const ExampleListItem = ({
<Text noMargin>{renderExampleField('name')} </Text>
{exampleShortHeader.authors && (
<Line>
{exampleShortHeader.authors.map(author => (
{exampleShortHeader.authors.map((author) => (
<UserPublicProfileChip user={author} key={author.id} />
))}
</Line>
@@ -125,7 +125,7 @@ export const ExampleListItem = ({
label={<Trans>Open</Trans>}
disabled={isOpening || !isCompatible}
onClick={() => onOpen()}
buildMenuTemplate={i18n => [
buildMenuTemplate={(i18n) => [
{
label: i18n._(t`Open details`),
click: onChoose,

View File

@@ -21,7 +21,7 @@ type ExampleStoreState = {|
allExamples: ?Array<ExampleShortHeader>,
error: ?Error,
searchText: string,
setSearchText: string => void,
setSearchText: (string) => void,
filtersState: FiltersState,
|};
@@ -49,79 +49,67 @@ type ExampleStoreStateProviderProps = {|
export const ExampleStoreStateProvider = ({
children,
}: ExampleStoreStateProviderProps) => {
const [
exampleShortHeadersById,
setExampleShortHeadersById,
] = React.useState<?{
[string]: ExampleShortHeader,
}>(null);
const [exampleShortHeadersById, setExampleShortHeadersById] =
React.useState<?{
[string]: ExampleShortHeader,
}>(null);
const [filters, setFilters] = React.useState<?Filters>(null);
const [error, setError] = React.useState<?Error>(null);
const [
allExamples,
setAllExamples,
] = React.useState<?Array<ExampleShortHeader>>(null);
const [allExamples, setAllExamples] =
React.useState<?Array<ExampleShortHeader>>(null);
const isLoading = React.useRef<boolean>(false);
const [searchText, setSearchText] = React.useState(defaultSearchText);
const filtersState = useFilters();
const fetchExamplesAndFilters = React.useCallback(
() => {
// Don't attempt to load again resources and filters if they
// were loaded already.
if (exampleShortHeadersById || isLoading.current) return;
const fetchExamplesAndFilters = React.useCallback(() => {
// Don't attempt to load again resources and filters if they
// were loaded already.
if (exampleShortHeadersById || isLoading.current) return;
(async () => {
setError(null);
isLoading.current = true;
(async () => {
setError(null);
isLoading.current = true;
try {
const allExamples: AllExamples = await listAllExamples();
const { exampleShortHeaders, filters } = allExamples;
setAllExamples(exampleShortHeaders);
try {
const allExamples: AllExamples = await listAllExamples();
const { exampleShortHeaders, filters } = allExamples;
setAllExamples(exampleShortHeaders);
const exampleShortHeadersById = {};
exampleShortHeaders.forEach(exampleShortHeader => {
exampleShortHeadersById[exampleShortHeader.id] = exampleShortHeader;
});
const exampleShortHeadersById = {};
exampleShortHeaders.forEach((exampleShortHeader) => {
exampleShortHeadersById[exampleShortHeader.id] = exampleShortHeader;
});
console.info(
`Loaded ${
exampleShortHeaders.length
} examples from the example store.`
);
setExampleShortHeadersById(exampleShortHeadersById);
setFilters(filters);
} catch (error) {
console.error(
`Unable to load the examples from the example store:`,
error
);
setError(error);
}
console.info(
`Loaded ${exampleShortHeaders.length} examples from the example store.`
);
setExampleShortHeadersById(exampleShortHeadersById);
setFilters(filters);
} catch (error) {
console.error(
`Unable to load the examples from the example store:`,
error
);
setError(error);
}
isLoading.current = false;
})();
},
[exampleShortHeadersById, isLoading]
);
isLoading.current = false;
})();
}, [exampleShortHeadersById, isLoading]);
React.useEffect(
() => {
// Don't attempt to load again examples and filters if they
// were loaded already.
if (exampleShortHeadersById || isLoading.current) return;
React.useEffect(() => {
// Don't attempt to load again examples and filters if they
// were loaded already.
if (exampleShortHeadersById || isLoading.current) return;
const timeoutId = setTimeout(() => {
console.info('Pre-fetching examples from the example store...');
fetchExamplesAndFilters();
}, 5000);
return () => clearTimeout(timeoutId);
},
[fetchExamplesAndFilters, exampleShortHeadersById, isLoading]
);
const timeoutId = setTimeout(() => {
console.info('Pre-fetching examples from the example store...');
fetchExamplesAndFilters();
}, 5000);
return () => clearTimeout(timeoutId);
}, [fetchExamplesAndFilters, exampleShortHeadersById, isLoading]);
const { chosenCategory, chosenFilters } = filtersState;
const searchResults: ?Array<{|

View File

@@ -23,7 +23,7 @@ const styles = {
type Props = {|
isOpening: boolean,
onOpen: ExampleShortHeader => Promise<void>,
onOpen: (ExampleShortHeader) => Promise<void>,
focusOnMount?: boolean,
|};
@@ -31,10 +31,8 @@ const getExampleName = (exampleShortHeader: ExampleShortHeader) =>
exampleShortHeader.name;
export const ExampleStore = ({ isOpening, onOpen, focusOnMount }: Props) => {
const [
selectedExampleShortHeader,
setSelectedExampleShortHeader,
] = React.useState<?ExampleShortHeader>(null);
const [selectedExampleShortHeader, setSelectedExampleShortHeader] =
React.useState<?ExampleShortHeader>(null);
const {
filters,
searchResults,
@@ -48,20 +46,14 @@ export const ExampleStore = ({ isOpening, onOpen, focusOnMount }: Props) => {
const shouldAutofocusSearchbar = useShouldAutofocusSearchbar();
const searchBarRef = React.useRef<?SearchBarInterface>(null);
React.useEffect(
() => {
fetchExamplesAndFilters();
},
[fetchExamplesAndFilters]
);
React.useEffect(() => {
fetchExamplesAndFilters();
}, [fetchExamplesAndFilters]);
React.useEffect(
() => {
if (focusOnMount && shouldAutofocusSearchbar && searchBarRef.current)
searchBarRef.current.focus();
},
[shouldAutofocusSearchbar, focusOnMount]
);
React.useEffect(() => {
if (focusOnMount && shouldAutofocusSearchbar && searchBarRef.current)
searchBarRef.current.focus();
}, [shouldAutofocusSearchbar, focusOnMount]);
const tagsHandler = React.useMemo(
() => ({
@@ -77,7 +69,7 @@ export const ExampleStore = ({ isOpening, onOpen, focusOnMount }: Props) => {
): SearchMatch[] => {
if (!searchResults) return [];
const exampleMatches = searchResults.find(
result => result.item.id === exampleShortHeader.id
(result) => result.item.id === exampleShortHeader.id
);
return exampleMatches ? exampleMatches.matches : [];
};
@@ -85,7 +77,7 @@ export const ExampleStore = ({ isOpening, onOpen, focusOnMount }: Props) => {
return (
<React.Fragment>
<ResponsiveWindowMeasurer>
{windowWidth => (
{(windowWidth) => (
<Column expand noMargin useFullHeight>
<SearchBar
value={searchText}

View File

@@ -63,25 +63,20 @@ const ExtensionInstallDialog = ({
const extensionUpdate = useExtensionUpdate(project, extensionShortHeader);
const [error, setError] = React.useState<?Error>(null);
const [
extensionHeader,
setExtensionHeader,
] = React.useState<?ExtensionHeader>(null);
const [extensionHeader, setExtensionHeader] =
React.useState<?ExtensionHeader>(null);
const loadExtensionheader = React.useCallback(
() => {
setError(null);
getExtensionHeader(extensionShortHeader).then(
extensionHeader => {
setExtensionHeader(extensionHeader);
},
error => {
setError(error);
}
);
},
[extensionShortHeader]
);
const loadExtensionheader = React.useCallback(() => {
setError(null);
getExtensionHeader(extensionShortHeader).then(
(extensionHeader) => {
setExtensionHeader(extensionHeader);
},
(error) => {
setError(error);
}
);
}, [extensionShortHeader]);
React.useEffect(() => loadExtensionheader(), [loadExtensionheader]);
@@ -91,22 +86,19 @@ const ExtensionInstallDialog = ({
);
const canInstallExtension = !isInstalling && isCompatible;
const onInstallExtension = React.useCallback(
() => {
if (canInstallExtension) {
if (alreadyInstalled) {
const answer = Window.showConfirmDialog(
'This extension is already in your project, this will install the latest version. You may have to do some adaptations to make sure your game still works. Do you want to continue?'
);
if (!answer) return;
onInstall();
} else {
onInstall();
}
const onInstallExtension = React.useCallback(() => {
if (canInstallExtension) {
if (alreadyInstalled) {
const answer = Window.showConfirmDialog(
'This extension is already in your project, this will install the latest version. You may have to do some adaptations to make sure your game still works. Do you want to continue?'
);
if (!answer) return;
onInstall();
} else {
onInstall();
}
},
[onInstall, canInstallExtension, alreadyInstalled]
);
}
}, [onInstall, canInstallExtension, alreadyInstalled]);
return (
<Dialog
@@ -179,7 +171,7 @@ const ExtensionInstallDialog = ({
</Text>
<Line>
{extensionShortHeader.authors &&
extensionShortHeader.authors.map(author => (
extensionShortHeader.authors.map((author) => (
<UserPublicProfileChip
user={author}
key={author.id}

View File

@@ -26,7 +26,7 @@ type Props = {|
extensionShortHeader: ExtensionShortHeader,
matches: ?Array<SearchMatch>,
onChoose: () => void,
onHeightComputed: number => void,
onHeightComputed: (number) => void,
|};
export const ExtensionListItem = ({
@@ -51,7 +51,7 @@ export const ExtensionListItem = ({
const originalField = extensionShortHeader[field];
if (!matches) return originalField;
const nameMatches = matches.filter(match => match.key === field);
const nameMatches = matches.filter((match) => match.key === field);
if (nameMatches.length === 0) return originalField;
return (
@@ -78,7 +78,7 @@ export const ExtensionListItem = ({
</Text>
{extensionShortHeader.authors && (
<Line>
{extensionShortHeader.authors.map(author => (
{extensionShortHeader.authors.map((author) => (
<UserPublicProfileChip user={author} key={author.id} />
))}
</Line>

View File

@@ -23,7 +23,7 @@ type ExtensionStoreState = {|
fetchExtensionsAndFilters: () => void,
error: ?Error,
searchText: string,
setSearchText: string => void,
setSearchText: (string) => void,
extensionShortHeadersByName: { [name: string]: ExtensionShortHeader },
filtersState: FiltersState,
|};
@@ -52,12 +52,10 @@ type ExtensionStoreStateProviderProps = {|
export const ExtensionStoreStateProvider = ({
children,
}: ExtensionStoreStateProviderProps) => {
const [
extensionShortHeadersByName,
setExtensionShortHeadersByName,
] = React.useState<{
[string]: ExtensionShortHeader,
}>({});
const [extensionShortHeadersByName, setExtensionShortHeadersByName] =
React.useState<{
[string]: ExtensionShortHeader,
}>({});
const [filters, setFilters] = React.useState<?Filters>(null);
const [error, setError] = React.useState<?Error>(null);
const isLoading = React.useRef<boolean>(false);
@@ -65,72 +63,65 @@ export const ExtensionStoreStateProvider = ({
const [searchText, setSearchText] = React.useState(defaultSearchText);
const filtersState = useFilters();
const fetchExtensionsAndFilters = React.useCallback(
() => {
// Don't attempt to load again resources and filters if they
// were loaded already.
if (Object.keys(extensionShortHeadersByName).length || isLoading.current)
return;
const fetchExtensionsAndFilters = React.useCallback(() => {
// Don't attempt to load again resources and filters if they
// were loaded already.
if (Object.keys(extensionShortHeadersByName).length || isLoading.current)
return;
(async () => {
setError(null);
isLoading.current = true;
(async () => {
setError(null);
isLoading.current = true;
try {
const extensionRegistry: ExtensionsRegistry = await getExtensionsRegistry();
const { extensionShortHeaders, allTags } = extensionRegistry;
try {
const extensionRegistry: ExtensionsRegistry =
await getExtensionsRegistry();
const { extensionShortHeaders, allTags } = extensionRegistry;
const sortedTags = allTags
.slice()
.sort((tag1, tag2) =>
tag1.toLowerCase().localeCompare(tag2.toLowerCase())
);
const extensionShortHeadersByName = {};
extensionShortHeaders.forEach(extension => {
extensionShortHeadersByName[extension.name] = extension;
});
console.info(
`Loaded ${
extensionShortHeaders.length
} extensions from the extension store.`
const sortedTags = allTags
.slice()
.sort((tag1, tag2) =>
tag1.toLowerCase().localeCompare(tag2.toLowerCase())
);
setExtensionShortHeadersByName(extensionShortHeadersByName);
setFilters({
allTags: sortedTags,
defaultTags: sortedTags,
tagsTree: [],
});
} catch (error) {
console.error(
`Unable to load the extensions from the extension store:`,
error
);
setError(error);
}
isLoading.current = false;
})();
},
[extensionShortHeadersByName, isLoading]
);
const extensionShortHeadersByName = {};
extensionShortHeaders.forEach((extension) => {
extensionShortHeadersByName[extension.name] = extension;
});
React.useEffect(
() => {
// Don't attempt to load again extensions and filters if they
// were loaded already.
if (Object.keys(extensionShortHeadersByName).length || isLoading.current)
return;
console.info(
`Loaded ${extensionShortHeaders.length} extensions from the extension store.`
);
setExtensionShortHeadersByName(extensionShortHeadersByName);
setFilters({
allTags: sortedTags,
defaultTags: sortedTags,
tagsTree: [],
});
} catch (error) {
console.error(
`Unable to load the extensions from the extension store:`,
error
);
setError(error);
}
const timeoutId = setTimeout(() => {
console.info('Pre-fetching extensions from extension store...');
fetchExtensionsAndFilters();
}, 5000);
return () => clearTimeout(timeoutId);
},
[fetchExtensionsAndFilters, extensionShortHeadersByName, isLoading]
);
isLoading.current = false;
})();
}, [extensionShortHeadersByName, isLoading]);
React.useEffect(() => {
// Don't attempt to load again extensions and filters if they
// were loaded already.
if (Object.keys(extensionShortHeadersByName).length || isLoading.current)
return;
const timeoutId = setTimeout(() => {
console.info('Pre-fetching extensions from extension store...');
fetchExtensionsAndFilters();
}, 5000);
return () => clearTimeout(timeoutId);
}, [fetchExtensionsAndFilters, extensionShortHeadersByName, isLoading]);
const { chosenCategory, chosenFilters } = filtersState;
const searchResults: ?Array<{|

View File

@@ -21,7 +21,7 @@ import {
type Props = {|
project: gdProject,
onClose: () => void,
onInstallExtension: ExtensionShortHeader => void,
onInstallExtension: (ExtensionShortHeader) => void,
onExtensionInstalled?: (extensionShortHeader?: ExtensionShortHeader) => void,
|};
@@ -35,9 +35,8 @@ export default function ExtensionsSearchDialog({
onExtensionInstalled,
}: Props) {
const [isInstalling, setIsInstalling] = React.useState(false);
const [extensionWasInstalled, setExtensionWasInstalled] = React.useState(
false
);
const [extensionWasInstalled, setExtensionWasInstalled] =
React.useState(false);
const eventsFunctionsExtensionsState = React.useContext(
EventsFunctionsExtensionsContext
);
@@ -84,7 +83,8 @@ export default function ExtensionsSearchDialog({
}
};
const eventsFunctionsExtensionOpener = eventsFunctionsExtensionsState.getEventsFunctionsExtensionOpener();
const eventsFunctionsExtensionOpener =
eventsFunctionsExtensionsState.getEventsFunctionsExtensionOpener();
return (
<I18n>
@@ -123,7 +123,7 @@ export default function ExtensionsSearchDialog({
>
<ExtensionStore
isInstalling={isInstalling}
onInstall={async extensionShortHeader =>
onInstall={async (extensionShortHeader) =>
installOrImportExtension(i18n, extensionShortHeader)
}
project={project}

View File

@@ -48,16 +48,19 @@ export const importExtension = async (
eventsFunctionsExtensionsState: EventsFunctionsExtensionsState,
project: gdProject
): Promise<boolean> => {
const eventsFunctionsExtensionOpener = eventsFunctionsExtensionsState.getEventsFunctionsExtensionOpener();
const eventsFunctionsExtensionOpener =
eventsFunctionsExtensionsState.getEventsFunctionsExtensionOpener();
if (!eventsFunctionsExtensionOpener) return false;
try {
const pathOrUrl = await eventsFunctionsExtensionOpener.chooseEventsFunctionExtensionFile();
const pathOrUrl =
await eventsFunctionsExtensionOpener.chooseEventsFunctionExtensionFile();
if (!pathOrUrl) return false;
const serializedExtension = await eventsFunctionsExtensionOpener.readEventsFunctionExtensionFile(
pathOrUrl
);
const serializedExtension =
await eventsFunctionsExtensionOpener.readEventsFunctionExtensionFile(
pathOrUrl
);
if (project.hasEventsFunctionsExtensionNamed(serializedExtension.name)) {
const answer = Window.showConfirmDialog(

View File

@@ -25,7 +25,7 @@ const styles = {
type Props = {|
isInstalling: boolean,
project: gdProject,
onInstall: ExtensionShortHeader => Promise<boolean>,
onInstall: (ExtensionShortHeader) => Promise<boolean>,
showOnlyWithBehaviors: boolean,
|};
@@ -38,10 +38,8 @@ export const ExtensionStore = ({
onInstall,
showOnlyWithBehaviors,
}: Props) => {
const [
selectedExtensionShortHeader,
setSelectedExtensionShortHeader,
] = React.useState<?ExtensionShortHeader>(null);
const [selectedExtensionShortHeader, setSelectedExtensionShortHeader] =
React.useState<?ExtensionShortHeader>(null);
const {
filters,
searchResults,
@@ -52,12 +50,9 @@ export const ExtensionStore = ({
setSearchText,
} = React.useContext(ExtensionStoreContext);
React.useEffect(
() => {
fetchExtensionsAndFilters();
},
[fetchExtensionsAndFilters]
);
React.useEffect(() => {
fetchExtensionsAndFilters();
}, [fetchExtensionsAndFilters]);
const filteredSearchResults = searchResults
? searchResults.filter(
@@ -81,7 +76,7 @@ export const ExtensionStore = ({
): SearchMatch[] => {
if (!searchResults) return [];
const extensionMatches = searchResults.find(
result => result.item.name === extensionShortHeader.name
(result) => result.item.name === extensionShortHeader.name
);
return extensionMatches ? extensionMatches.matches : [];
};
@@ -93,7 +88,7 @@ export const ExtensionStore = ({
return (
<React.Fragment>
<ResponsiveWindowMeasurer>
{windowWidth => (
{(windowWidth) => (
<Column expand noMargin useFullHeight>
<SearchBar
value={searchText}

View File

@@ -24,11 +24,11 @@ const toPascalCase = (str: string) => {
return str
.replace(/^[^A-Za-z0-9]*|[^A-Za-z0-9]*$/g, '$')
.replace(/[^A-Za-z0-9]+/g, '$')
.replace(/([a-z])([A-Z])/g, function(m, a, b) {
.replace(/([a-z])([A-Z])/g, function (m, a, b) {
return a + '$' + b;
})
.toLowerCase()
.replace(/(\$)(\w?)/g, function(m, a, b) {
.replace(/(\$)(\w?)/g, function (m, a, b) {
return b.toUpperCase();
});
};
@@ -82,9 +82,8 @@ export const installResource = (
resourceOriginIdentifier
)
: '';
const existingResourceNameWithSameFile = resourcesManager.getResourceNameWithFile(
resourceFileUrl
);
const existingResourceNameWithSameFile =
resourcesManager.getResourceNameWithFile(resourceFileUrl);
if (existingResourceNameFromSameOrigin) {
// There is a resource with the same origin, use it.
@@ -108,7 +107,7 @@ export const installResource = (
unserializeFromJSObject(newResource, serializedResource);
const newName = newNameGenerator(originalResourceName, name =>
const newName = newNameGenerator(originalResourceName, (name) =>
resourcesManager.hasResource(name)
);
newResource.setName(newName);
@@ -135,18 +134,18 @@ export const addAssetToProject = async ({
const resourceNewNames = {};
const createdObjects: Array<gdObject> = [];
asset.objectAssets.forEach(objectAsset => {
objectAsset.resources.forEach(serializedResource => {});
asset.objectAssets.forEach((objectAsset) => {
objectAsset.resources.forEach((serializedResource) => {});
});
// Create objects (and their behaviors)
asset.objectAssets.forEach(objectAsset => {
asset.objectAssets.forEach((objectAsset) => {
const type: ?string = objectAsset.object.type;
if (!type) throw new Error('An object has no type specified');
// Insert the object
const originalName = sanitizeObjectName(objectAsset.object.name);
const newName = newNameGenerator(originalName, name =>
const newName = newNameGenerator(originalName, (name) =>
objectsContainer.hasObjectNamed(name)
);
const object = objectsContainer.insertNewObject(
@@ -168,7 +167,7 @@ export const addAssetToProject = async ({
object.setName(newName);
// Add resources used by the object
objectAsset.resources.forEach(serializedResource => {
objectAsset.resources.forEach((serializedResource) => {
installResource(project, serializedResource, resourceNewNames);
});
@@ -182,7 +181,7 @@ export const addAssetToProject = async ({
object.exposeResources(resourcesRenamer);
resourcesRenamer.delete();
objectAsset.customization.forEach(customization => {
objectAsset.customization.forEach((customization) => {
if (customization.behaviorName) {
const { behaviorName, behaviorType } = customization;
@@ -205,7 +204,7 @@ export const addAssetToProject = async ({
behaviorType,
behaviorName
);
customization.properties.forEach(property => {
customization.properties.forEach((property) => {
behavior.updateProperty(
behaviorContent.getContent(),
property.name,
@@ -220,11 +219,11 @@ export const addAssetToProject = async ({
// Add the events after adding all objects, as we need to potentially
// rename the objects in the inserted events.
asset.objectAssets.forEach(objectAsset => {
asset.objectAssets.forEach((objectAsset) => {
const originalName = objectAsset.object.name;
const newName = objectNewNames[originalName];
objectAsset.customization.forEach(customization => {
objectAsset.customization.forEach((customization) => {
if (customization.events) {
const groupEvent = new gd.GroupEvent();
groupEvent.setName(newName);
@@ -237,7 +236,7 @@ export const addAssetToProject = async ({
);
// Find/replace the customization parameters in the events.
customization.parameters.forEach(parameter => {
customization.parameters.forEach((parameter) => {
gd.EventsRefactorer.replaceStringInEvents(
project,
objectsContainer,
@@ -290,15 +289,12 @@ export const getRequiredBehaviorsFromAsset = (
): Array<RequiredBehavior> => {
return uniqBy(
flatten(
asset.objectAssets.map(objectAsset => {
asset.objectAssets.map((objectAsset) => {
return objectAsset.customization
.map(customization => {
.map((customization) => {
if (customization.behaviorName) {
const {
behaviorType,
extensionName,
extensionVersion,
} = customization;
const { behaviorType, extensionName, extensionVersion } =
customization;
return { behaviorType, extensionName, extensionVersion };
}
@@ -322,7 +318,7 @@ export const filterMissingExtensions = (
): Array<RequiredExtension> => {
const loadedExtensionNames = mapVector(
gd.asPlatform(gd.JsPlatform.get()).getAllPlatformExtensions(),
extension => {
(extension) => {
return extension.getName();
}
);
@@ -337,10 +333,10 @@ export const getRequiredExtensionsForEventsFromAsset = (
): Array<RequiredExtension> => {
return uniqBy(
flatten(
asset.objectAssets.map(objectAsset => {
asset.objectAssets.map((objectAsset) => {
return flatten(
objectAsset.customization
.map(customization => {
.map((customization) => {
if (customization.events) {
return customization.extensions;
}
@@ -376,12 +372,13 @@ export const downloadExtensions = async (
const extensionsRegistry = await getExtensionsRegistry();
const serializedExtensions = await Promise.all(
uniq(extensionNames).map(extensionName => {
const extensionShortHeader = extensionsRegistry.extensionShortHeaders.find(
extensionShortHeader => {
return extensionShortHeader.name === extensionName;
}
);
uniq(extensionNames).map((extensionName) => {
const extensionShortHeader =
extensionsRegistry.extensionShortHeaders.find(
(extensionShortHeader) => {
return extensionShortHeader.name === extensionName;
}
);
if (!extensionShortHeader) {
throw new Error(
'Unable to find extension ' + extensionName + ' in the registry.'
@@ -405,16 +402,15 @@ export const addSerializedExtensionsToProject = (
serializedExtensions: Array<SerializedExtension>,
fromExtensionStore: boolean = true
): Promise<void> => {
serializedExtensions.forEach(serializedExtension => {
serializedExtensions.forEach((serializedExtension) => {
const { name } = serializedExtension;
if (!name)
return Promise.reject(new Error('Malformed extension (missing name).'));
const newEventsFunctionsExtension = project.hasEventsFunctionsExtensionNamed(
name
)
? project.getEventsFunctionsExtension(name)
: project.insertNewEventsFunctionsExtension(name, 0);
const newEventsFunctionsExtension =
project.hasEventsFunctionsExtensionNamed(name)
? project.getEventsFunctionsExtension(name)
: project.insertNewEventsFunctionsExtension(name, 0);
unserializeFromJSObject(
newEventsFunctionsExtension,

View File

@@ -129,10 +129,7 @@ describe('InstallAsset', () => {
// Verify there was not extra resource added.
expect(
project
.getResourcesManager()
.getAllResourceNames()
.toJSArray()
project.getResourcesManager().getAllResourceNames().toJSArray()
).toEqual([
...originalResourceNames,
'player-ship1.png',
@@ -171,10 +168,7 @@ describe('InstallAsset', () => {
// Verify there was not extra resource added.
expect(
project
.getResourcesManager()
.getAllResourceNames()
.toJSArray()
project.getResourcesManager().getAllResourceNames().toJSArray()
).toEqual([
...originalResourceNames,
'renamed-player-ship1.png',
@@ -210,10 +204,7 @@ describe('InstallAsset', () => {
// Verify there was not extra resource added
expect(
project
.getResourcesManager()
.getAllResourceNames()
.toJSArray()
project.getResourcesManager().getAllResourceNames().toJSArray()
).toEqual([
...originalResourceNames,
'player-ship1.png',
@@ -221,10 +212,7 @@ describe('InstallAsset', () => {
'player-ship2.png',
]);
expect(
project
.getResourcesManager()
.getResource('player-ship1.png2')
.getFile()
project.getResourcesManager().getResource('player-ship1.png2').getFile()
).toBe('https://example.com/player-ship1.png');
// Verify the resource names used by the object
@@ -259,10 +247,7 @@ describe('InstallAsset', () => {
expect(layout.hasObjectNamed('PlayerSpaceship')).toBe(true);
expect(
layout
.getObject('PlayerSpaceship')
.getAllBehaviorNames()
.toJSArray()
layout.getObject('PlayerSpaceship').getAllBehaviorNames().toJSArray()
).toEqual(['MyBehavior']);
expect(
layout
@@ -785,12 +770,9 @@ describe('InstallAsset', () => {
// Check that the object was created, with the proper behavior:
expect(layout.getObjectsCount()).toBe(1);
expect(layout.getObjectAt(0).getName()).toBe('PlayerSpaceship');
expect(
layout
.getObjectAt(0)
.getAllBehaviorNames()
.toJSArray()
).toEqual(['MyBehavior']);
expect(layout.getObjectAt(0).getAllBehaviorNames().toJSArray()).toEqual([
'MyBehavior',
]);
});
});
});

View File

@@ -75,7 +75,7 @@ type Props = {|
events: gdEventsList,
onClose: () => void,
onCreateNewObject: (type: string) => void,
onObjectAddedFromAsset: gdObject => void,
onObjectAddedFromAsset: (gdObject) => void,
|};
export default function NewObjectDialog({
@@ -90,10 +90,8 @@ export default function NewObjectDialog({
onCreateNewObject,
onObjectAddedFromAsset,
}: Props) {
const {
setNewObjectDialogDefaultTab,
getNewObjectDialogDefaultTab,
} = React.useContext(PreferencesContext);
const { setNewObjectDialogDefaultTab, getNewObjectDialogDefaultTab } =
React.useContext(PreferencesContext);
const [assetWasInstalled, setAssetWasInstalled] = React.useState(false);
const [openedAsset, setOpenedAsset] = React.useState<null | AssetShortHeader>(
null
@@ -102,36 +100,32 @@ export default function NewObjectDialog({
const [currentTab, setCurrentTab] = React.useState(
getNewObjectDialogDefaultTab()
);
const allObjectMetadata = React.useMemo(() => enumerateObjectTypes(project), [
project,
]);
const allObjectMetadata = React.useMemo(
() => enumerateObjectTypes(project),
[project]
);
const objectsByCategory: {
[string]: Array<EnumeratedObjectMetadata>,
} = React.useMemo(
() => {
const objectsByCategory = {};
allObjectMetadata.forEach(objectMetadata => {
const category = objectMetadata.categoryFullName;
objectsByCategory[category] = [
...(objectsByCategory[category] || []),
objectMetadata,
];
});
return objectsByCategory;
},
[allObjectMetadata]
);
} = React.useMemo(() => {
const objectsByCategory = {};
allObjectMetadata.forEach((objectMetadata) => {
const category = objectMetadata.categoryFullName;
objectsByCategory[category] = [
...(objectsByCategory[category] || []),
objectMetadata,
];
});
return objectsByCategory;
}, [allObjectMetadata]);
const resourcesFetcher = useResourceFetcher();
React.useEffect(() => setNewObjectDialogDefaultTab(currentTab), [
setNewObjectDialogDefaultTab,
currentTab,
]);
React.useEffect(
() => setNewObjectDialogDefaultTab(currentTab),
[setNewObjectDialogDefaultTab, currentTab]
);
const [
assetBeingInstalled,
setAssetBeingInstalled,
] = React.useState<?AssetShortHeader>(null);
const [assetBeingInstalled, setAssetBeingInstalled] =
React.useState<?AssetShortHeader>(null);
const eventsFunctionsExtensionsState = React.useContext(
EventsFunctionsExtensionsContext
);
@@ -153,7 +147,7 @@ export default function NewObjectDialog({
});
console.log('Asset successfully installed.');
installOutput.createdObjects.forEach(object => {
installOutput.createdObjects.forEach((object) => {
onObjectAddedFromAsset(object);
});
@@ -164,9 +158,7 @@ export default function NewObjectDialog({
} catch (error) {
console.error('Error while installing the asset:', error);
showErrorBox({
message: `There was an error while installing the asset "${
assetShortHeader.name
}". Verify your internet connection or try again later.`,
message: `There was an error while installing the asset "${assetShortHeader.name}". Verify your internet connection or try again later.`,
rawError: error,
errorId: 'install-asset-error',
});
@@ -185,9 +177,8 @@ export default function NewObjectDialog({
]
);
const { DismissableTutorialMessage } = useDismissableTutorialMessage(
'intro-object-types'
);
const { DismissableTutorialMessage } =
useDismissableTutorialMessage('intro-object-types');
return (
<Dialog
@@ -224,7 +215,7 @@ export default function NewObjectDialog({
project={project}
objectsContainer={objectsContainer}
events={events}
onOpenDetails={assetShortHeader => {
onOpenDetails={(assetShortHeader) => {
setOpenedAsset(assetShortHeader);
sendAssetOpened({
id: assetShortHeader.id,
@@ -241,12 +232,12 @@ export default function NewObjectDialog({
</Line>
)}
<List>
{Object.keys(objectsByCategory).map(category => {
{Object.keys(objectsByCategory).map((category) => {
const categoryObjectMetadata = objectsByCategory[category];
return (
<React.Fragment key={category}>
<Subheader>{category}</Subheader>
{categoryObjectMetadata.map(objectMetadata => (
{categoryObjectMetadata.map((objectMetadata) => (
<ObjectListItem
key={objectMetadata.name}
objectMetadata={objectMetadata}

View File

@@ -22,7 +22,7 @@ type ResourceStoreState = {|
fetchResourcesAndFilters: () => void,
error: ?Error,
searchText: string,
setSearchText: string => void,
setSearchText: (string) => void,
filtersState: FiltersState,
|};
@@ -67,46 +67,40 @@ export const ResourceStoreStateProvider = ({
const [searchText, setSearchText] = React.useState(defaultSearchText);
const filtersState = useFilters();
const fetchResourcesAndFilters = React.useCallback(
() => {
// Don't attempt to load again resources and filters if they
// were loaded already.
if (resourcesByUrl || isLoading.current) return;
const fetchResourcesAndFilters = React.useCallback(() => {
// Don't attempt to load again resources and filters if they
// were loaded already.
if (resourcesByUrl || isLoading.current) return;
(async () => {
setError(null);
isLoading.current = true;
(async () => {
setError(null);
isLoading.current = true;
try {
const { resources, filters } = await listAllResources();
const authors = await listAllAuthors();
const licenses = await listAllLicenses();
try {
const { resources, filters } = await listAllResources();
const authors = await listAllAuthors();
const licenses = await listAllLicenses();
const resourcesByUrl = {};
resources.forEach(resource => {
resourcesByUrl[resource.url] = resource;
});
const resourcesByUrl = {};
resources.forEach((resource) => {
resourcesByUrl[resource.url] = resource;
});
console.info(
`Loaded ${resources.length} resources from the asset store.`
);
setResourcesByUrl(resourcesByUrl);
setFilters(filters);
setAuthors(authors);
setLicenses(licenses);
} catch (error) {
console.error(
`Unable to load the assets from the asset store:`,
error
);
setError(error);
}
console.info(
`Loaded ${resources.length} resources from the asset store.`
);
setResourcesByUrl(resourcesByUrl);
setFilters(filters);
setAuthors(authors);
setLicenses(licenses);
} catch (error) {
console.error(`Unable to load the assets from the asset store:`, error);
setError(error);
}
isLoading.current = false;
})();
},
[resourcesByUrl, isLoading]
);
isLoading.current = false;
})();
}, [resourcesByUrl, isLoading]);
const { chosenCategory, chosenFilters } = filtersState;
const searchResults: ?Array<Resource> = useSearchItem(

View File

@@ -21,7 +21,7 @@ const styles = {
};
type Props = {
onChoose: Resource => void,
onChoose: (Resource) => void,
resourceKind: string,
};
@@ -36,15 +36,12 @@ export const ResourceStore = ({ onChoose, resourceKind }: Props) => {
setSearchText,
} = React.useContext(ResourceStoreContext);
React.useEffect(
() => {
fetchResourcesAndFilters();
},
[fetchResourcesAndFilters]
);
React.useEffect(() => {
fetchResourcesAndFilters();
}, [fetchResourcesAndFilters]);
const searchResultsForResourceKind = searchResults
? searchResults.filter(resource => resource.type === resourceKind)
? searchResults.filter((resource) => resource.type === resourceKind)
: null;
return (

View File

@@ -34,7 +34,7 @@ type Props = {
project: gdProject,
objectsContainer: gdObjectsContainer,
events: gdEventsList,
onOpenDetails: AssetShortHeader => void,
onOpenDetails: (AssetShortHeader) => void,
focusOnMount?: boolean,
};
@@ -56,30 +56,24 @@ export const AssetStore = ({
setSearchText,
} = React.useContext(AssetStoreContext);
React.useEffect(
() => {
fetchAssetsAndFilters();
},
[fetchAssetsAndFilters]
);
React.useEffect(() => {
fetchAssetsAndFilters();
}, [fetchAssetsAndFilters]);
const searchBar = React.useRef<?SearchBarInterface>(null);
const shouldAutofocusSearchbar = useShouldAutofocusSearchbar();
const [isOnHomePage, setIsOnHomePage] = React.useState(true);
const [isFiltersOpen, setIsFiltersOpen] = React.useState(false);
React.useEffect(
() => {
if (focusOnMount && shouldAutofocusSearchbar && searchBar.current) {
searchBar.current.focus();
}
},
[shouldAutofocusSearchbar, focusOnMount]
);
React.useEffect(() => {
if (focusOnMount && shouldAutofocusSearchbar && searchBar.current) {
searchBar.current.focus();
}
}, [shouldAutofocusSearchbar, focusOnMount]);
return (
<ResponsiveWindowMeasurer>
{windowWidth => (
{(windowWidth) => (
<Column expand noMargin useFullHeight>
<SearchBar
placeholder={t`Enter your Search`}
@@ -166,7 +160,7 @@ export const AssetStore = ({
{isOnHomePage && assetPacks ? (
<AssetsHome
assetPacks={assetPacks}
onPackSelection={tag => {
onPackSelection={(tag) => {
const chosenCategory = {
node: { name: tag, allChildrenTags: [], children: [] },
parentNodes: [],

View File

@@ -12,7 +12,7 @@ type Props = {|
project: gdProject,
objectType: string,
value: string,
onChange: string => void,
onChange: (string) => void,
disabled?: boolean,
|};
type State = {|

View File

@@ -17,7 +17,7 @@ export default class BehaviorPropertiesEditor extends React.Component<Props> {
const propertiesSchema = propertiesMapToSchema(
properties,
behaviorContent => behavior.getProperties(behaviorContent.getContent()),
(behaviorContent) => behavior.getProperties(behaviorContent.getContent()),
(behaviorContent, name, value) => {
behavior.updateProperty(behaviorContent.getContent(), name, value);
},

View File

@@ -1,162 +1,157 @@
// @flow
import * as React from 'react';
import {
Table,
TableRow,
TableRowColumn,
TableBody,
TableHeader,
TableHeaderColumn,
} from '../../../UI/Table';
import SemiControlledTextField from '../../../UI/SemiControlledTextField';
import Warning from '@material-ui/icons/Warning';
import IconButton from '../../../UI/IconButton';
import ThemeConsumer from '../../../UI/Theme/ThemeConsumer';
import AddCircle from '@material-ui/icons/AddCircle';
import Delete from '@material-ui/icons/Delete';
export type Vertex = {|
x: number,
y: number,
|};
type Props = {|
vertices: Array<Vertex>,
onChangeVertexX: (newValue: number, index: number) => void,
onChangeVertexY: (newValue: number, index: number) => void,
onAdd: () => void,
onRemove: (index: number) => void,
|};
export default class PolygonEditor extends React.Component<Props> {
_isPolygonConvex(vertices: Array<Vertex>) {
// Get edges
let edges = [];
let v1 = null;
let v2 = null;
for (let i = 0; i < vertices.length; i++) {
v1 = vertices[i];
if (i + 1 >= vertices.length) v2 = vertices[0];
else v2 = vertices[i + 1];
edges.push({ x: v2.x - v1.x, y: v2.y - v1.y });
}
// Check convexity
if (edges.length < 3) return false;
const zProductIsPositive =
edges[0].x * edges[0 + 1].y - edges[0].y * edges[0 + 1].x > 0;
for (let i = 1; i < edges.length - 1; ++i) {
let zCrossProduct =
edges[i].x * edges[i + 1].y - edges[i].y * edges[i + 1].x;
let zCrossProductIsPositive = zCrossProduct > 0;
if (zCrossProductIsPositive !== zProductIsPositive) return false;
}
let lastZCrossProduct =
edges[edges.length - 1].x * edges[0].y -
edges[edges.length - 1].y * edges[0].x;
let lastZCrossProductIsPositive = lastZCrossProduct > 0;
if (lastZCrossProductIsPositive !== zProductIsPositive) return false;
// Check for repeated vertices (would crash Box2D during the game)
for (let i = 0; i < vertices.length - 1; ++i) {
for (let j = i + 1; j < vertices.length; ++j) {
if (vertices[i].x === vertices[j].x && vertices[i].y === vertices[j].y)
return false;
}
}
// Check if all vertices are aligned (would crash Box2D during the game)
let alignedX = true;
let alignedY = true;
for (let i = 0; i < vertices.length - 1; ++i) {
if (vertices[i].x !== vertices[i + 1].x) alignedX = false;
if (vertices[i].y !== vertices[i + 1].y) alignedY = false;
}
if (alignedX || alignedY) return false;
return true;
}
render() {
const {
vertices,
onChangeVertexX,
onChangeVertexY,
onAdd,
onRemove,
} = this.props;
return (
<ThemeConsumer>
{muiTheme => (
<Table>
<TableHeader>
<TableRow>
<TableHeaderColumn />
<TableHeaderColumn>X</TableHeaderColumn>
<TableHeaderColumn>Y</TableHeaderColumn>
<TableRowColumn />
</TableRow>
</TableHeader>
<TableBody>
{vertices.map((value, index) => {
return (
<TableRow
key={`vertexRow${index}`}
style={{
backgroundColor: muiTheme.list.itemsBackgroundColor,
}}
>
<TableRowColumn>
{!this._isPolygonConvex(vertices) && <Warning />}
</TableRowColumn>
<TableRowColumn>
<SemiControlledTextField
margin="none"
fullWidth
value={value.x.toString(10)}
onChange={newValue =>
onChangeVertexX(parseFloat(newValue) || 0, index)
}
type="number"
/>
</TableRowColumn>
<TableRowColumn>
<SemiControlledTextField
margin="none"
fullWidth
value={value.y.toString(10)}
onChange={newValue =>
onChangeVertexY(parseFloat(newValue) || 0, index)
}
type="number"
/>
</TableRowColumn>
<TableRowColumn>
<IconButton size="small" onClick={() => onRemove(index)}>
<Delete />
</IconButton>
</TableRowColumn>
</TableRow>
);
})}
<TableRow>
<TableRowColumn />
<TableRowColumn />
<TableRowColumn />
<TableRowColumn>
<IconButton onClick={onAdd}>
<AddCircle />
</IconButton>
</TableRowColumn>
</TableRow>
</TableBody>
</Table>
)}
</ThemeConsumer>
);
}
}
// @flow
import * as React from 'react';
import {
Table,
TableRow,
TableRowColumn,
TableBody,
TableHeader,
TableHeaderColumn,
} from '../../../UI/Table';
import SemiControlledTextField from '../../../UI/SemiControlledTextField';
import Warning from '@material-ui/icons/Warning';
import IconButton from '../../../UI/IconButton';
import ThemeConsumer from '../../../UI/Theme/ThemeConsumer';
import AddCircle from '@material-ui/icons/AddCircle';
import Delete from '@material-ui/icons/Delete';
export type Vertex = {|
x: number,
y: number,
|};
type Props = {|
vertices: Array<Vertex>,
onChangeVertexX: (newValue: number, index: number) => void,
onChangeVertexY: (newValue: number, index: number) => void,
onAdd: () => void,
onRemove: (index: number) => void,
|};
export default class PolygonEditor extends React.Component<Props> {
_isPolygonConvex(vertices: Array<Vertex>) {
// Get edges
let edges = [];
let v1 = null;
let v2 = null;
for (let i = 0; i < vertices.length; i++) {
v1 = vertices[i];
if (i + 1 >= vertices.length) v2 = vertices[0];
else v2 = vertices[i + 1];
edges.push({ x: v2.x - v1.x, y: v2.y - v1.y });
}
// Check convexity
if (edges.length < 3) return false;
const zProductIsPositive =
edges[0].x * edges[0 + 1].y - edges[0].y * edges[0 + 1].x > 0;
for (let i = 1; i < edges.length - 1; ++i) {
let zCrossProduct =
edges[i].x * edges[i + 1].y - edges[i].y * edges[i + 1].x;
let zCrossProductIsPositive = zCrossProduct > 0;
if (zCrossProductIsPositive !== zProductIsPositive) return false;
}
let lastZCrossProduct =
edges[edges.length - 1].x * edges[0].y -
edges[edges.length - 1].y * edges[0].x;
let lastZCrossProductIsPositive = lastZCrossProduct > 0;
if (lastZCrossProductIsPositive !== zProductIsPositive) return false;
// Check for repeated vertices (would crash Box2D during the game)
for (let i = 0; i < vertices.length - 1; ++i) {
for (let j = i + 1; j < vertices.length; ++j) {
if (vertices[i].x === vertices[j].x && vertices[i].y === vertices[j].y)
return false;
}
}
// Check if all vertices are aligned (would crash Box2D during the game)
let alignedX = true;
let alignedY = true;
for (let i = 0; i < vertices.length - 1; ++i) {
if (vertices[i].x !== vertices[i + 1].x) alignedX = false;
if (vertices[i].y !== vertices[i + 1].y) alignedY = false;
}
if (alignedX || alignedY) return false;
return true;
}
render() {
const { vertices, onChangeVertexX, onChangeVertexY, onAdd, onRemove } =
this.props;
return (
<ThemeConsumer>
{(muiTheme) => (
<Table>
<TableHeader>
<TableRow>
<TableHeaderColumn />
<TableHeaderColumn>X</TableHeaderColumn>
<TableHeaderColumn>Y</TableHeaderColumn>
<TableRowColumn />
</TableRow>
</TableHeader>
<TableBody>
{vertices.map((value, index) => {
return (
<TableRow
key={`vertexRow${index}`}
style={{
backgroundColor: muiTheme.list.itemsBackgroundColor,
}}
>
<TableRowColumn>
{!this._isPolygonConvex(vertices) && <Warning />}
</TableRowColumn>
<TableRowColumn>
<SemiControlledTextField
margin="none"
fullWidth
value={value.x.toString(10)}
onChange={(newValue) =>
onChangeVertexX(parseFloat(newValue) || 0, index)
}
type="number"
/>
</TableRowColumn>
<TableRowColumn>
<SemiControlledTextField
margin="none"
fullWidth
value={value.y.toString(10)}
onChange={(newValue) =>
onChangeVertexY(parseFloat(newValue) || 0, index)
}
type="number"
/>
</TableRowColumn>
<TableRowColumn>
<IconButton size="small" onClick={() => onRemove(index)}>
<Delete />
</IconButton>
</TableRowColumn>
</TableRow>
);
})}
<TableRow>
<TableRowColumn />
<TableRowColumn />
<TableRowColumn />
<TableRowColumn>
<IconButton onClick={onAdd}>
<AddCircle />
</IconButton>
</TableRowColumn>
</TableRow>
</TableBody>
</Table>
)}
</ThemeConsumer>
);
}
}

View File

@@ -186,14 +186,18 @@ const ShapePreview = (props: Props) => {
fillRule="evenodd"
points={vertices
.map(
vertex =>
`${(vertex.x +
offsetX +
(polygonOrigin === 'Center' ? width / 2 : 0)) *
zoomFactor},${(vertex.y +
offsetY +
(polygonOrigin === 'Center' ? height / 2 : 0)) *
zoomFactor}`
(vertex) =>
`${
(vertex.x +
offsetX +
(polygonOrigin === 'Center' ? width / 2 : 0)) *
zoomFactor
},${
(vertex.y +
offsetY +
(polygonOrigin === 'Center' ? height / 2 : 0)) *
zoomFactor
}`
)
.join(' ')}
/>

File diff suppressed because it is too large Load Diff

View File

@@ -20,13 +20,13 @@ export const enumerateBehaviorsMetadata = (
const extensionsList = platform.getAllPlatformExtensions();
return flatten(
mapFor(0, extensionsList.size(), i => {
mapFor(0, extensionsList.size(), (i) => {
const extension = extensionsList.at(i);
return extension
.getBehaviorsTypes()
.toJSArray()
.map(behaviorType => ({
.map((behaviorType) => ({
behaviorType,
behaviorMetadata: extension.getBehaviorMetadata(behaviorType),
}))
@@ -52,7 +52,7 @@ export const filterEnumeratedBehaviorMetadata = (
const lowercaseSearchText = searchText.toLowerCase();
return list.filter(enumerateBehaviorsMetadata => {
return list.filter((enumerateBehaviorsMetadata) => {
return (
enumerateBehaviorsMetadata.fullName
.toLowerCase()

Some files were not shown because too many files have changed in this diff Show More