Thank you for your suggestions,
I made this little "module" to access to pre-stored objects during production (compiled binary). I will leave it here in case someone has the same problem (already tested with pluginval).
Note: Remember, the goal is to be able to access JSON files that cannot be added directly into the compiled binary, so data-writing is only available during development.
First add this script in your Scripts/ folder and create an additional JSONStorage.data
file in the same folder (you can execute JSONStorage.createDataFile()
from console after compiling your project with the next script included):
// JSONStorage.js
/**
* Store JSON data during development to use in production.
* @namespace JSONStorage
* @property {Object} data - The current object where all JSON data is stored.
* @property {Boolean} ignoreWarnings=false - Don't show warning messages in production-mode (e.g. trying to write data-file during production).
* @property {Boolean} autoWrite=true - Write data-file automatically at every change.
* @example
* JSONStorage.set( 'myJson', { myProp : 1 } ) ; // <- Only in dev-mode, in production it will be skipped with a warning-message.
* var json = JSONStorage.get( 'myJson' ) ;
* var data = json.data ; // <- Already saved data (cached) in 'Scripts/JSONStorage.data' file.
* Console.print( trace( data ) ) ; // <- Expected : "{ myProp : 1 }"
*/
namespace JSONStorage {
/** Current cached data (Stored-Objects) */
reg data = { } ;
/** If enabled, the warning messages in prod-mode will not showing */
reg ignoreWarnings = false ;
/** If enabled, the data-file will be written automatically after every change. */
reg autoWrite = true ;
/** Check current enviroment (DEV/PROD) */
const var DEV = Engine.isHISE( ) ? true : false ;
/**
* Get the data-file reference from "Scripts/" folder (Only works during development).
* @memberof JSONStorage
* @function getDataFile
* @returns {FileObject}
*/
inline function getDataFile( ) {
if( !DEV && ignoreWarnings != true ) {
Console.print( 'WARNING: (JSONStorage) You are trying to access to the JSONStorage.data file during production mode.' ) ;
} // prod-mode notice [^] ;
local scriptsDir = FileSystem.fromReferenceString( '{PROJECT_FOLDER}../Scripts/', FileSystem.AudioFiles ) ;
return scriptsDir.getChildFile( 'JSONStorage.data' ) ;
} ;
/**
* (DEV) Call this function to a quick data-file creation (remove `"include( 'JSONStorage.data' )" first to avoid errors`).
* @memberof JSONStorage
* @function createDataFile
* @returns {Void}
*/
inline function createDataFile( ) {
if( !DEV && ignoreWarnings != true ) {
Console.print( 'WARNING: JSONStorage.createDataFile( ) is only available at development (skipping).' ) ;
return void 0 ;
} // create if doesn't exists [v]
local scriptFile = getDataFile( ) ;
if( !scriptFile.isFile( ) ) {
scriptFile.writeString( "/** JSON STORAGE */" ) ;
} // finish [v] ;
return void 0 ;
} ;
/**
* Store the given JSON-Object into the current data and print a message in the console (used by the `"JSONStorage.data"` file).
* @param {Object} json - The object to store in the data-file.
* @memberof JSONStorage
* @function loadData
* @returns {Void}
*/
inline function loadData( json ) {
if( typeof json != 'object' ) {
return Console.print( 'ERROR:JSONStorage.loadData( ) requires 1 parameter: json<Object>.' ) ;
} // store in data prop [v] ;
data = json ;
Console.print( 'JSON-STORAGE-DATA LOADED.' ) ;
return void 0 ;
} ;
/**
* Get a stored JSON-Object with the given *key*.
* @param {String} key - The key of the stored object.
* @memberof JSONStorage
* @function get
* @returns {Object|Null}
*/
inline function get( key ) {
if( typeof key != 'string' ) {
return Console.print( 'ERROR:JSONStorage.get( ) requires 1 parameter: key<String>' ) ;
} else if( typeof data != 'object' ) {
data = { } ;
} // retreive [v] ;
return data[ key ] ;
} ;
/**
* (DEV) Write all current data into the `"JSONStorage.data"` file to be available during production mode (or next compilation).
* @memberof JSONStorage
* @function write
* @returns {Void}
*/
inline function write( ) {
if( !DEV && ignoreWarnings != true ) {
Console.print( 'WARNING: JSONStorage.write( ) is only available during development (skipping).' ) ;
return void 0 ;
} // save [v] ;
local fileContent = 'JSONStorage.loadData( ' + JSON.stringify( data ) + ' ) ;' ;
local scriptFile = getDataFile( ) ;
if( !scriptFile.isFile( ) ) { createDataFile( ) ; }
scriptFile.writeString( fileContent ) ;
Console.print( 'JSON-STORAGE-DATA UPDATED.' ) ;
return void 0 ;
} ;
/**
* (DEV) Store a JSON-Object with the given *key*.
* @param {String} key - The object key to store in the data-file.
* @param {Object} value - The actual object to store in the data.
* @memberof JSONStorage
* @function set
* @returns {Void}
*/
inline function set( key, value ) {
if( typeof key != 'string' || typeof value != 'object' ) {
return Console.print( 'ERROR:JSONStorage.set( ) requires 2 parameters: key<String> & value<Object>' ) ;
} // continue [v] ;
if( typeof data != 'object' ) { data = { } ; }
data[ key ] = value ;
if( autoWrite == true ) {
return write( ) ;
} else {
return void 0 ;
}
} ;
/**
* (DEV) Remove an specific object object from the stored data.
* @memberof JSONStorage
* @function remove
* @returns {Void}
*/
inline function remove( key ) {
if( typeof key != 'string' ) {
return Console.print( 'ERROR:JSONStorage.remove( ) requires 1 parameter: key<String>.' ) ;
} else if( !isDefined( data[ key ] ) ) {
return void 0 ;
} // remove [v] ;
data[ key ] = null ;
local obj = { } ;
local z ;
for( z in data ) {
if( !isDefined( data[ z ] ) ) { continue ; }
obj[ z ] = data[ z ] ;
} // finish [v] ;
data = obj ;
if( autoWrite == true ) {
return write( ) ;
} else {
return void 0 ;
}
} ;
/**
* (DEV) Remove all objects from cached-data. If `autoWrite` is enabled, it will clear the `"JSONStorage.data"` file too.
* @memberof JSONStorage
* @function clear
* @returns {Void}
*/
inline function clear( ) {
data = { } ;
if( autoWrite == true ) {
return write( ) ;
} else {
return void 0 ;
}
} ;
/**
* (DEV) Load a given file and stores it in the cached data.
* @param {FileObject|String} fileOrPath - The file or file-path to use in object loading.
* @param {String|Null} key=null - The *key* to use locate the loaded object into the *data*. If not set, the filename will be used as *key*.
* @param {Null|Boolean} forceUpdate=false - If set `false`, the object will be not loaded if already exists in the current cached-data.
* @memberof JSONStorage
* @function loadFile
* @returns {String} - The key used to access to the data (the filename without extension).
* @example
* JSONStorage.loadFile( '{PROJECT_FOLDER}../Objects/MyFile.json', null, true ) ;
* // It will be saved as 'MyFile' ;
* var json = JSONStorage.get( 'MyFile' ) ;
*/
inline function loadFile( fileOrPath, key, forceUpdate ) {
if( !DEV && ignoreWarnings != true ) {
Console.print( "(JSONStorage) You are trying to load a JSON-file during production-mode (skipping)." ) ;
return void 0 ;
} // skip during prod-mode [^] ;
if( !isDefined( fileOrPath ) ) {
return Console.print( 'ERROR:JSONStorage.loadFile( ) requires 3 parameters: fileOrPath<FileObject|String>, key<Null|String> & replace<Null|Boolean>.' ) ; ;
} // get file ref [v] ;
local file = typeof fileOrPath != 'string' ? fileOrPath : fileOrPath.indexOf( '{PROJECT_FOLDER}' ) == 0 ? FileSystem.fromReferenceString( fileOrPath, FileSystem.AudioFiles ) : FileSystem.fromAbsolutePath( fileOrPath ) ;
if( !file.isFile( ) ) {
return Console.print( 'ERROR:(JSONStorage) No JSON file found "' + file.toString( 0 ) + '"' ) ;
} // check [v] ;
local force = forceUpdate == true ? true : false ;
local name = typeof key == 'string' ? key : file.toString( 1 ) ;
if( !isDefined( data ) ) {
data = { } ;
} else if( typeof data[ name ] == 'object' && force == false ) {
return name ;
} // store it [v] ;
local json = file.loadAsObject( ) ;
data[ name ] = json ;
if( autoWrite == true ) { write( ) ; }
return name ;
} ;
} ;
And now you will be able to add your JSON files during development to access them in production (compiled binary):
include( 'JSONStorage.js' ) ;
include( 'JSONStorage.data' ) ; // <- You must include the data file just after the given script.
// LOADING FILES ;
JSONStorage.loadFile( '{PROJECT_FOLDER}../MyObjectsFolder/MyObject.json', null, false ) ;
// [^] Load 'MyObject.json' with no custom key (using the filename as key) and not update it at every compilation.
var file = FileSystem.fromAbsolutePath( 'C://myObject/path.json' ) ;
JSONStorage.loadFile( file, 'absoluteObject', true ) ;
// [^] Loads 'path.json' from file-object with custom key ("absoluteObject") and update it at every compilation.
// MANUAL ADD
JSONStorage.set( 'myManualObject', { prop1 : 'value' } ) ;
// All changes will be saved automatically into "JSONStorage.data" file 'cause JSONStorage.autoWrite is enabled.
// GET OBJECTS ;
var myObject = JSONStorage.get( 'MyObject' ) ; // The first json-file loaded in this example.
var data = JSONStorage.data ;
Console.print( trace( data ) ) ;
// EXPECTED PRINT [v] ;
// {
// MyObject : ... ,
// absoluteObject : ... ,
// myManualObject : ...
// }
//
Some tips:
Try to make data-changes only if you are in dev-mode.
var devMode = Engine.isHISE( ) ;
if( devMode == true ) {
// LOAD FILES [v]
JSONStorage.loadFile( 'FILE_PATH', 'myJSONFile', false ) ;
}
var myObject = JSONStorage.get( 'myJSONFile' ) ;
By default, to avoid errors, the module will skip changes (writing) in production mode, but it will print a WARNING message in the console. If you want to remove those message, just set the ignoreWarnings
property to true
in order to use all features without getting warnings (in production mode).
JSONStorage.ignoreWarnings = true ;
JSONStorage.loadFile( ... ) ;
Hope it can be helpful to someone :)