mirror of
https://github.com/4ian/GDevelop.git
synced 2025-10-15 10:19:04 +00:00
Compare commits
35 Commits
v5.4.216
...
experiment
Author | SHA1 | Date | |
---|---|---|---|
![]() |
b7fb29b358 | ||
![]() |
daed45461e | ||
![]() |
f0cad71ac5 | ||
![]() |
aef7368e90 | ||
![]() |
17127d76ed | ||
![]() |
0cae4c5824 | ||
![]() |
2242b395a0 | ||
![]() |
118df198ab | ||
![]() |
bffc8b6190 | ||
![]() |
43f2582a39 | ||
![]() |
dbf916edf6 | ||
![]() |
b255409a9f | ||
![]() |
62c754e87c | ||
![]() |
eb87e84598 | ||
![]() |
4f1b75cacf | ||
![]() |
2c92c1a259 | ||
![]() |
9f82842a79 | ||
![]() |
69f2d52977 | ||
![]() |
26c472002e | ||
![]() |
1965b54726 | ||
![]() |
fdfa4538ae | ||
![]() |
9a422a4e03 | ||
![]() |
8c6669c88b | ||
![]() |
b47eb74c16 | ||
![]() |
d0487647f6 | ||
![]() |
2b4f4ed871 | ||
![]() |
13988ef533 | ||
![]() |
1d4fc4d333 | ||
![]() |
e5924322a6 | ||
![]() |
a494731c72 | ||
![]() |
21e306d853 | ||
![]() |
84396b8583 | ||
![]() |
b694d81b27 | ||
![]() |
3907c68f3a | ||
![]() |
1830180dc0 |
@@ -293,8 +293,8 @@ void ResourceWorkerInObjectsWorker::DoVisitBehavior(gd::Behavior &behavior){
|
||||
gd::ResourceWorkerInObjectsWorker
|
||||
GetResourceWorkerOnObjects(const gd::Project &project,
|
||||
gd::ArbitraryResourceWorker &worker) {
|
||||
gd::ResourceWorkerInObjectsWorker eventsWorker(project, worker);
|
||||
return eventsWorker;
|
||||
gd::ResourceWorkerInObjectsWorker resourcesWorker(project, worker);
|
||||
return resourcesWorker;
|
||||
}
|
||||
|
||||
} // namespace gd
|
||||
|
19
Core/GDCore/IDE/Project/ObjectsUsingResourceCollector.cpp
Normal file
19
Core/GDCore/IDE/Project/ObjectsUsingResourceCollector.cpp
Normal file
@@ -0,0 +1,19 @@
|
||||
#include "ObjectsUsingResourceCollector.h"
|
||||
|
||||
#include "GDCore/Project/Object.h"
|
||||
#include "GDCore/Project/Project.h"
|
||||
|
||||
namespace gd {
|
||||
|
||||
void ObjectsUsingResourceCollector::DoVisitObject(gd::Object& object) {
|
||||
gd::ResourceNameMatcher resourceNameMatcher(resourceName);
|
||||
|
||||
object.GetConfiguration().ExposeResources(resourceNameMatcher);
|
||||
if (resourceNameMatcher.AnyResourceMatches()) {
|
||||
objectNames.push_back(object.GetName());
|
||||
}
|
||||
};
|
||||
|
||||
ObjectsUsingResourceCollector::~ObjectsUsingResourceCollector() {}
|
||||
|
||||
} // namespace gd
|
89
Core/GDCore/IDE/Project/ObjectsUsingResourceCollector.h
Normal file
89
Core/GDCore/IDE/Project/ObjectsUsingResourceCollector.h
Normal file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* GDevelop Core
|
||||
* Copyright 2008-2016 Florian Rival (Florian.Rival@gmail.com). All rights
|
||||
* reserved. This project is released under the MIT License.
|
||||
*/
|
||||
|
||||
#ifndef ProjectObjectsUsingResourceCollector_H
|
||||
#define ProjectObjectsUsingResourceCollector_H
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "GDCore/IDE/Project/ArbitraryObjectsWorker.h"
|
||||
#include "GDCore/IDE/Project/ArbitraryResourceWorker.h"
|
||||
#include "GDCore/String.h"
|
||||
|
||||
namespace gd {
|
||||
class Object;
|
||||
} // namespace gd
|
||||
|
||||
namespace gd {
|
||||
|
||||
class GD_CORE_API ObjectsUsingResourceCollector
|
||||
: public ArbitraryObjectsWorker {
|
||||
public:
|
||||
ObjectsUsingResourceCollector(const gd::String& resourceName_)
|
||||
: resourceName(resourceName_){};
|
||||
virtual ~ObjectsUsingResourceCollector();
|
||||
|
||||
std::vector<gd::String>& GetObjectNames() { return objectNames; }
|
||||
|
||||
private:
|
||||
void DoVisitObject(gd::Object& object) override;
|
||||
|
||||
std::vector<gd::String> objectNames;
|
||||
gd::String resourceName;
|
||||
};
|
||||
|
||||
class GD_CORE_API ResourceNameMatcher : public ArbitraryResourceWorker {
|
||||
public:
|
||||
ResourceNameMatcher(const gd::String& resourceName_)
|
||||
: resourceName(resourceName_), matchesResourceName(false){};
|
||||
virtual ~ResourceNameMatcher(){};
|
||||
|
||||
bool AnyResourceMatches() { return matchesResourceName; }
|
||||
void Reset() { matchesResourceName = false; }
|
||||
|
||||
private:
|
||||
virtual void ExposeFile(gd::String& resource) override{
|
||||
/*Don't care, we just read resource names*/
|
||||
};
|
||||
virtual void ExposeImage(gd::String& otherResourceName) override {
|
||||
MatchResourceName(otherResourceName);
|
||||
};
|
||||
virtual void ExposeAudio(gd::String& otherResourceName) override {
|
||||
MatchResourceName(otherResourceName);
|
||||
};
|
||||
virtual void ExposeFont(gd::String& otherResourceName) override {
|
||||
MatchResourceName(otherResourceName);
|
||||
};
|
||||
virtual void ExposeJson(gd::String& otherResourceName) override {
|
||||
MatchResourceName(otherResourceName);
|
||||
};
|
||||
virtual void ExposeTilemap(gd::String& otherResourceName) override {
|
||||
MatchResourceName(otherResourceName);
|
||||
};
|
||||
virtual void ExposeTileset(gd::String& otherResourceName) override {
|
||||
MatchResourceName(otherResourceName);
|
||||
};
|
||||
virtual void ExposeVideo(gd::String& otherResourceName) override {
|
||||
MatchResourceName(otherResourceName);
|
||||
};
|
||||
virtual void ExposeBitmapFont(gd::String& otherResourceName) override {
|
||||
MatchResourceName(otherResourceName);
|
||||
};
|
||||
virtual void ExposeModel3D(gd::String& otherResourceName) override {
|
||||
MatchResourceName(otherResourceName);
|
||||
};
|
||||
|
||||
void MatchResourceName(gd::String& otherResourceName) {
|
||||
if (otherResourceName == resourceName) matchesResourceName = true;
|
||||
}
|
||||
|
||||
gd::String resourceName;
|
||||
bool matchesResourceName;
|
||||
};
|
||||
|
||||
}; // namespace gd
|
||||
|
||||
#endif // ProjectObjectsUsingResourceCollector_H
|
@@ -26,6 +26,7 @@ export type ObjectsRenderingService = {
|
||||
requireModule: (dirname: string, moduleName: string) => any,
|
||||
getThumbnail: (project: gdProject, objectConfiguration: gdObjectConfiguration) => string,
|
||||
rgbOrHexToHexNumber: (value: string) => number,
|
||||
registerClearCache: (clearCache: any => void) => void,
|
||||
};
|
||||
export type ObjectsEditorService = {
|
||||
registerEditorConfiguration: (objectType: string, editorConfiguration: any) => void,
|
||||
|
@@ -1044,7 +1044,9 @@ module.exports = {
|
||||
.setExtensionInformation(
|
||||
'TileMap',
|
||||
_('Tilemap'),
|
||||
"The Tilemap object can be used to display tile-based objects. It's a good way to create maps for RPG, strategy games or create objects by assembling tiles, useful for platformer, retro-looking games, etc...",
|
||||
_(
|
||||
"The Tilemap object can be used to display tile-based objects. It's a good way to create maps for RPG, strategy games or create objects by assembling tiles, useful for platformer, retro-looking games, etc..."
|
||||
),
|
||||
'Todor Imreorov',
|
||||
'Open source (MIT License)'
|
||||
)
|
||||
@@ -1061,6 +1063,25 @@ module.exports = {
|
||||
return extension;
|
||||
},
|
||||
|
||||
registerClearCache: function (
|
||||
objectsRenderingService /*: ObjectsRenderingService */
|
||||
) {
|
||||
const TilemapHelper = objectsRenderingService.requireModule(
|
||||
__dirname,
|
||||
'helper/TileMapHelper'
|
||||
);
|
||||
|
||||
const clearCaches = (
|
||||
project /* InstanceHolder - gdProject in the editor */
|
||||
) => {
|
||||
/** @type {TileMapHelper.TileMapManager} */
|
||||
const manager = TilemapHelper.TileMapManager.getManager(project);
|
||||
manager.clearCaches();
|
||||
};
|
||||
|
||||
objectsRenderingService.registerClearCache(clearCaches);
|
||||
},
|
||||
|
||||
/**
|
||||
* You can optionally add sanity tests that will check the basic working
|
||||
* of your extension behaviors/objects by instantiating behaviors/objects
|
||||
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,6 +1,6 @@
|
||||
import { LDtkTileMap } from '../load/ldtk/LDtkFormat';
|
||||
import { TiledTileMap } from '../load/tiled/TiledFormat';
|
||||
export declare type TileMapFileContent =
|
||||
export type TileMapFileContent =
|
||||
| {
|
||||
kind: 'tiled';
|
||||
data: TiledTileMap;
|
||||
|
@@ -1 +1 @@
|
||||
{"version":3,"file":"TileMapFileContent.d.ts","sourceRoot":"","sources":["../../src/load/TileMapFileContent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,oBAAY,kBAAkB,GAC1B;IACE,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,YAAY,CAAC;CACpB,GACD;IACE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,WAAW,CAAC;CACnB,CAAC"}
|
||||
{"version":3,"file":"TileMapFileContent.d.ts","sourceRoot":"","sources":["../../src/load/TileMapFileContent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,yBAAyB,CAAC;AACtD,OAAO,EAAE,YAAY,EAAE,MAAM,2BAA2B,CAAC;AAEzD,MAAM,MAAM,kBAAkB,GAC1B;IACE,IAAI,EAAE,OAAO,CAAC;IACd,IAAI,EAAE,YAAY,CAAC;CACpB,GACD;IACE,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,WAAW,CAAC;CACnB,CAAC"}
|
@@ -2,7 +2,7 @@ import { integer } from '../../model/CommonTypes';
|
||||
/**
|
||||
* version 1.1.3 - https://github.com/deepnight/ldtk/blob/66fff7199932357f3ab9b044c2fc2a856f527831/docs/JSON_SCHEMA.json
|
||||
*/
|
||||
export declare type LDtkTileMap = {
|
||||
export type LDtkTileMap = {
|
||||
/** LDtk application build identifier.<br/> This is only used to identify the LDtk version that generated this particular project file, which can be useful for specific bug fixing. Note that the build identifier is just the date of the release, so it's not unique to each user (one single global ID per LDtk public release), and as a result, completely anonymous. */
|
||||
appBuildId: number;
|
||||
/** Number of backup files to keep, if the `backupOnSave` is TRUE */
|
||||
@@ -72,7 +72,7 @@ export declare type LDtkTileMap = {
|
||||
| null;
|
||||
};
|
||||
/** Auto-layer rule group */
|
||||
declare type LDtkAutoLayerRuleGroup = {
|
||||
type LDtkAutoLayerRuleGroup = {
|
||||
/** */
|
||||
active: boolean;
|
||||
/** *This field was removed in 1.0.0 and should no longer be used.* */
|
||||
@@ -87,9 +87,9 @@ declare type LDtkAutoLayerRuleGroup = {
|
||||
uid: integer;
|
||||
};
|
||||
/** This complex section isn't meant to be used by game devs at all, as these rules are completely resolved internally by the editor before any saving. You should just ignore this part. */
|
||||
declare type LDtkAutoRuleDef = {};
|
||||
type LDtkAutoRuleDef = {};
|
||||
/** If you're writing your own LDtk importer, you should probably just ignore *most* stuff in the `defs` section, as it contains data that are mostly important to the editor. To keep you away from the `defs` section and avoid some unnecessary JSON parsing, important data from definitions is often duplicated in fields prefixed with a double underscore (eg. `__identifier` or `__type`). The 2 only definition types you might need here are **Tilesets** and **Enums**. */
|
||||
declare type LDtkDefinition = {
|
||||
type LDtkDefinition = {
|
||||
/** All entities definitions, including their custom fields */
|
||||
entities: LDtkEntityDef[];
|
||||
/** All internal enums */
|
||||
@@ -104,7 +104,7 @@ declare type LDtkDefinition = {
|
||||
tilesets: LDtkTilesetDef[];
|
||||
};
|
||||
/** Entity definition */
|
||||
declare type LDtkEntityDef = {
|
||||
type LDtkEntityDef = {
|
||||
/** Base entity color */
|
||||
color: string;
|
||||
/** Array of field definitions */
|
||||
@@ -166,7 +166,7 @@ declare type LDtkEntityDef = {
|
||||
width: integer;
|
||||
};
|
||||
/** Entity instance */
|
||||
declare type LDtkEntityInstance = {
|
||||
type LDtkEntityInstance = {
|
||||
/** Grid-based coordinates (`[x,y]` format) */
|
||||
__grid: integer[];
|
||||
/** Entity definition identifier */
|
||||
@@ -193,7 +193,7 @@ declare type LDtkEntityInstance = {
|
||||
width: integer;
|
||||
};
|
||||
/** Enum definition */
|
||||
declare type LDtkEnumDef = {
|
||||
type LDtkEnumDef = {
|
||||
/** */
|
||||
externalFileChecksum: string | null;
|
||||
/** Relative path to the external file providing this Enum */
|
||||
@@ -210,7 +210,7 @@ declare type LDtkEnumDef = {
|
||||
values: LDtkEnumDefValues[];
|
||||
};
|
||||
/** Enum value definition */
|
||||
declare type LDtkEnumDefValues = {
|
||||
type LDtkEnumDefValues = {
|
||||
/** An array of 4 Int values that refers to the tile in the tileset image: `[ x, y, width, height ]` */
|
||||
__tileSrcRect: integer[] | null;
|
||||
/** Optional color */
|
||||
@@ -221,14 +221,14 @@ declare type LDtkEnumDefValues = {
|
||||
tileId: integer | null;
|
||||
};
|
||||
/** In a tileset definition, enum based tag infos */
|
||||
declare type LDtkEnumTagValue = {
|
||||
type LDtkEnumTagValue = {
|
||||
/** */
|
||||
enumValueId: string;
|
||||
/** */
|
||||
tileIds: integer[];
|
||||
};
|
||||
/** This section is mostly only intended for the LDtk editor app itself. You can safely ignore it. */
|
||||
declare type LDtkFieldDef = {
|
||||
type LDtkFieldDef = {
|
||||
/** Human readable value type. Possible values: `Int, Float, String, Bool, Color, ExternEnum.XXX, LocalEnum.XXX, Point, FilePath`.<br/> If the field is an array, this field will look like `Array<...>` (eg. `Array<Int>`, `Array<Point>` etc.)<br/> NOTE: if you enable the advanced option **Use Multilines type**, you will have \"*Multilines*\" instead of \"*String*\" when relevant. */
|
||||
__type: string;
|
||||
/** Optional list of accepted file extensions for FilePath value type. Includes the dot: `.ext` */
|
||||
@@ -310,7 +310,7 @@ declare type LDtkFieldDef = {
|
||||
useForSmartColor: boolean;
|
||||
};
|
||||
/** Field instance */
|
||||
declare type LDtkFieldInstance = {
|
||||
type LDtkFieldInstance = {
|
||||
/** Field definition identifier */
|
||||
__identifier: string;
|
||||
/** Optional TilesetRect used to display this field (this can be the field own Tile, or some other Tile guessed from the value, like an Enum). */
|
||||
@@ -324,7 +324,7 @@ declare type LDtkFieldInstance = {
|
||||
/** Editor internal raw values */
|
||||
realEditorValues: any[];
|
||||
};
|
||||
declare type LDtkFlag =
|
||||
type LDtkFlag =
|
||||
| 'DiscardPreCsvIntGrid'
|
||||
| 'ExportPreCsvIntGridFormat'
|
||||
| 'IgnoreBackupSuggest'
|
||||
@@ -332,7 +332,7 @@ declare type LDtkFlag =
|
||||
| 'MultiWorlds'
|
||||
| 'UseMultilinesType';
|
||||
/** IntGrid value definition */
|
||||
declare type LDtkIntGridValueDef = {
|
||||
type LDtkIntGridValueDef = {
|
||||
/** */
|
||||
color: string;
|
||||
/** User defined unique identifier */
|
||||
@@ -341,14 +341,14 @@ declare type LDtkIntGridValueDef = {
|
||||
value: integer;
|
||||
};
|
||||
/** IntGrid value instance */
|
||||
declare type LDtkIntGridValueInstance = {
|
||||
type LDtkIntGridValueInstance = {
|
||||
/** Coordinate ID in the layer grid */
|
||||
coordId: integer;
|
||||
/** IntGrid value */
|
||||
v: integer;
|
||||
};
|
||||
/** Layer definition */
|
||||
declare type LDtkLayerDef = {
|
||||
type LDtkLayerDef = {
|
||||
/** Type of the layer (*IntGrid, Entities, Tiles or AutoLayer*) */
|
||||
__type: string;
|
||||
/** Contains all the auto-layer rule definitions. */
|
||||
@@ -401,7 +401,7 @@ declare type LDtkLayerDef = {
|
||||
uid: integer;
|
||||
};
|
||||
/** Layer instance */
|
||||
declare type LDtkLayerInstance = {
|
||||
type LDtkLayerInstance = {
|
||||
/** Grid-based height */
|
||||
__cHei: integer;
|
||||
/** Grid-based width */
|
||||
@@ -452,7 +452,7 @@ declare type LDtkLayerInstance = {
|
||||
visible: boolean;
|
||||
};
|
||||
/** This section contains all the level data. It can be found in 2 distinct forms, depending on Project current settings: - If \"*Separate level files*\" is **disabled** (default): full level data is *embedded* inside the main Project JSON file, - If \"*Separate level files*\" is **enabled**: level data is stored in *separate* standalone `.ldtkl` files (one per level). In this case, the main Project JSON file will still contain most level data, except heavy sections, like the `layerInstances` array (which will be null). The `externalRelPath` string points to the `ldtkl` file. A `ldtkl` file is just a JSON file containing exactly what is described below. */
|
||||
declare type LDtkLevel = {
|
||||
type LDtkLevel = {
|
||||
/** Background color of the level (same as `bgColor`, except the default value is automatically used here if its value is `null`) */
|
||||
__bgColor: string;
|
||||
/** Position informations of the background image, if there is one. */
|
||||
@@ -497,7 +497,7 @@ declare type LDtkLevel = {
|
||||
worldY: integer;
|
||||
};
|
||||
/** Level background image position info */
|
||||
declare type LDtkLevelBgPosInfos = {
|
||||
type LDtkLevelBgPosInfos = {
|
||||
/** An array of 4 float values describing the cropped sub-rectangle of the displayed background image. This cropping happens when original is larger than the level bounds. Array format: `[ cropX, cropY, cropWidth, cropHeight ]` */
|
||||
cropRect: number[];
|
||||
/** An array containing the `[scaleX,scaleY]` values of the **cropped** background image, depending on `bgPos` option. */
|
||||
@@ -506,7 +506,7 @@ declare type LDtkLevelBgPosInfos = {
|
||||
topLeftPx: integer[];
|
||||
};
|
||||
/** Nearby level info */
|
||||
declare type LDtkNeighbourLevel = {
|
||||
type LDtkNeighbourLevel = {
|
||||
/** A single lowercase character tipping on the level location (`n`orth, `s`outh, `w`est, `e`ast). */
|
||||
dir: string;
|
||||
/** Neighbour Instance Identifier */
|
||||
@@ -515,7 +515,7 @@ declare type LDtkNeighbourLevel = {
|
||||
levelUid: integer;
|
||||
};
|
||||
/** This structure represents a single tile from a given Tileset. */
|
||||
declare type LDtkTile = {
|
||||
type LDtkTile = {
|
||||
/** Internal data used by the editor.<br/> For auto-layer tiles: `[ruleId, coordId]`.<br/> For tile-layer tiles: `[coordId]`. */
|
||||
d: integer[];
|
||||
/** \"Flip bits\", a 2-bits integer to represent the mirror transformations of the tile.<br/> - Bit 0 = X flip<br/> - Bit 1 = Y flip<br/> Examples: f=0 (no flip), f=1 (X flip only), f=2 (Y flip only), f=3 (both flips) */
|
||||
@@ -528,7 +528,7 @@ declare type LDtkTile = {
|
||||
t: integer;
|
||||
};
|
||||
/** The `Tileset` definition is the most important part among project definitions. It contains some extra informations about each integrated tileset. If you only had to parse one definition section, that would be the one. */
|
||||
export declare type LDtkTilesetDef = {
|
||||
export type LDtkTilesetDef = {
|
||||
/** Grid-based height */
|
||||
__cHei: integer;
|
||||
/** Grid-based width */
|
||||
@@ -565,14 +565,14 @@ export declare type LDtkTilesetDef = {
|
||||
uid: integer;
|
||||
};
|
||||
/** In a tileset definition, user defined meta-data of a tile. */
|
||||
declare type LDtkTileCustomMetadata = {
|
||||
type LDtkTileCustomMetadata = {
|
||||
/** */
|
||||
data: string;
|
||||
/** */
|
||||
tileId: integer;
|
||||
};
|
||||
/** This object represents a custom sub rectangle in a Tileset image. */
|
||||
declare type LDtkTilesetRect = {
|
||||
type LDtkTilesetRect = {
|
||||
/** Height in pixels */
|
||||
h: integer;
|
||||
/** UID of the tileset */
|
||||
@@ -584,6 +584,6 @@ declare type LDtkTilesetRect = {
|
||||
/** Y pixels coordinate of the top-left corner in the Tileset image */
|
||||
y: integer;
|
||||
};
|
||||
declare type LDtkWorld = {};
|
||||
type LDtkWorld = {};
|
||||
export {};
|
||||
//# sourceMappingURL=LDtkFormat.d.ts.map
|
||||
|
File diff suppressed because one or more lines are too long
@@ -2,7 +2,7 @@ import { float, integer } from '../../model/CommonTypes';
|
||||
/**
|
||||
* Tiled JSON format (https://github.com/mapeditor/tiled/blob/master/docs/reference/json-map-format.rst).
|
||||
*/
|
||||
export declare type TiledTileMap = {
|
||||
export type TiledTileMap = {
|
||||
/** Hex-formatted color (#RRGGBB or #AARRGGBB) (optional) */
|
||||
backgroundcolor?: string;
|
||||
/** The compression level to use for tile layer data (defaults to -1, which means to use the algorithm default) */
|
||||
@@ -44,7 +44,7 @@ export declare type TiledTileMap = {
|
||||
/** Number of tile columns */
|
||||
width: integer;
|
||||
};
|
||||
export declare type TiledLayer = {
|
||||
export type TiledLayer = {
|
||||
/** Array of {@link TiledChunk} (optional). `tilelayer` only. */
|
||||
chunks?: Array<TiledChunk>;
|
||||
/** `zlib`, `gzip`, `zstd` (since Tiled 1.3) or empty (default). `tilelayer` only. */
|
||||
@@ -98,7 +98,7 @@ export declare type TiledLayer = {
|
||||
/** Vertical layer offset in tiles. Always 0. */
|
||||
y: integer;
|
||||
};
|
||||
export declare type TiledChunk = {
|
||||
export type TiledChunk = {
|
||||
/** Array of `unsigned` `integer` (GIDs) or base64-encoded data */
|
||||
data: Array<integer> | string;
|
||||
/** Height in tiles */
|
||||
@@ -110,7 +110,7 @@ export declare type TiledChunk = {
|
||||
/** Y coordinate in tiles */
|
||||
y: integer;
|
||||
};
|
||||
export declare type TiledObject = {
|
||||
export type TiledObject = {
|
||||
/** The class of the object (was saved as class in 1.9, optional) */
|
||||
type?: string;
|
||||
/** The class of the object (used only in 1.9, optional) */
|
||||
@@ -148,7 +148,7 @@ export declare type TiledObject = {
|
||||
/** Y coordinate in pixels */
|
||||
y: float;
|
||||
};
|
||||
export declare type TiledText = {
|
||||
export type TiledText = {
|
||||
/** Whether to use a bold font (default: `false`) */
|
||||
bold: boolean;
|
||||
/** Hex-formatted color (#RRGGBB or #AARRGGBB) (default: `#000000`) */
|
||||
@@ -174,7 +174,7 @@ export declare type TiledText = {
|
||||
/** Whether the text is wrapped within the object bounds (default: `false`) */
|
||||
wrap: boolean;
|
||||
};
|
||||
export declare type TiledTileset = {
|
||||
export type TiledTileset = {
|
||||
/** Hex-formatted color (#RRGGBB or #AARRGGBB) (optional) */
|
||||
backgroundcolor?: string;
|
||||
/** The number of tile columns in the tileset */
|
||||
@@ -226,7 +226,7 @@ export declare type TiledTileset = {
|
||||
/** Array of {@link TiledWangSet} (since 1.1.5) */
|
||||
wangsets?: Array<TiledWangSet>;
|
||||
};
|
||||
export declare type TiledGrid = {
|
||||
export type TiledGrid = {
|
||||
/** Cell height of tile grid */
|
||||
height: integer;
|
||||
/** `orthogonal` (default) or `isometric` */
|
||||
@@ -234,13 +234,13 @@ export declare type TiledGrid = {
|
||||
/** Cell width of tile grid */
|
||||
width: integer;
|
||||
};
|
||||
export declare type TileOffset = {
|
||||
export type TileOffset = {
|
||||
/** Horizontal offset in pixels */
|
||||
x: integer;
|
||||
/** Vertical offset in pixels (positive is down) */
|
||||
y: integer;
|
||||
};
|
||||
export declare type TiledTransformations = {
|
||||
export type TiledTransformations = {
|
||||
/** Tiles can be flipped horizontally */
|
||||
hflip: boolean;
|
||||
/** Tiles can be flipped vertically */
|
||||
@@ -250,7 +250,7 @@ export declare type TiledTransformations = {
|
||||
/** Whether untransformed tiles remain preferred, otherwise transformed tiles are used to produce more variations */
|
||||
preferuntransformed: boolean;
|
||||
};
|
||||
export declare type TiledTileDefinition = {
|
||||
export type TiledTileDefinition = {
|
||||
/** Array of {@link TiledTiles} */
|
||||
animation?: Array<TiledTileDefinition>;
|
||||
/** The class of the object (was saved as class in 1.9, optional) */
|
||||
@@ -274,13 +274,13 @@ export declare type TiledTileDefinition = {
|
||||
/** Index of terrain for each corner of tile (optional) */
|
||||
terrain?: Array<integer>;
|
||||
};
|
||||
export declare type TiledFrame = {
|
||||
export type TiledFrame = {
|
||||
/** Frame duration in milliseconds */
|
||||
duration: integer;
|
||||
/** Local tile ID representing this frame */
|
||||
tileid: integer;
|
||||
};
|
||||
export declare type TiledTerrain = {
|
||||
export type TiledTerrain = {
|
||||
/** Name of terrain */
|
||||
name: string;
|
||||
/** Array of {@link TiledProperty} */
|
||||
@@ -288,7 +288,7 @@ export declare type TiledTerrain = {
|
||||
/** Local ID of tile representing terrain */
|
||||
tile: integer;
|
||||
};
|
||||
export declare type TiledWangSet = {
|
||||
export type TiledWangSet = {
|
||||
/** Array of {@link TiledWangColor} */
|
||||
colors: Array<TiledWangColor>;
|
||||
/** Name of the Wang set */
|
||||
@@ -300,7 +300,7 @@ export declare type TiledWangSet = {
|
||||
/** Array of {@link TiledWangTile} */
|
||||
wangtiles: Array<TiledWangTile>;
|
||||
};
|
||||
export declare type TiledWangColor = {
|
||||
export type TiledWangColor = {
|
||||
/** Hex-formatted color (#RRGGBB or #AARRGGBB) */
|
||||
color: string;
|
||||
/** Name of the Wang color */
|
||||
@@ -312,13 +312,13 @@ export declare type TiledWangColor = {
|
||||
/** Local ID of tile representing the Wang color */
|
||||
tile: integer;
|
||||
};
|
||||
export declare type TiledWangTile = {
|
||||
export type TiledWangTile = {
|
||||
/** Local ID of tile */
|
||||
tileid: integer;
|
||||
/** Array of Wang color indexes (`uchar[8]`) */
|
||||
wangid: Array<integer>;
|
||||
};
|
||||
export declare type TiledObjectTemplate = {
|
||||
export type TiledObjectTemplate = {
|
||||
/** `template` */
|
||||
type: string;
|
||||
/** External tileset used by the template (optional) */
|
||||
@@ -326,7 +326,7 @@ export declare type TiledObjectTemplate = {
|
||||
/** The object instantiated by this template */
|
||||
object: Object;
|
||||
};
|
||||
export declare type TiledProperty = {
|
||||
export type TiledProperty = {
|
||||
/** Name of the property */
|
||||
name: string;
|
||||
/** type of the property (`string` (default), `integer`, `float`, `boolean`, `color` or `file` (since 0.16, with `color` and `file` added in 0.17)) */
|
||||
@@ -334,7 +334,7 @@ export declare type TiledProperty = {
|
||||
/** Value of the property */
|
||||
value: string | number;
|
||||
};
|
||||
export declare type TiledPoint = {
|
||||
export type TiledPoint = {
|
||||
/** X coordinate in pixels */
|
||||
x: float;
|
||||
/** Y coordinate in pixels */
|
||||
|
File diff suppressed because one or more lines are too long
@@ -12,7 +12,7 @@ export declare const decodeBase64LayerData: (
|
||||
pako: any,
|
||||
tiledLayer: TiledLayer
|
||||
) => number[];
|
||||
export declare type TiledGID = {
|
||||
export type TiledGID = {
|
||||
id: integer;
|
||||
flippedHorizontally: boolean;
|
||||
flippedVertically: boolean;
|
||||
|
@@ -1 +1 @@
|
||||
{"version":3,"file":"TiledTileMapLoaderHelper.d.ts","sourceRoot":"","sources":["../../../src/load/tiled/TiledTileMapLoaderHelper.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,SAAU,GAAG,cAAc,UAAU,aAgDtE,CAAC;AAEF,oBAAY,QAAQ,GAAG;IACrB,EAAE,EAAE,OAAO,CAAC;IACZ,mBAAmB,EAAE,OAAO,CAAC;IAC7B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,iBAAiB,EAAE,OAAO,CAAC;CAC5B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,kBACvB,OAAO,KACrB,QAmBF,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,MAAM,GAAG,SAAS,CAEpB"}
|
||||
{"version":3,"file":"TiledTileMapLoaderHelper.d.ts","sourceRoot":"","sources":["../../../src/load/tiled/TiledTileMapLoaderHelper.ts"],"names":[],"mappings":"AAKA,OAAO,EAAE,OAAO,EAAE,MAAM,yBAAyB,CAAC;AAClD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,SAAU,GAAG,cAAc,UAAU,aAgDtE,CAAC;AAEF,MAAM,MAAM,QAAQ,GAAG;IACrB,EAAE,EAAE,OAAO,CAAC;IACZ,mBAAmB,EAAE,OAAO,CAAC;IAC7B,iBAAiB,EAAE,OAAO,CAAC;IAC3B,iBAAiB,EAAE,OAAO,CAAC;CAC5B,CAAC;AAEF;;;;GAIG;AACH,eAAO,MAAM,2BAA2B,kBACvB,OAAO,KACrB,QAmBF,CAAC;AAEF;;;;GAIG;AACH,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,GAAG,SAAS,GAC3B,MAAM,GAAG,SAAS,CAEpB"}
|
@@ -1,5 +1,5 @@
|
||||
export declare type integer = number;
|
||||
export declare type float = number;
|
||||
export declare type FloatPoint = [float, float];
|
||||
export declare type PolygonVertices = FloatPoint[];
|
||||
export type FloatPoint = [float, float];
|
||||
export type PolygonVertices = FloatPoint[];
|
||||
//# sourceMappingURL=CommonTypes.d.ts.map
|
||||
|
@@ -1 +1 @@
|
||||
{"version":3,"file":"CommonTypes.d.ts","sourceRoot":"","sources":["../../src/model/CommonTypes.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,MAAM,OAAO,GAAG,MAAM,CAAC;AACrC,MAAM,CAAC,OAAO,MAAM,KAAK,GAAG,MAAM,CAAC;AACnC,oBAAY,UAAU,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAExC,oBAAY,eAAe,GAAG,UAAU,EAAE,CAAC"}
|
||||
{"version":3,"file":"CommonTypes.d.ts","sourceRoot":"","sources":["../../src/model/CommonTypes.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,OAAO,MAAM,OAAO,GAAG,MAAM,CAAC;AACrC,MAAM,CAAC,OAAO,MAAM,KAAK,GAAG,MAAM,CAAC;AACnC,MAAM,MAAM,UAAU,GAAG,CAAC,KAAK,EAAE,KAAK,CAAC,CAAC;AAExC,MAAM,MAAM,eAAe,GAAG,UAAU,EAAE,CAAC"}
|
@@ -65,5 +65,6 @@ export declare class TileMapManager {
|
||||
levelIndex: number,
|
||||
callback: (textureCache: TileTextureCache | null) => void
|
||||
): void;
|
||||
clearCaches(): void;
|
||||
}
|
||||
//# sourceMappingURL=TileMapManager.d.ts.map
|
||||
|
@@ -1 +1 @@
|
||||
{"version":3,"file":"TileMapManager.d.ts","sourceRoot":"","sources":["../../src/render/TileMapManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAEhE;;;;;;;GAOG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,aAAa,CAAiC;IACtD,OAAO,CAAC,mBAAmB,CAAkC;;IAO7D;;;OAGG;IACH,MAAM,CAAC,UAAU,CAAC,cAAc,EAAE,MAAM,GAAG,cAAc;IAWzD;;;OAGG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,GAAG,kBAAkB,GAAG,IAAI;IAwBrD;;;;;;;OAOG;IACH,gBAAgB,CACd,WAAW,EAAE,CACX,uBAAuB,EAAE,MAAM,EAC/B,uBAAuB,EAAE,MAAM,EAC/B,QAAQ,EAAE,CAAC,kBAAkB,EAAE,kBAAkB,GAAG,IAAI,KAAK,IAAI,KAC9D,IAAI,EACT,uBAAuB,EAAE,MAAM,EAC/B,uBAAuB,EAAE,MAAM,EAC/B,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,GAAG,EACT,QAAQ,EAAE,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,KAAK,IAAI,GAClD,IAAI;IAiCP;;;;;;;;OAQG;IACH,qBAAqB,CACnB,WAAW,EAAE,CACX,uBAAuB,EAAE,MAAM,EAC/B,uBAAuB,EAAE,MAAM,EAC/B,QAAQ,EAAE,CAAC,kBAAkB,EAAE,kBAAkB,GAAG,IAAI,KAAK,IAAI,KAC9D,IAAI,EACT,UAAU,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,EACpE,sBAAsB,EAAE,MAAM,EAC9B,uBAAuB,EAAE,MAAM,EAC/B,uBAAuB,EAAE,MAAM,EAC/B,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,CAAC,YAAY,EAAE,gBAAgB,GAAG,IAAI,KAAK,IAAI,GACxD,IAAI;CAuCR"}
|
||||
{"version":3,"file":"TileMapManager.d.ts","sourceRoot":"","sources":["../../src/render/TileMapManager.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,eAAe,EAAE,MAAM,uBAAuB,CAAC;AACxD,OAAO,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAGtD,OAAO,EAAE,kBAAkB,EAAE,MAAM,4BAA4B,CAAC;AAEhE;;;;;;;GAOG;AACH,qBAAa,cAAc;IACzB,OAAO,CAAC,aAAa,CAAiC;IACtD,OAAO,CAAC,mBAAmB,CAAkC;;IAO7D;;;OAGG;IACH,MAAM,CAAC,UAAU,CAAC,cAAc,EAAE,MAAM,GAAG,cAAc;IAWzD;;;OAGG;IACH,MAAM,CAAC,QAAQ,CAAC,IAAI,EAAE,GAAG,GAAG,kBAAkB,GAAG,IAAI;IAwBrD;;;;;;;OAOG;IACH,gBAAgB,CACd,WAAW,EAAE,CACX,uBAAuB,EAAE,MAAM,EAC/B,uBAAuB,EAAE,MAAM,EAC/B,QAAQ,EAAE,CAAC,kBAAkB,EAAE,kBAAkB,GAAG,IAAI,KAAK,IAAI,KAC9D,IAAI,EACT,uBAAuB,EAAE,MAAM,EAC/B,uBAAuB,EAAE,MAAM,EAC/B,UAAU,EAAE,MAAM,EAClB,IAAI,EAAE,GAAG,EACT,QAAQ,EAAE,CAAC,OAAO,EAAE,eAAe,GAAG,IAAI,KAAK,IAAI,GAClD,IAAI;IAiCP;;;;;;;;OAQG;IACH,qBAAqB,CACnB,WAAW,EAAE,CACX,uBAAuB,EAAE,MAAM,EAC/B,uBAAuB,EAAE,MAAM,EAC/B,QAAQ,EAAE,CAAC,kBAAkB,EAAE,kBAAkB,GAAG,IAAI,KAAK,IAAI,KAC9D,IAAI,EACT,UAAU,EAAE,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,EACpE,sBAAsB,EAAE,MAAM,EAC9B,uBAAuB,EAAE,MAAM,EAC/B,uBAAuB,EAAE,MAAM,EAC/B,UAAU,EAAE,MAAM,EAClB,QAAQ,EAAE,CAAC,YAAY,EAAE,gBAAgB,GAAG,IAAI,KAAK,IAAI,GACxD,IAAI;IAwCP,WAAW,IAAI,IAAI;CAIpB"}
|
@@ -1,9 +1,7 @@
|
||||
import { TileTextureCache } from '../TileTextureCache';
|
||||
import { LDtkTileMap } from '../../load/ldtk/LDtkFormat';
|
||||
declare type Texture = PIXI.BaseTexture<PIXI.Resource>;
|
||||
declare type TextureLoader = (
|
||||
textureName: string
|
||||
) => PIXI.BaseTexture<PIXI.Resource>;
|
||||
type Texture = PIXI.BaseTexture<PIXI.Resource>;
|
||||
type TextureLoader = (textureName: string) => PIXI.BaseTexture<PIXI.Resource>;
|
||||
export declare namespace LDtkPixiHelper {
|
||||
/**
|
||||
* Split an atlas image into Pixi textures.
|
||||
|
@@ -1 +1 @@
|
||||
{"version":3,"file":"LDtkPixiHelper.d.ts","sourceRoot":"","sources":["../../../src/render/ldtk/LDtkPixiHelper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAkB,MAAM,4BAA4B,CAAC;AAGzE,aAAK,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC/C,aAAK,aAAa,GAAG,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAmC9E,yBAAiB,cAAc,CAAC;IAC9B;;;;;;;;OAQG;IACH,SAAgB,UAAU,CACxB,OAAO,EAAE,WAAW,EACpB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,OAAO,GAAG,IAAI,EAC5B,UAAU,EAAE,aAAa,GACxB,gBAAgB,GAAG,IAAI,CAoFzB;CACF"}
|
||||
{"version":3,"file":"LDtkPixiHelper.d.ts","sourceRoot":"","sources":["../../../src/render/ldtk/LDtkPixiHelper.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AACvD,OAAO,EAAE,WAAW,EAAkB,MAAM,4BAA4B,CAAC;AAGzE,KAAK,OAAO,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAC/C,KAAK,aAAa,GAAG,CAAC,WAAW,EAAE,MAAM,KAAK,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;AAmC9E,yBAAiB,cAAc,CAAC;IAC9B;;;;;;;;OAQG;IACH,SAAgB,UAAU,CACxB,OAAO,EAAE,WAAW,EACpB,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,OAAO,GAAG,IAAI,EAC5B,UAAU,EAAE,aAAa,GACxB,gBAAgB,GAAG,IAAI,CAoFzB;CACF"}
|
@@ -2296,6 +2296,7 @@ interface VectorUnfilledRequiredBehaviorPropertyProblem {
|
||||
|
||||
interface ProjectBrowserHelper {
|
||||
void STATIC_ExposeProjectEvents([Ref] Project project, [Ref] ArbitraryEventsWorker worker);
|
||||
void STATIC_ExposeProjectObjects([Ref] Project project, [Ref] ArbitraryObjectsWorker worker);
|
||||
};
|
||||
|
||||
interface ResourceExposer {
|
||||
@@ -2884,6 +2885,10 @@ interface ArbitraryEventsWorker {
|
||||
void Launch([Ref] EventsList events);
|
||||
};
|
||||
|
||||
interface ArbitraryObjectsWorker {
|
||||
void Launch([Ref] ObjectsContainer container);
|
||||
};
|
||||
|
||||
interface EventsLeaderboardsLister {
|
||||
void EventsLeaderboardsLister([Ref] Project project);
|
||||
[Const, Ref] SetString GetLeaderboardIds();
|
||||
@@ -2980,6 +2985,14 @@ interface ProjectResourcesCopier {
|
||||
boolean preserveDirectoryStructure);
|
||||
};
|
||||
|
||||
interface ObjectsUsingResourceCollector {
|
||||
void ObjectsUsingResourceCollector([Const] DOMString resourceName);
|
||||
[Const, Ref] VectorString GetObjectNames();
|
||||
|
||||
//Inherited from ArbitraryObjectsWorker
|
||||
void Launch([Ref] ObjectsContainer container);
|
||||
};
|
||||
|
||||
interface ResourcesInUseHelper {
|
||||
void ResourcesInUseHelper();
|
||||
|
||||
|
@@ -47,6 +47,8 @@
|
||||
#include <GDCore/IDE/Events/EventsIdentifiersFinder.h>
|
||||
#include <GDCore/IDE/Events/EventsFunctionSelfCallChecker.h>
|
||||
#include <GDCore/IDE/Project/ArbitraryResourceWorker.h>
|
||||
#include <GDCore/IDE/Project/ArbitraryObjectsWorker.h>
|
||||
#include <GDCore/IDE/Project/ObjectsUsingResourceCollector.h>
|
||||
#include <GDCore/IDE/Project/ProjectResourcesAdder.h>
|
||||
#include <GDCore/IDE/Project/ProjectResourcesCopier.h>
|
||||
#include <GDCore/IDE/Project/ResourcesInUseHelper.h>
|
||||
@@ -574,6 +576,7 @@ typedef ExtensionAndMetadata<ExpressionMetadata> ExtensionAndExpressionMetadata;
|
||||
#define STATIC_RemoveObjectInEvents RemoveObjectInEvents
|
||||
#define STATIC_ReplaceStringInEvents ReplaceStringInEvents
|
||||
#define STATIC_ExposeProjectEvents ExposeProjectEvents
|
||||
#define STATIC_ExposeProjectObjects ExposeProjectObjects
|
||||
#define STATIC_ExposeWholeProjectResources ExposeWholeProjectResources
|
||||
|
||||
#define STATIC_GetBehaviorMetadata GetBehaviorMetadata
|
||||
|
@@ -1556,6 +1556,73 @@ describe('libGD.js', function () {
|
||||
});
|
||||
});
|
||||
|
||||
describe('gd.ObjectsUsingResourceCollector', function () {
|
||||
it('lists objects that use the given resources', function () {
|
||||
const project = gd.ProjectHelper.createNewGDJSProject();
|
||||
const layout = project.insertNewLayout('Scene', 0);
|
||||
|
||||
const object = layout.insertNewObject(project, 'Sprite', 'MyObject', 0);
|
||||
const sprite1 = new gd.Sprite();
|
||||
sprite1.setImageName('Image1');
|
||||
const sprite2 = new gd.Sprite();
|
||||
sprite2.setImageName('Image2');
|
||||
const sprite3 = new gd.Sprite();
|
||||
sprite3.setImageName('Image3');
|
||||
|
||||
const spriteObject = gd.asSpriteConfiguration(object.getConfiguration());
|
||||
const animation = new gd.Animation();
|
||||
animation.setDirectionsCount(1);
|
||||
animation.getDirection(0).addSprite(sprite1);
|
||||
animation.getDirection(0).addSprite(sprite2);
|
||||
animation.getDirection(0).addSprite(sprite1);
|
||||
spriteObject.addAnimation(animation);
|
||||
|
||||
const object2 = project.insertNewObject(
|
||||
project,
|
||||
'Sprite',
|
||||
'MyObject2',
|
||||
0
|
||||
);
|
||||
const spriteObject2 = gd.asSpriteConfiguration(
|
||||
object2.getConfiguration()
|
||||
);
|
||||
const animation2 = new gd.Animation();
|
||||
animation2.setDirectionsCount(1);
|
||||
animation2.getDirection(0).addSprite(sprite1);
|
||||
animation2.getDirection(0).addSprite(sprite3);
|
||||
animation2.getDirection(0).addSprite(sprite1);
|
||||
spriteObject2.addAnimation(animation2);
|
||||
|
||||
{
|
||||
const objectsCollector = new gd.ObjectsUsingResourceCollector('Image1');
|
||||
gd.ProjectBrowserHelper.exposeProjectObjects(project, objectsCollector);
|
||||
const objectNames = objectsCollector.getObjectNames().toJSArray();
|
||||
objectsCollector.delete();
|
||||
expect(objectNames.length).toEqual(2);
|
||||
expect(objectNames).toContain('MyObject');
|
||||
expect(objectNames).toContain('MyObject2');
|
||||
}
|
||||
{
|
||||
const objectsCollector = new gd.ObjectsUsingResourceCollector('Image2');
|
||||
gd.ProjectBrowserHelper.exposeProjectObjects(project, objectsCollector);
|
||||
const objectNames = objectsCollector.getObjectNames().toJSArray();
|
||||
objectsCollector.delete();
|
||||
expect(objectNames.length).toEqual(1);
|
||||
expect(objectNames).toContain('MyObject');
|
||||
}
|
||||
{
|
||||
const objectsCollector = new gd.ObjectsUsingResourceCollector('Image3');
|
||||
gd.ProjectBrowserHelper.exposeProjectObjects(project, objectsCollector);
|
||||
const objectNames = objectsCollector.getObjectNames().toJSArray();
|
||||
objectsCollector.delete();
|
||||
expect(objectNames.length).toEqual(1);
|
||||
expect(objectNames).toContain('MyObject2');
|
||||
}
|
||||
|
||||
project.delete();
|
||||
});
|
||||
});
|
||||
|
||||
describe('gd.Behavior', function () {
|
||||
it('update a not existing property', function () {
|
||||
const project = gd.ProjectHelper.createNewGDJSProject();
|
||||
|
6
GDevelop.js/types/gdarbitraryobjectsworker.js
Normal file
6
GDevelop.js/types/gdarbitraryobjectsworker.js
Normal file
@@ -0,0 +1,6 @@
|
||||
// Automatically generated by GDevelop.js/scripts/generate-types.js
|
||||
declare class gdArbitraryObjectsWorker {
|
||||
launch(container: gdObjectsContainer): void;
|
||||
delete(): void;
|
||||
ptr: number;
|
||||
};
|
8
GDevelop.js/types/gdobjectsusingresourcecollector.js
Normal file
8
GDevelop.js/types/gdobjectsusingresourcecollector.js
Normal file
@@ -0,0 +1,8 @@
|
||||
// Automatically generated by GDevelop.js/scripts/generate-types.js
|
||||
declare class gdObjectsUsingResourceCollector {
|
||||
constructor(resourceName: string): void;
|
||||
getObjectNames(): gdVectorString;
|
||||
launch(container: gdObjectsContainer): void;
|
||||
delete(): void;
|
||||
ptr: number;
|
||||
};
|
@@ -1,6 +1,7 @@
|
||||
// Automatically generated by GDevelop.js/scripts/generate-types.js
|
||||
declare class gdProjectBrowserHelper {
|
||||
static exposeProjectEvents(project: gdProject, worker: gdArbitraryEventsWorker): void;
|
||||
static exposeProjectObjects(project: gdProject, worker: gdArbitraryObjectsWorker): void;
|
||||
delete(): void;
|
||||
ptr: number;
|
||||
};
|
@@ -201,6 +201,7 @@ declare class libGDevelop {
|
||||
AbstractFileSystemJS: Class<gdAbstractFileSystemJS>;
|
||||
ProjectResourcesAdder: Class<gdProjectResourcesAdder>;
|
||||
ArbitraryEventsWorker: Class<gdArbitraryEventsWorker>;
|
||||
ArbitraryObjectsWorker: Class<gdArbitraryObjectsWorker>;
|
||||
EventsLeaderboardsLister: Class<gdEventsLeaderboardsLister>;
|
||||
EventsLeaderboardsRenamer: Class<gdEventsLeaderboardsRenamer>;
|
||||
EventsParametersLister: Class<gdEventsParametersLister>;
|
||||
@@ -214,6 +215,7 @@ declare class libGDevelop {
|
||||
ResourcesMergingHelper: Class<gdResourcesMergingHelper>;
|
||||
ResourcesRenamer: Class<gdResourcesRenamer>;
|
||||
ProjectResourcesCopier: Class<gdProjectResourcesCopier>;
|
||||
ObjectsUsingResourceCollector: Class<gdObjectsUsingResourceCollector>;
|
||||
ResourcesInUseHelper: Class<gdResourcesInUseHelper>;
|
||||
EditorSettings: Class<gdEditorSettings>;
|
||||
Point: Class<gdPoint>;
|
||||
|
@@ -177,4 +177,9 @@ export class TileMapManager {
|
||||
callback
|
||||
);
|
||||
}
|
||||
|
||||
clearCaches(): void {
|
||||
this._tileMapCache = new ResourceCache<EditableTileMap>();
|
||||
this._textureCacheCaches = new ResourceCache<TileTextureCache>();
|
||||
}
|
||||
}
|
||||
|
41
newIDE/app/package-lock.json
generated
41
newIDE/app/package-lock.json
generated
@@ -20,6 +20,7 @@
|
||||
"algoliasearch": "3.33.0",
|
||||
"axios": "^0.18.1",
|
||||
"blueimp-md5": "^2.10.0",
|
||||
"chokidar": "3.5.3",
|
||||
"classnames": "2.2.5",
|
||||
"date-fns": "2.16.1",
|
||||
"element-closest": "2.0.2",
|
||||
@@ -12158,7 +12159,6 @@
|
||||
},
|
||||
"node_modules/anymatch": {
|
||||
"version": "3.1.2",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"normalize-path": "^3.0.0",
|
||||
@@ -13218,7 +13218,6 @@
|
||||
},
|
||||
"node_modules/binary-extensions": {
|
||||
"version": "2.1.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
@@ -13347,7 +13346,6 @@
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"fill-range": "^7.0.1"
|
||||
},
|
||||
@@ -13751,7 +13749,6 @@
|
||||
},
|
||||
"node_modules/chokidar": {
|
||||
"version": "3.5.3",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "individual",
|
||||
@@ -17316,7 +17313,6 @@
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
},
|
||||
@@ -18217,7 +18213,6 @@
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||
"dev": true,
|
||||
"hasInstallScript": true,
|
||||
"optional": true,
|
||||
"os": [
|
||||
@@ -18412,7 +18407,6 @@
|
||||
},
|
||||
"node_modules/glob-parent": {
|
||||
"version": "5.1.2",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"is-glob": "^4.0.1"
|
||||
@@ -19557,7 +19551,6 @@
|
||||
},
|
||||
"node_modules/is-binary-path": {
|
||||
"version": "2.1.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"binary-extensions": "^2.0.0"
|
||||
@@ -19686,7 +19679,6 @@
|
||||
},
|
||||
"node_modules/is-extglob": {
|
||||
"version": "2.1.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -19740,7 +19732,6 @@
|
||||
},
|
||||
"node_modules/is-glob": {
|
||||
"version": "4.0.3",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"is-extglob": "^2.1.1"
|
||||
@@ -19808,7 +19799,6 @@
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.12.0"
|
||||
}
|
||||
@@ -25852,7 +25842,6 @@
|
||||
},
|
||||
"node_modules/normalize-path": {
|
||||
"version": "3.0.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
@@ -26624,7 +26613,6 @@
|
||||
},
|
||||
"node_modules/picomatch": {
|
||||
"version": "2.3.1",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8.6"
|
||||
@@ -30884,7 +30872,6 @@
|
||||
},
|
||||
"node_modules/readdirp": {
|
||||
"version": "3.6.0",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"picomatch": "^2.2.1"
|
||||
@@ -33770,7 +33757,6 @@
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-number": "^7.0.0"
|
||||
},
|
||||
@@ -44460,7 +44446,6 @@
|
||||
},
|
||||
"anymatch": {
|
||||
"version": "3.1.2",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"normalize-path": "^3.0.0",
|
||||
"picomatch": "^2.0.4"
|
||||
@@ -45249,8 +45234,7 @@
|
||||
"dev": true
|
||||
},
|
||||
"binary-extensions": {
|
||||
"version": "2.1.0",
|
||||
"dev": true
|
||||
"version": "2.1.0"
|
||||
},
|
||||
"bl": {
|
||||
"version": "4.1.0",
|
||||
@@ -45358,7 +45342,6 @@
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/braces/-/braces-3.0.2.tgz",
|
||||
"integrity": "sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fill-range": "^7.0.1"
|
||||
}
|
||||
@@ -45605,7 +45588,6 @@
|
||||
},
|
||||
"chokidar": {
|
||||
"version": "3.5.3",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"anymatch": "~3.1.2",
|
||||
"braces": "~3.0.2",
|
||||
@@ -48161,7 +48143,6 @@
|
||||
"version": "7.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz",
|
||||
"integrity": "sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"to-regex-range": "^5.0.1"
|
||||
}
|
||||
@@ -48811,7 +48792,6 @@
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
|
||||
"integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
|
||||
"dev": true,
|
||||
"optional": true
|
||||
},
|
||||
"function-bind": {
|
||||
@@ -48933,7 +48913,6 @@
|
||||
},
|
||||
"glob-parent": {
|
||||
"version": "5.1.2",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-glob": "^4.0.1"
|
||||
}
|
||||
@@ -49701,7 +49680,6 @@
|
||||
},
|
||||
"is-binary-path": {
|
||||
"version": "2.1.0",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"binary-extensions": "^2.0.0"
|
||||
}
|
||||
@@ -49761,8 +49739,7 @@
|
||||
"version": "2.1.1"
|
||||
},
|
||||
"is-extglob": {
|
||||
"version": "2.1.1",
|
||||
"dev": true
|
||||
"version": "2.1.1"
|
||||
},
|
||||
"is-finite": {
|
||||
"version": "1.1.0",
|
||||
@@ -49792,7 +49769,6 @@
|
||||
},
|
||||
"is-glob": {
|
||||
"version": "4.0.3",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-extglob": "^2.1.1"
|
||||
}
|
||||
@@ -49835,8 +49811,7 @@
|
||||
"is-number": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz",
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng==",
|
||||
"dev": true
|
||||
"integrity": "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="
|
||||
},
|
||||
"is-number-object": {
|
||||
"version": "1.0.7",
|
||||
@@ -54247,8 +54222,7 @@
|
||||
}
|
||||
},
|
||||
"normalize-path": {
|
||||
"version": "3.0.0",
|
||||
"dev": true
|
||||
"version": "3.0.0"
|
||||
},
|
||||
"normalize-range": {
|
||||
"version": "0.1.2",
|
||||
@@ -54776,8 +54750,7 @@
|
||||
"dev": true
|
||||
},
|
||||
"picomatch": {
|
||||
"version": "2.3.1",
|
||||
"dev": true
|
||||
"version": "2.3.1"
|
||||
},
|
||||
"pify": {
|
||||
"version": "4.0.1"
|
||||
@@ -57558,7 +57531,6 @@
|
||||
},
|
||||
"readdirp": {
|
||||
"version": "3.6.0",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"picomatch": "^2.2.1"
|
||||
}
|
||||
@@ -59629,7 +59601,6 @@
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz",
|
||||
"integrity": "sha512-65P7iz6X5yEr1cwcgvQxbbIw7Uk3gOy5dIdtZ4rDveLqhrdJP+Li/Hx6tyK0NEb+2GCyneCMJiGqrADCSNk8sQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"is-number": "^7.0.0"
|
||||
}
|
||||
|
@@ -50,6 +50,7 @@
|
||||
"algoliasearch": "3.33.0",
|
||||
"axios": "^0.18.1",
|
||||
"blueimp-md5": "^2.10.0",
|
||||
"chokidar": "3.5.3",
|
||||
"classnames": "2.2.5",
|
||||
"date-fns": "2.16.1",
|
||||
"element-closest": "2.0.2",
|
||||
|
@@ -315,6 +315,10 @@ export class EventsSheetComponentWithoutHandle extends React.Component<
|
||||
}
|
||||
}
|
||||
|
||||
onResourceExternallyChanged = resourceInfo => {
|
||||
if (this._eventsTree) this._eventsTree.forceEventsUpdate();
|
||||
};
|
||||
|
||||
updateToolbar() {
|
||||
if (!this.props.setToolbar) return;
|
||||
|
||||
@@ -1991,6 +1995,7 @@ export class EventsSheetComponentWithoutHandle extends React.Component<
|
||||
|
||||
export type EventsSheetInterface = {|
|
||||
updateToolbar: () => void,
|
||||
onResourceExternallyChanged: ({| identifier: string |}) => void,
|
||||
|};
|
||||
|
||||
// EventsSheet is a wrapper so that the component can use multiple
|
||||
@@ -1998,12 +2003,17 @@ export type EventsSheetInterface = {|
|
||||
const EventsSheet = (props, ref) => {
|
||||
React.useImperativeHandle(ref, () => ({
|
||||
updateToolbar,
|
||||
onResourceExternallyChanged,
|
||||
}));
|
||||
|
||||
const component = React.useRef<?EventsSheetComponentWithoutHandle>(null);
|
||||
const updateToolbar = () => {
|
||||
if (component.current) component.current.updateToolbar();
|
||||
};
|
||||
const onResourceExternallyChanged = resourceInfo => {
|
||||
if (component.current)
|
||||
component.current.onResourceExternallyChanged(resourceInfo);
|
||||
};
|
||||
|
||||
const authenticatedUser = React.useContext(AuthenticatedUserContext);
|
||||
const preferences = React.useContext(PreferencesContext);
|
||||
|
@@ -1055,6 +1055,12 @@ export default class InstancesEditor extends Component<Props> {
|
||||
pauseSceneRendering = () => {
|
||||
if (this.nextFrame) cancelAnimationFrame(this.nextFrame);
|
||||
this._renderingPaused = true;
|
||||
// Deactivate interactions when the scene is paused.
|
||||
// Useful when the scene is paused to reload textures. The event system
|
||||
// might try to check if pointer is over a PIXI object using the texture
|
||||
// of the object. If there is no texture, it will crash.
|
||||
// The PIXI.EventSystem is not based on the PIXI.Ticker.
|
||||
this.instancesRenderer.getPixiContainer().eventMode = 'none';
|
||||
|
||||
stopPIXITicker();
|
||||
};
|
||||
@@ -1062,6 +1068,7 @@ export default class InstancesEditor extends Component<Props> {
|
||||
restartSceneRendering = () => {
|
||||
this._renderingPaused = false;
|
||||
this._renderScene();
|
||||
this.instancesRenderer.getPixiContainer().eventMode = 'auto';
|
||||
|
||||
startPIXITicker();
|
||||
};
|
||||
|
@@ -199,8 +199,6 @@ export default function makeExtensionsLoader({
|
||||
jsExtensions
|
||||
.filter(({ name }) => !filterExamples || !name.includes('Example'))
|
||||
.map(({ name, extensionModule, objectsRenderingServiceModules }) => {
|
||||
// Load any editor for objects, if we have somewhere where
|
||||
// to register them.
|
||||
if (
|
||||
objectsEditorService &&
|
||||
extensionModule.registerEditorConfigurations
|
||||
@@ -210,25 +208,23 @@ export default function makeExtensionsLoader({
|
||||
);
|
||||
}
|
||||
|
||||
// Register modules for ObjectsRenderingService
|
||||
if (objectsRenderingService && objectsRenderingServiceModules) {
|
||||
for (let requirePath in objectsRenderingServiceModules) {
|
||||
objectsRenderingService.registerModule(
|
||||
requirePath,
|
||||
objectsRenderingServiceModules[requirePath]
|
||||
if (objectsRenderingService) {
|
||||
if (objectsRenderingServiceModules) {
|
||||
for (const requirePath in objectsRenderingServiceModules) {
|
||||
objectsRenderingService.registerModule(
|
||||
requirePath,
|
||||
objectsRenderingServiceModules[requirePath]
|
||||
);
|
||||
}
|
||||
}
|
||||
if (extensionModule.registerInstanceRenderers) {
|
||||
extensionModule.registerInstanceRenderers(
|
||||
objectsRenderingService
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
// Load any renderer for objects, if we have somewhere where
|
||||
// to register them.
|
||||
if (
|
||||
objectsRenderingService &&
|
||||
extensionModule.registerInstanceRenderers
|
||||
) {
|
||||
extensionModule.registerInstanceRenderers(
|
||||
objectsRenderingService
|
||||
);
|
||||
if (extensionModule.registerClearCache) {
|
||||
extensionModule.registerClearCache(objectsRenderingService);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
|
@@ -56,47 +56,45 @@ module.exports = function makeExtensionsLoader(
|
||||
};
|
||||
}
|
||||
|
||||
if (extensionModule) {
|
||||
// Load any editor for objects, if we have somewhere where
|
||||
// to register them.
|
||||
if (
|
||||
objectsEditorService &&
|
||||
extensionModule.registerEditorConfigurations
|
||||
) {
|
||||
extensionModule.registerEditorConfigurations(
|
||||
objectsEditorService
|
||||
);
|
||||
}
|
||||
if (!extensionModule) {
|
||||
return {
|
||||
extensionModulePath,
|
||||
result: {
|
||||
error: true,
|
||||
message:
|
||||
'Unknown error. Please check for any syntax error or error that would prevent it from being run.',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
// Load any renderer for objects, if we have somewhere where
|
||||
// to register them.
|
||||
if (
|
||||
objectsRenderingService &&
|
||||
extensionModule.registerInstanceRenderers
|
||||
) {
|
||||
if (
|
||||
objectsEditorService &&
|
||||
extensionModule.registerEditorConfigurations
|
||||
) {
|
||||
extensionModule.registerEditorConfigurations(
|
||||
objectsEditorService
|
||||
);
|
||||
}
|
||||
|
||||
if (objectsRenderingService) {
|
||||
if (extensionModule.registerInstanceRenderers) {
|
||||
extensionModule.registerInstanceRenderers(
|
||||
objectsRenderingService
|
||||
);
|
||||
}
|
||||
|
||||
return {
|
||||
extensionModulePath,
|
||||
result: loadExtension(
|
||||
_,
|
||||
gd,
|
||||
gd.JsPlatform.get(),
|
||||
extensionModule
|
||||
),
|
||||
};
|
||||
if (extensionModule.registerClearCache) {
|
||||
extensionModule.registerClearCache(objectsRenderingService);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
extensionModulePath,
|
||||
result: {
|
||||
error: true,
|
||||
message:
|
||||
'Unknown error. Please check for any syntax error or error that would prevent it from being run.',
|
||||
},
|
||||
result: loadExtension(
|
||||
_,
|
||||
gd,
|
||||
gd.JsPlatform.get(),
|
||||
extensionModule
|
||||
),
|
||||
};
|
||||
})
|
||||
);
|
||||
|
@@ -48,6 +48,10 @@ export class ExternalEventsEditorContainer extends React.Component<
|
||||
return this.props.isActive || nextProps.isActive;
|
||||
}
|
||||
|
||||
onResourceExternallyChanged = (resourceInfo: {| identifier: string |}) => {
|
||||
if (this.editor) this.editor.onResourceExternallyChanged(resourceInfo);
|
||||
};
|
||||
|
||||
getProject(): ?gdProject {
|
||||
return this.props.project;
|
||||
}
|
||||
|
@@ -76,6 +76,13 @@ export class ExternalLayoutEditorContainer extends React.Component<
|
||||
}
|
||||
}
|
||||
|
||||
onResourceExternallyChanged(resourceInfo: {| identifier: string |}) {
|
||||
const { editor } = this;
|
||||
if (editor) {
|
||||
editor.onResourceExternallyChanged(resourceInfo);
|
||||
}
|
||||
}
|
||||
|
||||
updateToolbar() {
|
||||
if (this.editor) this.editor.updateToolbar();
|
||||
}
|
||||
|
37
newIDE/app/src/MainFrame/ResourcesWatcher.js
Normal file
37
newIDE/app/src/MainFrame/ResourcesWatcher.js
Normal file
@@ -0,0 +1,37 @@
|
||||
import * as React from 'react';
|
||||
import ResourcesLoader from '../ResourcesLoader';
|
||||
|
||||
const useResourcesWatcher = (getStorageProvider, fileMetadata, editorTabs) => {
|
||||
const informEditorsResourceExternallyChanged = React.useCallback(
|
||||
(resourceInfo: {| identifier: string |}) => {
|
||||
ResourcesLoader.burstAllUrlsCache();
|
||||
editorTabs.editors.forEach(editorTab => {
|
||||
if (
|
||||
editorTab.editorRef &&
|
||||
editorTab.editorRef.editor &&
|
||||
editorTab.editorRef.editor.onResourceExternallyChanged
|
||||
) {
|
||||
// Each editor container has an accessible editor property.
|
||||
// $FlowFixMe[not-a-function]
|
||||
editorTab.editorRef.editor.onResourceExternallyChanged(resourceInfo);
|
||||
}
|
||||
});
|
||||
},
|
||||
[editorTabs]
|
||||
);
|
||||
|
||||
React.useEffect(
|
||||
() => {
|
||||
const storageProvider = getStorageProvider();
|
||||
if (fileMetadata && storageProvider.setupResourcesWatcher) {
|
||||
const unsubscribe = storageProvider.setupResourcesWatcher(
|
||||
fileMetadata,
|
||||
informEditorsResourceExternallyChanged
|
||||
);
|
||||
return unsubscribe;
|
||||
}
|
||||
},
|
||||
[fileMetadata, informEditorsResourceExternallyChanged, getStorageProvider]
|
||||
);
|
||||
};
|
||||
export default useResourcesWatcher;
|
@@ -180,7 +180,8 @@ import newNameGenerator from '../Utils/NewNameGenerator';
|
||||
import { addDefaultLightToAllLayers } from '../ProjectCreation/CreateProject';
|
||||
import useEditorTabsStateSaving from './EditorTabs/UseEditorTabsStateSaving';
|
||||
import { type PrivateGameTemplateListingData } from '../Utils/GDevelopServices/Shop';
|
||||
|
||||
import PixiResourcesLoader from '../ObjectsRendering/PixiResourcesLoader';
|
||||
import useResourcesWatcher from './ResourcesWatcher';
|
||||
const GD_STARTUP_TIMES = global.GD_STARTUP_TIMES || [];
|
||||
|
||||
const gd: libGDevelop = global.gd;
|
||||
@@ -498,6 +499,11 @@ const MainFrame = (props: Props) => {
|
||||
ensureResourcesAreFetched,
|
||||
renderResourceFetcherDialog,
|
||||
} = useResourceFetcher({ resourceFetcher });
|
||||
useResourcesWatcher(
|
||||
getStorageProvider,
|
||||
currentFileMetadata,
|
||||
state.editorTabs
|
||||
);
|
||||
|
||||
/**
|
||||
* This reference is useful to get the current opened project,
|
||||
@@ -898,7 +904,7 @@ const MainFrame = (props: Props) => {
|
||||
// the URL to a resource with a name in the old project is not re-used
|
||||
// for another resource with the same name in the new project.
|
||||
ResourcesLoader.burstAllUrlsCache();
|
||||
// TODO: Pixi cache should also be burst
|
||||
PixiResourcesLoader.burstCache();
|
||||
|
||||
const state = await setState(state => ({
|
||||
...state,
|
||||
|
@@ -157,6 +157,10 @@ const ObjectsRenderingService = {
|
||||
|
||||
this.renderers3D[objectType] = renderer;
|
||||
},
|
||||
renderersCacheClearingMethods: [],
|
||||
registerClearCache: function(clearCache: (project: gdProject) => void) {
|
||||
this.renderersCacheClearingMethods.push(clearCache);
|
||||
},
|
||||
/**
|
||||
* Register a module that can be then required using `requireModule`.
|
||||
* This is necessary for the web-app, as all files must be bundled.
|
||||
|
@@ -10,13 +10,13 @@ import { loadFontFace } from '../Utils/FontFaceLoader';
|
||||
import { checkIfCredentialsRequired } from '../Utils/CrossOrigin';
|
||||
const gd: libGDevelop = global.gd;
|
||||
|
||||
const loadedBitmapFonts = {};
|
||||
const loadedFontFamilies = {};
|
||||
const loadedTextures = {};
|
||||
let loadedBitmapFonts = {};
|
||||
let loadedFontFamilies = {};
|
||||
let loadedTextures = {};
|
||||
const invalidTexture = PIXI.Texture.from('res/error48.png');
|
||||
const loadedThreeTextures = {};
|
||||
const loadedThreeMaterials = {};
|
||||
const loadedOrLoading3DModelPromises: {
|
||||
let loadedThreeTextures = {};
|
||||
let loadedThreeMaterials = {};
|
||||
let loadedOrLoading3DModelPromises: {
|
||||
[resourceName: string]: Promise<THREE.THREE_ADDONS.GLTF>,
|
||||
} = {};
|
||||
|
||||
@@ -150,6 +150,49 @@ const traverseToRemoveMetalnessFromMeshes = (
|
||||
* This internally uses ResourcesLoader to get the URL of the resources.
|
||||
*/
|
||||
export default class PixiResourcesLoader {
|
||||
static burstCache() {
|
||||
loadedBitmapFonts = {};
|
||||
loadedFontFamilies = {};
|
||||
loadedTextures = {};
|
||||
loadedThreeTextures = {};
|
||||
loadedThreeMaterials = {};
|
||||
loadedOrLoading3DModelPromises = {};
|
||||
}
|
||||
|
||||
static async reloadTextureForResource(
|
||||
project: gdProject,
|
||||
resourceName: string
|
||||
) {
|
||||
const loadedTexture = loadedTextures[resourceName];
|
||||
if (loadedTexture && loadedTexture.textureCacheIds) {
|
||||
await PIXI.Assets.unload(loadedTexture.textureCacheIds);
|
||||
}
|
||||
|
||||
await PixiResourcesLoader.loadTextures(project, [resourceName], () => {});
|
||||
|
||||
if (loadedOrLoading3DModelPromises[resourceName]) {
|
||||
delete loadedOrLoading3DModelPromises[resourceName];
|
||||
}
|
||||
if (loadedFontFamilies[resourceName]) {
|
||||
delete loadedFontFamilies[resourceName];
|
||||
}
|
||||
if (loadedBitmapFonts[resourceName]) {
|
||||
delete loadedBitmapFonts[resourceName];
|
||||
}
|
||||
if (loadedThreeTextures[resourceName]) {
|
||||
loadedThreeTextures[resourceName].dispose();
|
||||
delete loadedThreeTextures[resourceName];
|
||||
}
|
||||
const matchingMaterials = Object.keys(loadedThreeMaterials).filter(key =>
|
||||
key.startsWith(resourceName)
|
||||
);
|
||||
if (matchingMaterials.length > 0) {
|
||||
matchingMaterials.forEach(key => {
|
||||
loadedThreeMaterials[key].dispose();
|
||||
delete loadedThreeMaterials[key];
|
||||
});
|
||||
}
|
||||
}
|
||||
/**
|
||||
* (Re)load the PIXI texture represented by the given resources.
|
||||
*/
|
||||
|
@@ -0,0 +1,60 @@
|
||||
// @flow
|
||||
import optionalRequire from '../../Utils/OptionalRequire';
|
||||
import { type FileMetadata } from '..';
|
||||
import debounce from 'lodash/debounce';
|
||||
import wrap from 'lodash/wrap';
|
||||
import memoize from 'lodash/memoize';
|
||||
|
||||
const fileWatcher = optionalRequire('chokidar');
|
||||
const path = optionalRequire('path');
|
||||
|
||||
export const setupResourcesWatcher =
|
||||
fileWatcher && path
|
||||
? (
|
||||
fileMetadata: FileMetadata,
|
||||
callback: ({| identifier: string |}) => void
|
||||
) => {
|
||||
// We can't just debounce the whole callback, it has to be done file-wise,
|
||||
// otherwise we would miss all the debounced calls but the last one.
|
||||
// See https://stackoverflow.com/questions/28787436/debounce-a-function-with-argument
|
||||
const debouncedCallback = wrap(
|
||||
memoize(() =>
|
||||
debounce(
|
||||
filePath => {
|
||||
const relativePath = path
|
||||
.relative(folderPath, filePath)
|
||||
.replace(/\\/g, '/');
|
||||
|
||||
callback({ identifier: relativePath });
|
||||
},
|
||||
200,
|
||||
{ leading: false, trailing: true }
|
||||
)
|
||||
),
|
||||
(getMemoizedFunc, obj) => getMemoizedFunc(obj)(obj)
|
||||
);
|
||||
const folderPath = path.dirname(fileMetadata.fileIdentifier);
|
||||
const gameFile = path.basename(fileMetadata.fileIdentifier);
|
||||
const autosaveFile = gameFile + '.autosave';
|
||||
const watcher = fileWatcher
|
||||
.watch(folderPath, {
|
||||
ignored: [
|
||||
`**/.DS_Store`,
|
||||
path.join(folderPath, gameFile),
|
||||
path.join(folderPath, autosaveFile),
|
||||
],
|
||||
awaitWriteFinish: {
|
||||
stabilityThreshold: 250,
|
||||
pollInterval: 100,
|
||||
},
|
||||
})
|
||||
.on(
|
||||
'change',
|
||||
// TODO: Is it safe to let it like that since the OS could for some reason
|
||||
// do never-ending operations on the folder or its children, making the debounce
|
||||
// never ending.
|
||||
debouncedCallback
|
||||
);
|
||||
return () => watcher.unwatch(folderPath);
|
||||
}
|
||||
: undefined;
|
@@ -36,6 +36,7 @@ import {
|
||||
type ShowAlertFunction,
|
||||
type ShowConfirmFunction,
|
||||
} from '../../UI/Alert/AlertContext';
|
||||
import { setupResourcesWatcher } from './LocalFileResourcesWatcher';
|
||||
|
||||
/**
|
||||
* Use the Electron APIs to provide access to the native
|
||||
@@ -55,6 +56,7 @@ export default ({
|
||||
},
|
||||
getProjectLocation: getProjectLocation,
|
||||
renderNewProjectSaveAsLocationChooser: renderNewProjectSaveAsLocationChooser,
|
||||
setupResourcesWatcher,
|
||||
createOperations: () => ({
|
||||
onOpenWithPicker,
|
||||
onOpen,
|
||||
|
@@ -193,4 +193,9 @@ export type StorageProvider = {|
|
||||
createResourceOperations?: ({|
|
||||
authenticatedUser: AuthenticatedUser,
|
||||
|}) => ResourcesActionsMenuBuilder,
|
||||
/** Resources external changes */
|
||||
setupResourcesWatcher?: (
|
||||
fileMetadata: FileMetadata,
|
||||
callback: ({| identifier: string |}) => void
|
||||
) => () => void,
|
||||
|};
|
||||
|
@@ -63,19 +63,7 @@ const ResourcePropertiesEditor = React.forwardRef<
|
||||
},
|
||||
ref
|
||||
) => {
|
||||
const _forceUpdate = useForceUpdate();
|
||||
const resourcePreviewRef = React.useRef<?ResourcePreview>(null);
|
||||
|
||||
const forceUpdate = React.useCallback(
|
||||
() => {
|
||||
_forceUpdate();
|
||||
if (resourcePreviewRef.current) {
|
||||
resourcePreviewRef.current.forceUpdate();
|
||||
}
|
||||
},
|
||||
[_forceUpdate]
|
||||
);
|
||||
|
||||
const forceUpdate = useForceUpdate();
|
||||
React.useImperativeHandle(ref, () => ({ forceUpdate }));
|
||||
|
||||
const chooseResourcePath = React.useCallback(
|
||||
@@ -183,7 +171,6 @@ const ResourcePropertiesEditor = React.forwardRef<
|
||||
|
||||
return (
|
||||
<ResourcePreview
|
||||
ref={resourcePreviewRef}
|
||||
resourceName={resources[0].getName()}
|
||||
resourcesLoader={resourcesLoader}
|
||||
project={project}
|
||||
|
@@ -205,6 +205,13 @@ export default class ResourcesEditor extends React.Component<Props, State> {
|
||||
);
|
||||
};
|
||||
|
||||
onResourceExternallyChanged = (resourceInfo: {| identifier: string |}) => {
|
||||
if (this._propertiesEditor) {
|
||||
this._propertiesEditor.forceUpdate();
|
||||
}
|
||||
this.refreshResourcesList();
|
||||
};
|
||||
|
||||
render() {
|
||||
const {
|
||||
project,
|
||||
|
@@ -1,7 +1,6 @@
|
||||
// @flow
|
||||
import * as React from 'react';
|
||||
import ResourcesLoader from '../../ResourcesLoader';
|
||||
import { type ResourceKind } from '../ResourceSource';
|
||||
import ImagePreview, { isProjectImageResourceSmooth } from './ImagePreview';
|
||||
import GenericIconPreview from './GenericIconPreview';
|
||||
import FontDownload from '@material-ui/icons/FontDownload';
|
||||
@@ -16,80 +15,50 @@ type Props = {|
|
||||
onSize?: (number, number) => void,
|
||||
|};
|
||||
|
||||
type State = {|
|
||||
resourceKind: ?ResourceKind,
|
||||
|};
|
||||
|
||||
/**
|
||||
* Display the right preview for any given resource of a project
|
||||
*/
|
||||
export default class ResourcePreview extends React.PureComponent<Props, State> {
|
||||
state = this._loadFrom(this.props);
|
||||
const ResourcePreview = (props: Props) => {
|
||||
const { project, resourceName } = props;
|
||||
const resourcesManager = project.getResourcesManager();
|
||||
const resourceKind = resourcesManager.hasResource(resourceName)
|
||||
? resourcesManager.getResource(resourceName).getKind()
|
||||
: null;
|
||||
|
||||
// To be updated, see https://reactjs.org/docs/react-component.html#unsafe_componentwillreceiveprops.
|
||||
UNSAFE_componentWillReceiveProps(newProps: Props) {
|
||||
if (
|
||||
newProps.resourceName !== this.props.resourceName ||
|
||||
newProps.project !== this.props.project
|
||||
) {
|
||||
this.setState(this._loadFrom(newProps));
|
||||
}
|
||||
switch (resourceKind) {
|
||||
case 'image':
|
||||
return (
|
||||
<ImagePreview
|
||||
resourceName={resourceName}
|
||||
imageResourceSource={props.resourcesLoader.getResourceFullUrl(
|
||||
project,
|
||||
resourceName,
|
||||
{}
|
||||
)}
|
||||
isImageResourceSmooth={isProjectImageResourceSmooth(
|
||||
project,
|
||||
resourceName
|
||||
)}
|
||||
onSize={props.onSize}
|
||||
/>
|
||||
);
|
||||
case 'audio':
|
||||
return <GenericIconPreview renderIcon={props => <Music {...props} />} />;
|
||||
case 'json':
|
||||
case 'tilemap':
|
||||
case 'tileset':
|
||||
case 'model3D':
|
||||
return <GenericIconPreview renderIcon={props => <File {...props} />} />;
|
||||
case 'video':
|
||||
return <GenericIconPreview renderIcon={props => <Video {...props} />} />;
|
||||
case 'font':
|
||||
case 'bitmapFont':
|
||||
return (
|
||||
<GenericIconPreview renderIcon={props => <FontDownload {...props} />} />
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
};
|
||||
|
||||
_loadFrom(props: Props): State {
|
||||
const { project, resourceName } = props;
|
||||
const resourcesManager = project.getResourcesManager();
|
||||
const resourceKind = resourcesManager.hasResource(resourceName)
|
||||
? resourcesManager.getResource(resourceName).getKind()
|
||||
: null;
|
||||
|
||||
return {
|
||||
resourceKind,
|
||||
};
|
||||
}
|
||||
|
||||
render() {
|
||||
const { resourceKind } = this.state;
|
||||
|
||||
switch (resourceKind) {
|
||||
case 'image':
|
||||
return (
|
||||
<ImagePreview
|
||||
resourceName={this.props.resourceName}
|
||||
imageResourceSource={this.props.resourcesLoader.getResourceFullUrl(
|
||||
this.props.project,
|
||||
this.props.resourceName,
|
||||
{}
|
||||
)}
|
||||
isImageResourceSmooth={isProjectImageResourceSmooth(
|
||||
this.props.project,
|
||||
this.props.resourceName
|
||||
)}
|
||||
onSize={this.props.onSize}
|
||||
/>
|
||||
);
|
||||
case 'audio':
|
||||
return (
|
||||
<GenericIconPreview renderIcon={props => <Music {...props} />} />
|
||||
);
|
||||
case 'json':
|
||||
case 'tilemap':
|
||||
case 'tileset':
|
||||
case 'model3D':
|
||||
return <GenericIconPreview renderIcon={props => <File {...props} />} />;
|
||||
case 'video':
|
||||
return (
|
||||
<GenericIconPreview renderIcon={props => <Video {...props} />} />
|
||||
);
|
||||
case 'font':
|
||||
case 'bitmapFont':
|
||||
return (
|
||||
<GenericIconPreview
|
||||
renderIcon={props => <FontDownload {...props} />}
|
||||
/>
|
||||
);
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
export default ResourcePreview;
|
||||
|
@@ -135,6 +135,7 @@ export type SceneEditorsDisplayInterface = {|
|
||||
getLastContextMenuSceneCoordinates: () => [number, number],
|
||||
getViewPosition: () => ?ViewPosition,
|
||||
|},
|
||||
startSceneRendering: (start: boolean) => void,
|
||||
instancesHandlers: {|
|
||||
getSelectionAABB: () => Rectangle,
|
||||
addInstances: (
|
||||
|
@@ -151,6 +151,14 @@ const MosaicEditorsDisplay = React.forwardRef<
|
||||
return editorMosaicRef.current.getOpenedEditorNames().includes(editorId);
|
||||
}, []);
|
||||
|
||||
const startSceneRendering = React.useCallback((start: boolean) => {
|
||||
const editor = editorRef.current;
|
||||
if (!editor) return;
|
||||
|
||||
if (start) editor.restartSceneRendering();
|
||||
else editor.pauseSceneRendering();
|
||||
}, []);
|
||||
|
||||
React.useImperativeHandle(ref, () => {
|
||||
const { current: editor } = editorRef;
|
||||
return {
|
||||
@@ -163,6 +171,7 @@ const MosaicEditorsDisplay = React.forwardRef<
|
||||
openNewObjectDialog,
|
||||
toggleEditorView,
|
||||
isEditorVisible,
|
||||
startSceneRendering,
|
||||
viewControls: {
|
||||
zoomBy: editor ? editor.zoomBy : noop,
|
||||
setZoomFactor: editor ? editor.setZoomFactor : noop,
|
||||
|
@@ -137,6 +137,14 @@ const SwipeableDrawerEditorsDisplay = React.forwardRef<
|
||||
[selectedEditorId, drawerOpeningState]
|
||||
);
|
||||
|
||||
const startSceneRendering = React.useCallback((start: boolean) => {
|
||||
const editor = editorRef.current;
|
||||
if (!editor) return;
|
||||
|
||||
if (start) editor.restartSceneRendering();
|
||||
else editor.pauseSceneRendering();
|
||||
}, []);
|
||||
|
||||
React.useImperativeHandle(ref, () => {
|
||||
const { current: editor } = editorRef;
|
||||
|
||||
@@ -150,6 +158,7 @@ const SwipeableDrawerEditorsDisplay = React.forwardRef<
|
||||
openNewObjectDialog,
|
||||
toggleEditorView: halfOpenOrCloseDrawerOnEditor,
|
||||
isEditorVisible,
|
||||
startSceneRendering,
|
||||
viewControls: {
|
||||
zoomBy: editor ? editor.zoomBy : noop,
|
||||
setZoomFactor: editor ? editor.setZoomFactor : noop,
|
||||
|
@@ -62,6 +62,7 @@ import MosaicEditorsDisplay from './MosaicEditorsDisplay';
|
||||
import SwipeableDrawerEditorsDisplay from './SwipeableDrawerEditorsDisplay';
|
||||
import { type SceneEditorsDisplayInterface } from './EditorsDisplay.flow';
|
||||
import newNameGenerator from '../Utils/NewNameGenerator';
|
||||
import ObjectsRenderingService from '../ObjectsRendering/ObjectsRenderingService';
|
||||
|
||||
const gd: libGDevelop = global.gd;
|
||||
|
||||
@@ -206,6 +207,49 @@ export default class SceneEditor extends React.Component<Props, State> {
|
||||
return this.state.instancesEditorSettings;
|
||||
}
|
||||
|
||||
onResourceExternallyChanged = async (resourceInfo: {|
|
||||
identifier: string,
|
||||
|}) => {
|
||||
const { project } = this.props;
|
||||
|
||||
const resourceName = project
|
||||
.getResourcesManager()
|
||||
.getResourceNameWithFile(resourceInfo.identifier);
|
||||
if (resourceName) {
|
||||
const { editorDisplay } = this;
|
||||
if (!editorDisplay) return;
|
||||
try {
|
||||
// When reloading textures, there can be a short time during which
|
||||
// the existing texture is removed but the InstancesEditor tries to use it
|
||||
// through the RenderedInstance's, triggering crashes. So the scene rendering
|
||||
// is paused during this period.
|
||||
editorDisplay.startSceneRendering(false);
|
||||
await PixiResourcesLoader.reloadTextureForResource(
|
||||
project,
|
||||
resourceName
|
||||
);
|
||||
|
||||
editorDisplay.forceUpdateObjectsList();
|
||||
|
||||
const objectsCollector = new gd.ObjectsUsingResourceCollector(
|
||||
resourceName
|
||||
);
|
||||
// $FlowIgnore - Flow does not know ObjectsUsingResourceCollector inherits from ArbitraryObjectsWorker
|
||||
gd.ProjectBrowserHelper.exposeProjectObjects(project, objectsCollector);
|
||||
const objectNames = objectsCollector.getObjectNames().toJSArray();
|
||||
objectsCollector.delete();
|
||||
ObjectsRenderingService.renderersCacheClearingMethods.forEach(clear =>
|
||||
clear(project)
|
||||
);
|
||||
objectNames.forEach(objectName => {
|
||||
editorDisplay.instancesHandlers.resetInstanceRenderersFor(objectName);
|
||||
});
|
||||
} finally {
|
||||
editorDisplay.startSceneRendering(true);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
updateToolbar = () => {
|
||||
const { editorDisplay } = this;
|
||||
if (!editorDisplay) return;
|
||||
|
@@ -3,6 +3,9 @@ import * as PIXI from 'pixi.js-legacy';
|
||||
// PIXI has a ticker that is used by PIXI InteractionManager, and which
|
||||
// frequently check if interaction happened. We may want to disable it
|
||||
// when it's useless to do these interaction checks to save CPU usage.
|
||||
// TODO: We might not need this anymore since PIXI v7 dropped the use of
|
||||
// InteractionManager in favor of EventSystem that does not seem
|
||||
// to use a ticker.
|
||||
|
||||
/**
|
||||
* Stop the PIXI Ticker used to monitor interactions
|
||||
|
Reference in New Issue
Block a user