Forum Replies Created
-
AuthorPosts
-
nerobot, you the bomb!
feature creep, always feature creep
Been working with ted2go more today. A suggestion:
Can auto complete lists be sorted by a combination of casing, length and distance/popularity?
casing
If I type Item then the list should prioritise ItemBlah over itemBlahlength
If i type appl then the list should prioritise apple over AppleColordistance/usage (not as important as casing and length)
The list should try and sort by number popularity of keyword and also the closest recent usage of keyword. So for example if i define a Local variable, then autocomplete should favour this over variables further away in the file.Given a quick test, seems like it doesn’t redraw properly on startup when the flag is set. I have just a black screen. I have to manually find a gadget in the dark (mojox) that will trigger the redraw. It looks like if you set a smaller window size then the actual maximised sized, then this is where it does not redraw properly.
Also noticed there is no way to capture when the maximised state in the Window class. Would be nice to get a .Maximized and .Minimized Property on Window.
This works:
[/crayon]Monkey123[crayon-5cba820e5c1a0647449740 inline="true" ]Cast<SDL_WindowFlags>(SDL_GetWindowFlags(window.SDLWindow)) & SDL_WINDOW_MAXIMIZEDCould we have new events to wrap the SDL ones too:
[/crayon]Monkey12345[crayon-5cba820e5c1b6145748505 inline="true" ]SDL_WINDOWEVENT_MAXIMIZEDSDL_WINDOWEVENT_MINIMIZEDSDL_WINDOWEVENT_RESTOREDThere doesn’t seem to be a way to capture these without modifying mojo. Would it be possible to add a RawEvent:Void() callback to the app class? So we can hook into all SDL events, even ones not captured into mojo?
winner thanks
Liking ted2go so far, good work!
Can I suggest switching the icons to something a bit more monochrome (and modern looking) to fit with the solid color theme of ted2?
http://fontawesome.io/icons/Handy tool here for converting to png:
http://fa2png.io/r/font-awesome/winner! so let me tell you some more about promises!
lol
[/crayon]Monkey123456789101112131415161718192021[crayon-5cba820e66937888952707 inline="true" ]function ItemPromise(id) {return new Promise(function(resolve, reject) {let item = {};//get the item or do something//finishedresolve(item);});}let jobs = [];for(let index = 0; index < 20;index++) {jobs.push(ItemPromise(index));}Promise.all(jobs).then(function(items) {//we now have 20 items that have been fetched async, all 20 items are being fetched at the same time, with little setup!}).catch(function(err) {console.log('something went wrong');});I dunno, but this just pleases me.
I think the benefit of promises cant really be shown in just one small snippet. For promises to be useful, everything has to be promises. So fetching from database, a promise. Creating an object, promise. Everything a promise. Then you can just encapsulate all your routines as promises. You can flow them together without really thinking. You can have one catch to rule them all as well. Regardless of which library the promise lives.
But pretty much your correct. Promises are are to *fix* javascript lack of async/fiber. They were also introduced to solve the problem of a nested nightmare of callbacks.
However javascript does have async/await on the horizon https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/async_function it’s just not fully mainstream yet. I get the impression they are implementing this to *fix* the issues that promises brought with it.
But yeah going off topic a little. I agree with tyou, mx2 should not go the promise route. The async/await using fibers/futures is much nicer!
Well how about something like this:
[/crayon]Monkey123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869[crayon-5cba820e6d427332138306 inline="true" ]function loadUser() {return fetchUserData("skn3").then(function(user) {return downloadImage(user);});}function fetchUserData(id) {return new Promise(resolve, reject) {return database.users.query.where('username',id).then(function(user) {if (user.banned) {reject(new Error('access denied'));} else {resolve(user);}});}}function downloadImage(user) {return new Promise(function(resolve, reject) {if (!network.isConnected) {reject(new Error('not connected foo));} else {let localPath = '/localFiles/users/'+user.username+'.png';return network.get('http://www.images.com/users/'+user.username+'.png', localPath).then(function(image) {user.image = localPath;resolve(user);});}})}class userWidget() {constructor(id) {this.id = id;this.user = null;this.div = document.appendthis.div = document.createElement('div');this.div.style.width = '100px';this.div.style.height = '100px';let that = this;this.div.addEventListener('click',function(event) {if (that.user == null) {that.load();}});document.body.appendChild(this.div);}load() {let that = this;loadUser(this.id).then(function(user) {that.user = user;that.div.style.backgroundImage = 'url('+user.localPath+')';}).catch(function(err) {console.log('failed');})}}I can create modular promises that can perform async operations, and then have one final destination for catching exceptions.
async and await are nice, but at the same time promises do have their merits. They fall down when you need to pass around more information then just one thing. You either have to contain the data in the parent closure, or build objects by passing it down the .then() chain. Its also possible to use Promise.all([]) and then build your object at the end. The .then() of Promise.all([]) receives an array with each promises result.
Well clearly myn is a fugly LOL! I was trying to make it a self contained pattern, also similar to javascript with the commands passed to the callback/promise.
Anyway, I just tried your version and this works a charm. My example modified to yours:
[/crayon]Monkey1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465[crayon-5cba820e72e3b649935654 inline="true" ]Namespace myapp#Import "<std>"#Import "<mojo>"Using std..Using mojo..'await codeFunction Await<T>:T(future:Future<T>)Return future.Get()EndFunction Async:Future<Int>(callback:Int())Local future:=New Future<Int>New Fiber(Lambda()Local result:=callback()future.Set(result)End)Return futureEndFunction Main:Void()New AppInstanceNew MyWindowApp.Run()EndClass MyWindow Extends WindowMethod OnRender( canvas:Canvas ) OverrideApp.RequestRender()canvas.DrawText( "Hello World! "+Rnd(0,1),Width/2,Height/2,.5,.5 )EndMethod OnKeyEvent( event:KeyEvent ) OverrideIf event.Type = EventType.KeyUpSelect event.KeyCase Key.Space'create wrapper fiber so we are not executing on main fiberNew Fiber(Lambda()'await valuePrint Await<Int>(Async(Lambda:Int()Local start := App.MillisecsWhile App.Millisecs - start < 3000Fiber.Sleep(0)WendReturn 555End))Print Await<Int>(Async(Lambda:Int()Local start := App.MillisecsWhile App.Millisecs - start < 3000Fiber.Sleep(0)WendReturn 123End))End)EndEndifEndEndSo your correct about the theory. Once you start pushing around those async operations you have to keep doing so.
I have had most experience using Promises in Javascript. With those you fire off a ton of operations which signal to the promise when they are complete. Like so:
[/crayon]Monkey123456789101112131415[crayon-5cba820e72e41952246975 inline="true" ]New Promise(function(resolve,reject) {'do something blockinglet success = blocking();if (success) {resolve(123);} else {reject(new Error('uh oh));}}).then(result)console.log(result);'123.catch(function(err){'errortime})The awesomeness is you can keep returning new promises from your promise, or your .then() to chain together functionality into you callbacks. So you can break your code up into say, fetchUser(), generateImage(), updateCounters(), etc and have each return a promise. You can then piece together complex tasks and receive your result back in a chain of .then()’s.
There is also Promise.All([]) which fires off a list of promises at once, and then() is called once all have finished.
But anyway…
I removed my code above as was getting it to work. And here is the finished result
[/crayon]Monkey1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374[crayon-5cba820e78d13995836044 inline="true" ]Namespace myapp#Import "<std>"#Import "<mojo>"Using std..Using mojo..'await codeFunction Await<T>:T(callback:Void(Resolve:Void(value:T),Yield:Void()))Local future := New Future<T>'create fiber to handle our awaitLocal fiber := New Fiber(Lambda()'sleep the fiber so we get a chance to start the futureFiber.Sleep(0)'execute callbackcallback(Lambda(value:T)'Resolve()future.Set(value)End, Lambda()'Yield()Fiber.Sleep(0)End)End)Return future.Get()EndFunction Main:Void()New AppInstanceNew MyWindowApp.Run()EndClass MyWindow Extends WindowMethod OnRender( canvas:Canvas ) OverrideApp.RequestRender()canvas.DrawText( "Hello World! "+Rnd(0,1),Width/2,Height/2,.5,.5 )EndMethod OnKeyEvent( event:KeyEvent ) OverrideIf event.Type = EventType.KeyUpSelect event.KeyCase Key.Space'create wrapper fiber so we are not executing on main fiberNew Fiber(Lambda()'await valuePrint Await<Int>(Lambda(Resolve:Void(value:Int), Yield:Void())Local start := App.MillisecsWhile App.Millisecs - start < 3000Yield()WendResolve(123)End)'await valuePrint Await<Int>(Lambda(Resolve:Void(value:Int), Yield:Void())Local start := App.MillisecsWhile App.Millisecs - start < 2000Yield()WendResolve(555)End)End)EndEndifEndEnd.
When I was writing the previous reply, trying to ponder the ramifications of the Async suggestion, I did burn a few thousand braincells in the process! So yeah thats gonna be a long trip down the rabbit hole if you go that route!
The mojox thing does sound like a decent stop gap, as your not gonna break anything core in monkey2.
.
Yeah the JS editor is a pain in the ass when adding code! Is there a markdown plugin for wordpress? Would be nice to use that instead! (https://en.support.wordpress.com/markdown/)
Well I guess everything would have to be on a fiber. Anything else and you are always going to find a scenario where this may happen?
Could we potentially tag our functions/lambdas as async, which indicates their calling mechanism? So it could be used like so:
[/crayon]Monkey1234[crayon-5cba820e81f50726555112 inline="true" ]Function DoFiberThing:Void() AsyncLocal value := TextDialog.Run("blah blah",text,New String[]("ok"))Endlist.Clicked += DoFiberThingor
[/crayon]Monkey123[crayon-5cba820e81f56177301264 inline="true" ]list.Clicked += Async()'this is a lambda, but async versionEndI am surprised that emscripten doesn’t support fibers. future versions of JS will have generators, which are similar… https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/function*
I created a small util function:
[/crayon]Monkey1234567[crayon-5cba820e85b32742638168 inline="true" ]Function CallFunction:Void(func:Void())#if __TARGET__ <> "emscripten"New Fiber(func)#Elsefunc()#endifEndWhich is used like:
[/crayon]Monkey12345[crayon-5cba820e85b37757301478 inline="true" ]list.ItemClicked = Lambda(item:ListView.Item)CallFunction(Lambda()DoFiberThing(item.Text)End)EndIt doesn’t work. Now it fails to build with
C:/dev/projects/monkey1/conveyor/tools/itemMaker/itemMaker.buildv1.0.91/windows_debug/src/itemMaker_classes_2utils.cpp:192:27: error: declaration of ‘t_std_fiber_Fiber l_func’ shadows a parameter
t_std_fiber_Fiber(l_func);
If I change it to the follow, then it works:
[/crayon]Monkey123456789[crayon-5cba820e85b3d146097767 inline="true" ]Function CallFunction:Void(func:Void())#if __TARGET__ <> "emscripten"New Fiber(Lambda()func()End)#Elsefunc()#endifEndBut this does seem a bit cludge!
-
AuthorPosts