Add gdjs.JsonManager to load json + added icons in ResourcePreview for all resources

This commit is contained in:
Florian Rival
2019-06-30 15:45:20 +01:00
committed by Florian Rival
parent 45070d3323
commit a7e0cd2cec
8 changed files with 134 additions and 49 deletions

View File

@@ -499,6 +499,7 @@ void ExporterHelper::AddLibsInclude(bool pixiRenderers,
InsertUnique(includesFiles, "libs/hshg.js");
InsertUnique(includesFiles, "libs/rbush.js");
InsertUnique(includesFiles, "inputmanager.js");
InsertUnique(includesFiles, "jsonmanager.js");
InsertUnique(includesFiles, "timemanager.js");
InsertUnique(includesFiles, "runtimeobject.js");
InsertUnique(includesFiles, "profiler.js");

View File

@@ -0,0 +1,76 @@
/*
* GDevelop JS Platform
* Copyright 2013-present Florian Rival (Florian.Rival@gmail.com). All rights reserved.
* This project is released under the MIT License.
*/
/**
* JsonManager loads json files (using XMLHttpRequest), using the "json" resources
* registered in the game resources.
*
* Contrary to audio/fonts, json files are loaded asynchronously, when requested.
* You should properly handle errors, and give the developer/player a way to know
* that loading failed.
*
* @class JsonManager
* @memberof gdjs
* @param {Object[]} resources The resources data of the game.
*/
gdjs.JsonManager = function(resources) {
this._resources = resources;
};
/**
* The callback called when a json that was requested is loaded (or an error occured).
* @callback JsonManagerRequestCallback
* @param {?Error} error The error, if any. `null` otherwise.
* @param {?Object} jsonContent The content of the json file (or null if an error occured).
* @returns {undefined} Nothing
*/
/**
* Request the json file from the given resource name.
* When loaded, the `callback` is called with the error (null if none) and the loaded
* json (string).
*
* @param {string} resourceName The resource pointing to the json file to load.
* @param {JsonManagerRequestCallback} callback The callback function called when json is loaded (or an error occured).
*/
gdjs.JsonManager.prototype.loadJson = function(resourceName, callback) {
var resource = this._resources.find(
resource => resource.kind === 'json' && resource.name === resourceName
);
if (!resource) {
callback(
new Error(
'Can\'t find resource with name: "' +
resourceName +
'" (or is not a json resource).'
),
null
);
return;
}
var xhr = new XMLHttpRequest();
xhr.responseType = 'json';
xhr.open('GET', resource.file);
xhr.onload = function() {
if (xhr.status !== 200) {
callback(
new Error('HTTP error: ' + xhr.status + '(' + xhr.statusText + ')'),
null
);
return;
}
callback(null, xhr.response);
};
xhr.onerror = function() {
callback(new Error('Network error'), null);
};
xhr.onabort = function() {
callback(new Error('Request aborted'), null);
};
xhr.send();
};

View File

@@ -26,6 +26,9 @@ gdjs.RuntimeGame = function(data, spec) {
this._fontManager = new gdjs.FontManager(
data.resources ? data.resources.resources : undefined
);
this._jsonManager = new gdjs.JsonManager(
data.resources ? data.resources.resources : undefined
);
this._maxFPS = data ? parseInt(data.properties.maxFPS, 10) : 60;
this._minFPS = data ? parseInt(data.properties.minFPS, 10) : 15;

View File

@@ -17,6 +17,7 @@ module.exports = function(config) {
'../Runtime/howler-sound-manager/howler-sound-manager.js',
'../Runtime/fontfaceobserver-font-manager/fontfaceobserver.js',
'../Runtime/fontfaceobserver-font-manager/fontfaceobserver-font-manager.js',
'../Runtime/jsonmanager.js',
'../Runtime/timemanager.js',
'../Runtime/runtimeobject.js',
'../Runtime/runtimescene.js',

View File

@@ -148,8 +148,8 @@ export default [
const options = {
multiSelections,
title: 'Choose a json file',
name: 'Json files',
extensions: ['mp4'],
name: 'JSON file',
extensions: ['json'],
};
return selectLocalResourcePath(project, options).then(resources => {
return resources.map(resourcePath => {

View File

@@ -1,39 +0,0 @@
// @flow
import * as React from 'react';
import ResourcesLoader from '../../ResourcesLoader';
import Audiotrack from 'material-ui/svg-icons/image/audiotrack';
const styles = {
previewContainer: {
display: 'flex',
width: '100%',
alignItems: 'center',
justifyContent: 'center',
height: 200,
border: '#AAAAAA 1px solid',
background: 'url("res/transparentback.png") repeat',
},
icon: { width: 60, height: 60 },
};
type Props = {|
project: gdProject,
resourceName: string,
resourcesLoader: typeof ResourcesLoader,
children?: any,
style?: Object,
resourcePath?: string,
|};
/**
* Display the preview for a resource of a project with kind "audio".
*/
export default class AudioPreview extends React.Component<Props, void> {
render() {
return (
<div style={styles.previewContainer}>
<Audiotrack style={styles.icon} />
</div>
);
}
}

View File

@@ -0,0 +1,28 @@
// @flow
import * as React from 'react';
const styles = {
previewContainer: {
display: 'flex',
width: '100%',
alignItems: 'center',
justifyContent: 'center',
height: 200,
border: '#AAAAAA 1px solid',
background: 'url("res/transparentback.png") repeat',
},
icon: { width: 60, height: 60 },
};
type Props = {|
renderIcon: ({| style: Object |}) => React.Node,
|};
/**
* Display a generic container to display an icon.
*/
export default ({ renderIcon }: Props) => (
<div style={styles.previewContainer}>
{renderIcon({ style: styles.icon })}
</div>
);

View File

@@ -3,7 +3,11 @@ import * as React from 'react';
import ResourcesLoader from '../../ResourcesLoader';
import { type ResourceKind } from '../ResourceSource.flow';
import ImagePreview from './ImagePreview';
import AudioPreview from './AudioPreview';
import GenericIconPreview from './GenericIconPreview';
import Audiotrack from 'material-ui/svg-icons/image/audiotrack';
import InsertDriveFile from 'material-ui/svg-icons/editor/insert-drive-file';
import VideoLibrary from 'material-ui/svg-icons/av/video-library';
import FontDownload from 'material-ui/svg-icons/content/font-download';
type Props = {|
project: gdProject,
@@ -69,13 +73,24 @@ export default class ResourcePreview extends React.Component<Props, State> {
);
case 'audio':
return (
<AudioPreview
project={this.props.project}
resourceName={this.props.resourceName}
resourcesLoader={this.props.resourcesLoader}
children={this.props.children}
style={this.props.style}
resourcePath={this.props.resourcePath}
<GenericIconPreview renderIcon={props => <Audiotrack {...props} />} />
);
case 'json':
return (
<GenericIconPreview
renderIcon={props => <InsertDriveFile {...props} />}
/>
);
case 'video':
return (
<GenericIconPreview
renderIcon={props => <VideoLibrary {...props} />}
/>
);
case 'font':
return (
<GenericIconPreview
renderIcon={props => <FontDownload {...props} />}
/>
);
default: