mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Compare commits
2 Commits
toon-mater
...
refactor/p
Author | SHA1 | Date | |
---|---|---|---|
![]() |
ac97470140 | ||
![]() |
bde4e9254d |
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
||||
|
@@ -169,5 +169,6 @@ namespace gdjs {
|
||||
return this._pixiObject.textHeight * this.getScale();
|
||||
}
|
||||
}
|
||||
export const BitmapTextRuntimeObjectRenderer = BitmapTextRuntimeObjectPixiRenderer;
|
||||
export const BitmapTextRuntimeObjectRenderer =
|
||||
BitmapTextRuntimeObjectPixiRenderer;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
};
|
||||
|
@@ -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];
|
||||
|
@@ -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') {
|
||||
|
@@ -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') {
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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) {},
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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') {
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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') {
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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) {},
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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') {
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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);
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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') {
|
||||
|
@@ -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') {
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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') {
|
||||
|
@@ -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') {
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
},
|
||||
|
@@ -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;
|
||||
});
|
||||
};
|
||||
|
||||
|
@@ -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();
|
||||
|
||||
/**
|
||||
|
@@ -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;
|
||||
};
|
||||
|
||||
/**
|
||||
|
@@ -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()
|
||||
)
|
||||
);
|
||||
});
|
||||
|
||||
|
@@ -552,9 +552,8 @@ namespace gdjs {
|
||||
|
||||
resetLeaderboardDisplayErrorTimeout(runtimeScene);
|
||||
|
||||
_leaderboardViewIframe = computeLeaderboardDisplayingIframe(
|
||||
targetUrl
|
||||
);
|
||||
_leaderboardViewIframe =
|
||||
computeLeaderboardDisplayingIframe(targetUrl);
|
||||
if (typeof window !== 'undefined') {
|
||||
_leaderboardViewClosingCallback = (event: MessageEvent) => {
|
||||
receiveMessageFromLeaderboardView(
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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,
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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) {
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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() &&
|
||||
|
@@ -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,
|
||||
|
@@ -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
|
||||
|
@@ -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) {
|
||||
|
@@ -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
|
||||
*
|
||||
|
@@ -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;
|
||||
|
||||
|
@@ -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 () {
|
||||
|
@@ -487,6 +487,8 @@ namespace gdjs {
|
||||
}
|
||||
}
|
||||
|
||||
export const ShapePainterRuntimeObjectRenderer = ShapePainterRuntimeObjectPixiRenderer;
|
||||
export type ShapePainterRuntimeObjectRenderer = ShapePainterRuntimeObjectPixiRenderer;
|
||||
export const ShapePainterRuntimeObjectRenderer =
|
||||
ShapePainterRuntimeObjectPixiRenderer;
|
||||
export type ShapePainterRuntimeObjectRenderer =
|
||||
ShapePainterRuntimeObjectPixiRenderer;
|
||||
}
|
||||
|
@@ -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],
|
||||
|
@@ -75,6 +75,8 @@ namespace gdjs {
|
||||
}
|
||||
}
|
||||
|
||||
export const TextEntryRuntimeObjectRenderer = TextEntryRuntimeObjectPixiRenderer;
|
||||
export type TextEntryRuntimeObjectRenderer = TextEntryRuntimeObjectPixiRenderer;
|
||||
export const TextEntryRuntimeObjectRenderer =
|
||||
TextEntryRuntimeObjectPixiRenderer;
|
||||
export type TextEntryRuntimeObjectRenderer =
|
||||
TextEntryRuntimeObjectPixiRenderer;
|
||||
}
|
||||
|
@@ -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');
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -157,5 +157,6 @@ namespace gdjs {
|
||||
}
|
||||
export const TileMapRuntimeObjectRenderer =
|
||||
gdjs.TileMapRuntimeObjectPixiRenderer;
|
||||
export type TileMapRuntimeObjectRenderer = gdjs.TileMapRuntimeObjectPixiRenderer;
|
||||
export type TileMapRuntimeObjectRenderer =
|
||||
gdjs.TileMapRuntimeObjectPixiRenderer;
|
||||
}
|
||||
|
@@ -126,6 +126,8 @@ namespace gdjs {
|
||||
}
|
||||
}
|
||||
|
||||
export const TiledSpriteRuntimeObjectRenderer = TiledSpriteRuntimeObjectPixiRenderer;
|
||||
export type TiledSpriteRuntimeObjectRenderer = TiledSpriteRuntimeObjectPixiRenderer;
|
||||
export const TiledSpriteRuntimeObjectRenderer =
|
||||
TiledSpriteRuntimeObjectPixiRenderer;
|
||||
export type TiledSpriteRuntimeObjectRenderer =
|
||||
TiledSpriteRuntimeObjectPixiRenderer;
|
||||
}
|
||||
|
@@ -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[][];
|
||||
|
||||
/**
|
||||
|
@@ -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 {
|
||||
|
@@ -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,
|
||||
|
@@ -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 = '';
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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 >
|
||||
|
@@ -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(
|
||||
|
@@ -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();
|
||||
}
|
||||
|
||||
|
@@ -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();
|
||||
}
|
||||
|
@@ -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,
|
||||
|
@@ -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;
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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,
|
||||
|
@@ -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;
|
||||
}
|
||||
|
@@ -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
17
GDJS/package-lock.json
generated
@@ -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": {
|
||||
|
@@ -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",
|
||||
|
19
newIDE/app/package-lock.json
generated
19
newIDE/app/package-lock.json
generated
@@ -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": {
|
||||
|
@@ -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",
|
||||
|
@@ -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}
|
||||
|
@@ -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(
|
||||
|
@@ -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 = ({
|
||||
|
@@ -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}
|
||||
|
@@ -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]
|
||||
}
|
||||
|
@@ -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,
|
||||
|
@@ -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<{|
|
||||
|
@@ -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}
|
||||
|
@@ -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}
|
||||
|
@@ -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>
|
||||
|
@@ -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<{|
|
||||
|
@@ -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}
|
||||
|
@@ -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(
|
||||
|
@@ -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}
|
||||
|
@@ -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,
|
||||
|
@@ -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',
|
||||
]);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
@@ -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}
|
||||
|
@@ -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(
|
||||
|
@@ -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 (
|
||||
|
@@ -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: [],
|
||||
|
@@ -12,7 +12,7 @@ type Props = {|
|
||||
project: gdProject,
|
||||
objectType: string,
|
||||
value: string,
|
||||
onChange: string => void,
|
||||
onChange: (string) => void,
|
||||
disabled?: boolean,
|
||||
|};
|
||||
type State = {|
|
||||
|
@@ -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);
|
||||
},
|
||||
|
@@ -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>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@@ -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
@@ -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
Reference in New Issue
Block a user