This repository has been archived by the owner on Feb 27, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
d2bb6c8
commit 710c953
Showing
12 changed files
with
184 additions
and
206 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,153 +1,114 @@ | ||
import * as fse from "fs-extra"; | ||
import * as path from "path"; | ||
|
||
import GMFolder from "../GMFolder"; | ||
import GMProject from "../GMProject"; | ||
import GMResource from "../GMResource"; | ||
import IGMFolder from "../interfaces/IGMFolder"; | ||
import IGMProject from "../interfaces/IGMProject"; | ||
import IGMProjectFactory from "../interfaces/IGMProjectFactory"; | ||
import IGMResource from "../interfaces/IGMResource"; | ||
import GMS2ResourceType from "./GMS2ResourceType"; | ||
import GMS2Script from "./GMS2Script"; | ||
import { IFolder, IProject, IResource, IResourceInfo, IScript } from "./IGMS2Descriptor"; | ||
|
||
/** | ||
* Creates a new GameMakerStudio 2 Project Factory that loads a project | ||
* file and creates a new GMProject | ||
* Factory class to create GMS2Project instances | ||
*/ | ||
export default class GMS2ProjectFactory implements IGMProjectFactory { | ||
|
||
/** | ||
* A map with each key is the GMS2 parent folder and each value is an | ||
* array with the keys of the childrens of that folder. | ||
*/ | ||
private _folderChildsKeys: Map<IGMFolder, string[]> = new Map(); | ||
export default class GMS2ProjectFactory { | ||
|
||
/** | ||
* A map with the resources by key. | ||
* The created GMProject | ||
*/ | ||
private _resourcesByKey: Map<string, GMResource> = new Map(); | ||
private _project: IGMProject; | ||
|
||
/** | ||
* The project file | ||
* A map with each GMFolder, and an array with the children key ids of each folder | ||
*/ | ||
private readonly _file: string; | ||
private _folderChildrenKeys: Map<IGMFolder, string[]> = new Map(); | ||
|
||
/** | ||
* The GMS2Project to create | ||
* A map with the key ids and the associated resource | ||
*/ | ||
private readonly _project: IGMProject; | ||
private _resourcesByKey: Map<string, GMResource> = new Map(); | ||
|
||
/** | ||
* Creates GMS2ProjectFactory | ||
* @param file The project file | ||
* Creates an instance of GMS2ProjectFactory. | ||
* @param {string} gmProjectFolder The project folder | ||
* @memberof GMS2ProjectFactory | ||
*/ | ||
constructor(file: string) { | ||
this._file = file; | ||
this._project = new GMProject(path.dirname(this._file)); | ||
public constructor(gmProjectFolder: string) { | ||
this._project = new GMProject(gmProjectFolder); | ||
} | ||
|
||
/** | ||
* Loads the specified GMS2 project | ||
* @param file The file path of the project to load | ||
* @returns A Promise with the created GMS2Project | ||
* Builds the GMS2Project instance and returns it | ||
*/ | ||
public async load(): Promise<IGMProject> { | ||
const str = await fse.readFile(this._file, "utf8"); | ||
const data: IProject = JSON.parse(str); | ||
|
||
for (const item of data.resources) { | ||
await this._addResource(item.Key, item.Value); | ||
} | ||
public build() { | ||
for (const folder of this._project.children) { | ||
this._buildSubTree(folder); | ||
this._buildSubtree(folder); | ||
} | ||
return this._project; | ||
} | ||
|
||
/** | ||
* Build subtre for the specified folder | ||
* @param folder The folder to find the childrens | ||
* Adds a new GMS2Folder to the project | ||
* | ||
* @param {string} key The resource key id | ||
* @param {string} folderName The folder name | ||
* @param {string} localizedFolderName The localizedFolderName | ||
* @param {string[]} children An array with the children keys id of the folder | ||
* @memberof GMS2ProjectFactory | ||
*/ | ||
private _buildSubTree(folder: IGMFolder) { | ||
const children = this._folderChildsKeys.get(folder) as string[]; | ||
for (const childKey of children) { | ||
const child = this._resourcesByKey.get(childKey); | ||
if (child) { | ||
folder.addChild(child); | ||
if (this._isFolder(child)) { | ||
this._buildSubTree(child); | ||
} | ||
} | ||
public addFolder(key: string, folderName: string, localizedFolderName: string, children: string[]): void { | ||
const topLevelName = localizedFolderName.split("ResourceTree_").join(""); | ||
const folder = new GMFolder(folderName); | ||
this._folderChildrenKeys.set(folder, children); | ||
if (topLevelName !== "") { | ||
this._project.addChild(folder); | ||
} | ||
this._resourcesByKey.set(key, folder); | ||
} | ||
|
||
/** | ||
* Determines if the resource is a folder (ducktyping) | ||
* @param res The resource | ||
* Adds a new GMS2Script | ||
* | ||
* @param {string} key The resource key id | ||
* @param {string} name The script name | ||
* @param {boolean} isCompatibility Is a compatibility script? | ||
* @memberof GMS2ProjectFactory | ||
*/ | ||
private _isFolder(res: IGMResource): res is IGMFolder { | ||
return ("addChild" in res); | ||
public addScript(key: string, name: string, isCompatibility: boolean): void { | ||
const script = new GMS2Script(name, isCompatibility); | ||
this._resourcesByKey.set(key, script); | ||
} | ||
|
||
/** | ||
* Adds and loads a resource | ||
* @param key Resource Key | ||
* @param resource ResourceInfo | ||
* Adds a new Resource to the GMS2Project | ||
* @param key The resource key id | ||
* @param name The resource name | ||
*/ | ||
private async _addResource(key: string, resource: IResourceInfo) { | ||
const data = await this._loadResourceData(resource.resourcePath); | ||
const res = this._createFromData(data); | ||
public addResource(key: string, name: string) { | ||
const res = new GMResource(name); | ||
this._resourcesByKey.set(key, res); | ||
} | ||
|
||
/** | ||
* Creates a GMS2Resource from a YOYO model data | ||
* @param modelData The YOYO model data to create the GMS2Resource from | ||
* Build subtree for the specified folder | ||
* @param folder The folder to find the children | ||
*/ | ||
private _createFromData(modelData: IResource): GMResource { | ||
switch (modelData.modelName) { | ||
case GMS2ResourceType.GMFolder: | ||
return this._createFolder(modelData as IFolder); | ||
case GMS2ResourceType.GMScript: | ||
return this._createScript(modelData as IScript); | ||
default: | ||
return new GMResource(modelData.name); | ||
} | ||
} | ||
|
||
/** | ||
* Load a resource JSON data from a file | ||
* @param filename The relative path to load the data from | ||
*/ | ||
private async _loadResourceData(filename: string): Promise<IResource> { | ||
const file = path.resolve(this._project.path, filename); | ||
const str = await fse.readFile(file, "utf8"); | ||
return JSON.parse(str); | ||
} | ||
|
||
/** | ||
* Creates a new GMS2Folder | ||
* @param data The folder data | ||
*/ | ||
private _createFolder(data: IFolder): GMFolder { | ||
const topLevelName = data.localisedFolderName.split("ResourceTree_").join(""); | ||
const folder = new GMFolder(data.folderName); | ||
this._folderChildsKeys.set(folder, data.children); | ||
if (topLevelName !== "") { | ||
this._project.addChild(folder); | ||
private _buildSubtree(folder: IGMFolder) { | ||
const children = this._folderChildrenKeys.get(folder) as string[]; | ||
for (const childKey of children) { | ||
const child = this._resourcesByKey.get(childKey); | ||
if (child) { | ||
folder.addChild(child); | ||
if (this._isFolder(child)) { | ||
this._buildSubtree(child); | ||
} | ||
} | ||
} | ||
return folder; | ||
} | ||
|
||
/** | ||
* Creates a new GMS2Script | ||
* @param data The Script data | ||
* Determines if the resource is a folder (ducktyping) | ||
* @param res The resource | ||
*/ | ||
private _createScript(data: IScript): GMS2Script { | ||
const script = new GMS2Script(data.name); | ||
script.isCompatibility = data.IsCompatibility; | ||
return script; | ||
private _isFolder(res: IGMResource): res is IGMFolder { | ||
return ("addChild" in res); | ||
} | ||
} |
Oops, something went wrong.