About Monkey 2 › Forums › Monkey 2 Programming Help › ProgressDialog useless ?
This topic contains 10 replies, has 4 voices, and was last updated by
Mark Sibly
2 years, 6 months ago.
-
AuthorPosts
-
October 1, 2016 at 5:35 pm #4208
I’m searching for a way to show a progressbar with text , and so I found mojox progressDialog.
But my ‘game’ load many atlas files and other data, and the progressDialog is only visible after everything is loaded
Monkey1234567891011121314151617181920212223Method createStartupScreen:Void()' every game use a START buttonLocal button:=New Button("Start")button.Clicked=Lambda()Local progress:=New ProgressDialog( "Modeless Progress Dialog","Performing incredibly intense calculations..." )' Show the progressDialog , but its not visibleprogress.Open()' still not visibleLoadScene() ' heavy atlas loading and stuff' If its visible, I want to use the progress.Text = "load x"' now after everything is loaded, the progressbar is visible (but useless now)' progress.Close()EndLocal dockingView:=New DockingViewdockingView.AddView( button,"top" )App.ActiveWindow.ContentView=dockingViewEndOctober 2, 2016 at 7:05 am #4222Hi
not at the computer atm, but it seems that ‘progress’ is not attached to ContentView, so nothing it’s shown.October 2, 2016 at 7:48 am #4223But I see the progressbar after everything is loaded.
In the mojox modules/test Mark Does the same.
October 2, 2016 at 8:23 am #4224You can’t asynchronously load stuff yet.
The ted2 ‘building’ process works because there is some native code behind the scenes of the Process class that effectively runs mc2cc on a different thread. But there is nothing like that for loading images etc yet.
It shouldn’t be too hard to do though, the only catch being that the loaders will need to run on a fiber.
October 2, 2016 at 8:29 am #4225To say it in other words, When I put the loaders inside a Fiber then its async ?
I can see a Fiber lick a backgroundworker for c#
Going to try that.
October 2, 2016 at 10:02 am #4226another way would be to show (some form of dialog/progress control)
update it after each load.
so for 10 loads you would be advancing at 10% after each load
October 2, 2016 at 3:21 pm #4228@AdamStrang
That’s is not possible I think because
Everything is rendered on the screen after that the LoadScene() is ready.
LoadScene includes only JsonObject.Load() , object generation, image (atlas) loadingBut async LoadScene() would be the thing needed here for a method.
Simply fiber using don’t work, or I don’t understand how a Fiber works
Monkey1234567891011121314151617181920Method createStartupScreen:Void()Local button:=New Button("Start")button.Clicked=Lambda()Local progress:=New ProgressDialog( "Modeless Progress Dialog","Performing incredibly intense calculations..." )progress.Open()' progressbar not visible yetNew Fiber( Lambda()LoadScene()End )' progressbar visible after LoadScene is readyEndLocal dockingView:=New DockingViewdockingView.AddView( button,"top" )App.ActiveWindow.ContentView=dockingViewEndAnother possible idea was a function like this.
progressbar.Ready += LoadScene()
Monkey1progress.Open()That is that the progressbar is visible now at the screen and can retrieve .Text changes callable from outside the LoadScene()
October 2, 2016 at 9:46 pm #4231For a simple fix, try running your loading code on a fiber and calling this after each ‘LoadImage’ etc…
Monkey12345678910Function Yield()Local future:=New Future<Bool>App.Idle+=Lambda()future.Set( True )Endfuture.Get()EndThe key thing about fibers is that they’re *not* threads – if one fiber blocks, everything blocks, so a simple Repeat…Forever will hang the entire app.
October 3, 2016 at 5:21 pm #4247@mark
copy / pasting your code I can see the progress dialog !
the progessbar not ‘moving’, and I see now that it don’t support the step/value
BUT
The text is changing like I was hoping, so I/user can see what is loading.
Monkey12345678910111213Function Yield(progressText:String=Null)Local future:=New Future<Bool>App.Idle+=Lambda()future.Set( True )Endfuture.Get()If progressText<>Null Thenprogress.Text = progressTextEndEndBut you say a fiber is not a async and not a background task.
But what is it, where does it live.If you say yes to this, then I understand it.
> Inside the Yield() function above, I can change every runtime variable, this within a loop or process that is running at the moment ?Function BlockingHeavyThing()
yield(“heavything() start”)
heavything()
yield(“start heavything2()”)
heavything2()
EndRenderloop {
New Fiber( Lambda()
BlockingHeavyThing()
End )DOESstartThisAfter_BlockingHeavyThing_isReady() ‘ duh
}
I see this in your code
Monkey123App.Idle+=Lambda()future.Set( True )EndDoes App.Idle resets itself after a loop ?
Because when I load 1000+ things I get internal 1000+ App.Idle+=things I don’t know if this is a problem.What future does is abracadabra (I did read the module info about it) but for now it works with the text.
I think that in the near future you need to make the gui async , on a other thread or something if you want that many people make applications with monkey.
October 3, 2016 at 7:08 pm #4249Quick idea: add an App.RequestRender() to the bottom of Yield().
But what is it, where does it live.
‘On the stack’, really. Fibers are very similar to threads in that each has its own stack and set of CPU registers, only fibers *never* switch ‘behind your back’ the way threads do. A little old, but more info here:
http://monkey2.monkey-x.com/2016/02/01/func-with-fibers/
Does App.Idle resets itself after a loop ?
Yes, anything you add to App.Idle is only called once, so you need to keep ‘re-adding’ idle handlers if you want them to keep being called.
Inside the Yield() function above, I can change every runtime variable, this within a loop or process that is running at the moment ?
Yes, fibers execute in the same address space so they have access to the same globals etc.
I think that in the near future you need to make the gui async , on a other thread or something if you want that many people make applications with monkey.
Nope, the fiber based GUI rocks (and is a common ‘modern’ approach). The problem here is that LoadImage etc. ‘block’. Solving that the way I did with processes and tcpstreams should be quite easy for me to do, and would solve your problems here without you having to change anything.
On the other hand, having a progress dialog running on one thread while loaders run on another is a vastly more complex proposition, as suddenly things need to be synched via mutexs, semaphores. Threads are HARD, and I think the GUI does an excellent job of shielding users from having to deal with them, although obviously there are still ‘holes’ in what is fully supported.
IMO, Ted2 achieves a remarkable level of apparent parallezation (eg: you can type in textviews while programs are building etc) thanks to the fiber system, as you don’t have to really think about synchronization at all (almost anyway) the way you do with threads. In fact, far more works ‘in parallel’ in Ted2 than probably should, but I didn’t design that way, it just works!
Which is not to say threads aren’t useful – being able to load data on a thread is useful. But it’ll be considerably tricker as you’ll have to start dealing with mutexs, semaphores etc. I am personally interested in being able to run OnRender ‘on a thread’, or physics etc – which is another reason that it’s nice for the GUI to use as *few* threads as possible, as it saves threads (ie: cores) for rendering, physics etc. But that’s a way of yet…!
October 3, 2016 at 8:22 pm #4251Ok, just had a quick play and this works pretty well for me:
Monkey1234567891011121314151617181920212223242526272829303132333435363738Function Yield()Local future:=New Future<Bool>App.Idle+=Lambda()future.Set( True )Endfuture.Get()App.RequestRender()EndFunction LoadGraphics:Image( path:String )Local progress:=New ProgressDialog( "Loading..." )progress.MinSize=New Vec2i( 320,240 )progress.Open()Local image:ImageFor Local i:=0 Until 250If image image.Discard()progress.Text="Loading image "+iimage=Image.Load( path )Yield()Endprogress.Close()Return imageEndNote: this MUST be run on a fiber, or you’ll get a ‘can’t suspend GUI fiber’ error. This means it should also set a ‘loadingFinished’ flag or something similar when it’s done.
All it does is load the same image a bunch of times, but the progress dialog updates and can be dragged around.
It’s not the *ideal* solution – you shouldn’t need to manually ‘Yield’ – but I think it’s acceptable until I get a chance to do more work on this.
-
AuthorPosts
You must be logged in to reply to this topic.