Nodragem Posted November 3, 2018 Share Posted November 3, 2018 I would like to be able to load a text file (or json, csv, and other text-based files) as simply as I do with textures. Something like that this.dictionary = new BABYLON.TextFile("./assets/data/dictionary.txt"); console.log(this.dictionary); I would like my text file to de loaded synchronously so that I am sure I can read its content once I run the line that loaded it. But it seems that there is no way to do so ? that just drives me crazy. Quote Link to comment Share on other sites More sharing options...
JCPalmer Posted November 3, 2018 Share Posted November 3, 2018 LoadFile is what gets run for things like a .babylon or sound file. The second arg is a success function callback. You cannot really do any synchronous file loading except for script & other files listed in a html file. Even then, it is not really synchronous, just performed before control is passed. Do Something like: BABYLON.Tools.LoadFile("./assets/data/dictionary.txt", (data) => { this.dictionary = data; console.log(data); }); Quote Link to comment Share on other sites More sharing options...
Dad72 Posted November 3, 2018 Share Posted November 3, 2018 You can do this this way to load a json file synchronously (with $.ajaxSetup({ async: false});) function getJson() { var text = ""; $.ajaxSetup({ async: false}); $.getJSON(dictionary.json?" + Date.now(), (data) => { text = data; }); $.ajaxSetup({ async: true}); return text; } var myText = getJson(); Quote Link to comment Share on other sites More sharing options...
Nodragem Posted November 3, 2018 Author Share Posted November 3, 2018 1 hour ago, JCPalmer said: LoadFile is what gets run for things like a .babylon or sound file. The second arg is a success function callback. You cannot really do any synchronous file loading except for script & other files listed in a html file. Even then, it is not really synchronous, just performed before control is passed. Do Something like: BABYLON.Tools.LoadFile("./assets/data/dictionary.txt", (data) => { this.dictionary = data; console.log(data); }); The issue of this solution is that this is not synchronous. Hence when I try to use my dictionary from an other object, I get an error because the dictionary is still "undefined". @Dad72 I am new in web development, I am using Typescript. Is there big drawback in using jQuery? In term of memory usage and mobile web? Thank you for your answers! Quote Link to comment Share on other sites More sharing options...
Dad72 Posted November 3, 2018 Share Posted November 3, 2018 No, there is no inconvenience, Jquery is very good, performing, but I do not know how to use it with typescript, but I guess it should not be a problem. try. Quote Link to comment Share on other sites More sharing options...
JohnK Posted November 4, 2018 Share Posted November 4, 2018 These PGs load meshes for synchronous use and perhaps using addTextFileTask rather than addMeshTask they could be adapted https://www.babylonjs-playground.com/#YGUADW%2311 https://www.babylonjs-playground.com/#YGUADW%238 from or it could be a complete red herring Quote Link to comment Share on other sites More sharing options...
Nodragem Posted November 4, 2018 Author Share Posted November 4, 2018 @JohnK That's not really synchronous, but yes, I thought of a similar solution. Ultimately I thought I will have to use the AssetManager and start the game when it is loaded and then access the assets by name from the Scene... However, you can't access a Text-based asset by name from the Scene. Here is the list of things you can retrieve by name: Async / Await as a solution I started to play with async / await, which are very similar to Coroutine / Yield in C# (or python). Basically you can start an "async" function (Coroutine), in which you can use "await" to block the code execution until a Promise is resolved (Yield). Instead of using BABYLON.Tools.loadFile(), I use d3-fetch, which is part of d3.js, a library for handling and visualizing data. As d3-fetch is based on fetch API and Promises, it is compatible with async / await. As far as I understand, BABYLON.Tools.LoadFile() returns a IFileRequest and hence, it is not compatible with async / await. Here is the code I came up with: class LetterData { letterTable:any; async loadData(){ let s:any = await d3f.csv("./assets/data/letter-frequency.csv"); this.letterTable = s; } } class Game { constructor(canvasElement : string) { // Create canvas and engine. this._canvas = document.getElementById(canvasElement) as HTMLCanvasElement; this._engine = new BABYLON.Engine(this._canvas, true); this.start(); // this is equivalent to a Coroutine // I could display a loading screen here in parallel to this.start() ... } async start(){ // here every single functions wait for the previous one to be terminated before to start await this.initScene(); await this.loadUI(); // we are 100% sure that the scene was loaded when we start making the UI await this.initRendering(); } async initScene() { console.log("Loading...") this._scene = new BABYLON.Scene(this._engine); await new Promise((resolve, reject) => { window.setTimeout(() => resolve("simulating loading time here!"), 1000) }); console.log("Loading done!") } async loadUI() { let letterData = new LetterData(); await letterData.loadData(); // I am 100% sure that the data is accessible now: console.log(letterData.getEnglishLetterDistribution()); } async initRendering() {} } The only drawback on this await / async solution is that I need to add "es2015" to "lib" in my tsconfig.json. After this change, "console.log" was not recognised by typescript anymore and I needed to add "dom" to "lib". One drawback I can think of is that I have no idea if that makes the code incompatible with some browsers, or make the dependencies heavier. But I can say for definite that await / async is a very nice things to have for game dev (to create a game loop coroutine for instance). EDIT: So I checked, and it seems we can add lib = ["es2015", "dom"] to the tsconfig.json without messing up compatibility with browsers, as the target stays the same. ... Any one to confirm? Quote Link to comment Share on other sites More sharing options...
Guest Posted November 5, 2018 Share Posted November 5, 2018 async await WON'T work on old browsers (but most will be fine) as an intermediate solution you can uses promises (Babylon.js will provide a fallback for you) so instead of await loadData() you will end up wtih loadData().then(...) but at least it will work even on ie 11 Quote Link to comment Share on other sites More sharing options...
Nodragem Posted November 9, 2018 Author Share Posted November 9, 2018 Actually I found this link in the documentation which speaks about Async/Await: https://doc.babylonjs.com/how_to/promises On 11/5/2018 at 6:26 PM, Deltakosh said: async await WON'T work on old browsers (but most will be fine) as an intermediate solution you can uses promises (Babylon.js will provide a fallback for you) so instead of await loadData() you will end up wtih loadData().then(...) but at least it will work even on ie 11 I am not sure that .then(...) avoids "having to deal with pyramids of callbacks intricated in a non easy to maintain way." (cited from the documentation link above). I get the impression I will end up doing Promise.then().then().then().then() ? So... I guess that means I won't support old browsers ? thank you for letting me know! Quote Link to comment Share on other sites More sharing options...
Guest Posted November 10, 2018 Share Posted November 10, 2018 Well yeah this is a bit better still than pure pyramidal callbacks but if you do not need to support old browsers then async/await is magic Nodragem 1 Quote Link to comment Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.