Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

Working with loading background and progress bar.
Started by swanandthakur1105 Mar 05 2018 07:13 AM

* * * * * 1 votes
38 replies to this topic
gui
[TOPIC CONTROLS]
Page 2 of 2 1 2
This topic has been archived. This means that you cannot reply to this topic.
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#26

remiduchalard

[GLOBAL: userInfoPane.html]
remiduchalard
  • Contributor

  • 306 posts
  • Corona SDK

If you want to have a loading animation and loading time depend of device perf you can do:

You split your loading in few coroutine (more than 6) and add a lot of "coroutine.yield()" in your loading code.

Then run all your coroutine and add them in an array.

At all enter frame resume some unfinish coroutine. If the frame rate is at 30fps you resume the same number as the last enterframe. If the frame rate is under 30fps resume less coroutine and if higher than 30fps resume more coroutine.

 

With a code like this you can mine bitcoin on device and don't impact the app ;)

The loading time is 2.6x faster with this kind of loading than if you load normaly (with no coroutine) (I think it's help the CPU to use more thread)

 

My code used in Stronghold and Gate Of Heroes if you don't know how to do it.

	local cpt=0
	function coroutinegestion(event)
		if not desactivecoroutine then
			nbframetoremove=nbframetoremove+1
			actualtime=event.time*0.001
			fpsactif=fpsactif*0.75+0.25*1/(actualtime-oldtime)
			if fpsactif>30 then
				fpsactif=30
			end
			-- chaineroutine=chaineroutine.." fps= "..fpsactif
			oldtime=actualtime
			if fpsactif>26 then
				nbroutinesametime=nbroutinesametime+1
			elseif fpsactif<20 and fpsactif>13 then
				nbroutinesametime=nbroutinesametime-1
			else
				nbroutinesametime=0
			end
			if coroutinemiregime and nbroutinesametime>1 then
				nbroutinesametime=1
			end
			if coroutinemiregime and not issimulator then
				nbroutinesametime=0
			end 
			if fullcouritine then
				nbroutinesametime=10
			end
			if true then --cptfirst>=10 then
				coroutineutile=false
				routinesametime=0
				--cptfirst=0
				if nbroutinesametime>0 then
					local coroutineactive=""
					for i=1,#tabcorourtine do
						if coroutine.status(tabcorourtine[i])~="dead" then
							if nbroutinesametime>=routinesametime then
								routinesametime=routinesametime+1
								coroutine.resume(tabcorourtine[i])
								coroutineactive=coroutineactive.." i "..i --print("coroutine "..i.." est toujours en activité")
								coroutineutile=true
								nbcoroutine=nbcoroutine+1
								--chaineroutine=chaineroutine.."\n coroutineutile coroutine "..nbcoroutine.."  #tabcorourtine "..#tabcorourtine.." i="..i
							else
								break
							end
							-- print("pas")
						end
					end
					chargementdesfichiertt=0
					local coroutinepasfini=""
					for i=1,#chargementdesfichier do
						chargementdesfichiertt=chargementdesfichiertt+chargementdesfichier[i]
						if chargementdesfichier[i]==0 then
							coroutinepasfini=coroutinepasfini.." "..i
						end
					end
					local textureut
					if issimulator then
						cpt=cpt+1
						if cpt>5 then
							cpt=0
							local memUsed = mathfloor((collectgarbage("count"))/1000*10)*0.1
							local texUsed = system.getInfo( "textureMemoryUsed" ) / 1000000
							textureut="Texture Memory Used: "..memUsed.." "..string.format("%.03f", texUsed).."Mb"
							print("fpsactif "..mathfloor(fpsactif).." nbroutinesametime "..nbroutinesametime.." coroutine "..coroutineactive.." en activité et "..coroutinepasfini.." pas fini "..textureut)
						end
					end
					if nbroutinesametime>routinesametime then
						nbroutinesametime=routinesametime
					end
				end
			else
				cptfirst=cptfirst+1
			end
		end
	end
	Runtime:addEventListener("enterFrame",coroutinegestion)


[TOPIC: post.html]
#27

swanandthakur1105

[GLOBAL: userInfoPane.html]
swanandthakur1105
  • Enthusiast

  • 83 posts
  • Corona SDK

In my last attempt to achieve the functionality what I had done was I had distributed a function in 3-4 co-routines.yield() and then by using timer.performWithDelay( ) after every second I was resuming the suspended process, it was working great but then it strike me like if the process do not get completes in one second then it will remain incomplete and as I am forcing another co-routine to resume the next co-routine will take place.

What I am thinking is correct?? If wrong please help me to bring more clarity in my thoughts.

 

 

Regards,

Swanand Thakur



[TOPIC: post.html]
#28

swanandthakur1105

[GLOBAL: userInfoPane.html]
swanandthakur1105
  • Enthusiast

  • 83 posts
  • Corona SDK

Sorry no.  That is as simple as it gets: 

  1. Fake workload to demo problem,
  2. Three examples showing how to display work load (one showing issue; second showing native activity indicator, third showing enterFrame solution).

If this is too hard to understand at this point, you're better off just living with the delay.  This isn't a simple thing.

 

PS - As @sgs pointed out: "Doing this is a significant chunk of work."  This technique requires both knowledge and discipline to deal with.  If you'e new, this may be beyond your current skills.

Please is it possible for you to add some more comments in your that code only for scene3.lua ?? If you would be able to do that then it will definitely help me to understand it.



[TOPIC: post.html]
#29

remiduchalard

[GLOBAL: userInfoPane.html]
remiduchalard
  • Contributor

  • 306 posts
  • Corona SDK

In my last attempt to achieve the functionality what I had done was I had distributed a function in 3-4 co-routines.yield() and then by using timer.performWithDelay( ) after every second I was resuming the suspended process, it was working great but then it strike me like if the process do not get completes in one second then it will remain incomplete and as I am forcing another co-routine to resume the next co-routine will take place.

What I am thinking is correct?? If wrong please help me to bring more clarity in my thoughts.

 

 

Regards,

Swanand Thakur

What do you have in your coroutine? Normally it doesn't change anything expect if you do something like that:

Coroutine one :
tab[#tab+1]=value
coroutine two :
tab[#tab+1]=value

It can write two time in the same index. This problem can also happen without coroutine if you do in a lot of listener with that



[TOPIC: post.html]
#30

davebollinger

[GLOBAL: userInfoPane.html]
davebollinger
  • Corona Geek

  • 1,373 posts
  • Corona SDK

keep in mind that corona is single-threaded*, and thus, so are coroutines and listener callbacks and timers and etc, so these sorts of concurrency concerns don't actually happen in practice.  coroutines run with their own execution stack, and so are interruptable/resumable, and sort of act like threads in that regard, but they're not true threads in the "multi-tasking" sense implied.

 

(* at least the part that you can directly experience from lua, which is itself not thread-safe, so that's a requirement; but excluding things like audio worker threads and other system-level threads that may truly be operating asynchronously, but you can't directly experience those anyway.   i suppose if you're writing your own native libs you could potentially?? mess with this 'agreement', but you'd probably crash regularly)



[TOPIC: post.html]
#31

remiduchalard

[GLOBAL: userInfoPane.html]
remiduchalard
  • Contributor

  • 306 posts
  • Corona SDK

@davebollinger Have you already have a look on CPU use on android device?



[TOPIC: post.html]
#32

davebollinger

[GLOBAL: userInfoPane.html]
davebollinger
  • Corona Geek

  • 1,373 posts
  • Corona SDK

@remiduchalard - I'm not sure I follow your question...  Are you suggesting that just because multiple cores are "occupied" then that implies that Lua must be multithreaded?  An app spawns all sorts of processes (witness any crash dump) but your Lua code is only running on one of them.

 

Here's an experiment:  build something like below into an app, run it, drag across the screen, wait for the timeout ANR, then check:  how many threads were dead?

local rect = display.newRect(display.contentCenterX, display.contentCenterY, display.actualContentWidth, display.actualContentHeight)
rect.touch = function(self,event)
  print("touch")
  while true do end -- infinite loop
end
rect:addEventListener("touch")

if Corona's use of Lua were multithreaded, then as each individual move phase of your swipe continues to lock up new threads, eventually you'd have many threads locked (at least more than one, up to whatever imagined level of threading you suspect exists) and you'd see lots of prints in the logcat.  but that won't happen.  you'll get one print, halt the main thread, then ANR.



[TOPIC: post.html]
#33

StarCrunch

[GLOBAL: userInfoPane.html]
StarCrunch
  • Contributor

  • 842 posts
  • Corona SDK

 

(* at least the part that you can directly experience from lua, which is itself not thread-safe, so that's a requirement; but excluding things like audio worker threads and other system-level threads that may truly be operating asynchronously, but you can't directly experience those anyway.   i suppose if you're writing your own native libs you could potentially?? mess with this 'agreement', but you'd probably crash regularly)

 

It's certainly an interesting development experience, in Corona or otherwise.  :)

 

I've wrapped luaproc, but the Coronification process is ongoing. Lately I've been trying to hammer out various issues with someone, including how to conveniently use modules and plugins. (This of course imposes requirements on them, such as: no shared state, e.g. the majority of math; use thread-local variables (which iOS does not support in C++, requiring rolling your own); or copious use of mutex and friends.) Suspend, resume, shutdown et al. present a number of challenges as well.

 

Alternatives that I'm aware of are Lanes, Torch Threads, and Effil. Lanes and luaproc were what I knew of / were available when I started, and it was basically a coin flip. Some of the API details marked WIP in my docs might be better served in a companion plugin, in particular if say anybody makes plugins of the other packages and wants to use them, but so far I'm unaware of any such efforts. (If I'm wrong, please get in touch!) As an example of what I have in mind with companion plugins, see the (also-WIP) functions in my MemoryBlob plugin which are designed around passing memory chunks among threads.



[TOPIC: post.html]
#34

davebollinger

[GLOBAL: userInfoPane.html]
davebollinger
  • Corona Geek

  • 1,373 posts
  • Corona SDK

 e.g. the majority of math;

 

start with math.random() as an easy test of proper serialization ;)



[TOPIC: post.html]
#35

remiduchalard

[GLOBAL: userInfoPane.html]
remiduchalard
  • Contributor

  • 306 posts
  • Corona SDK

@davebollinger It's use a single core for all lua processing but for loading image in imagesheet there is a major different time of execution. It's perhaps not because it s use multi core but in fact is faster.



[TOPIC: post.html]
#36

SGS

[GLOBAL: userInfoPane.html]
SGS
  • Corona Geek

  • 2,197 posts
  • Corona SDK

Imagesheets perform much faster (than single assets) due to the GPU being able to batch draws for requests from the same imagesheet without making context switches.



[TOPIC: post.html]
#37

davebollinger

[GLOBAL: userInfoPane.html]
davebollinger
  • Corona Geek

  • 1,373 posts
  • Corona SDK

@davebollinger It's use a single core for all lua processing but for loading image in imagesheet there is a major different time of execution. It's perhaps not because it s use multi core but in fact is faster.

 

i wasn't intending to say ANYTHING re performance because that's too hard to comment on generically without benchmarking.  fe, you may have stumbled on a staggering of processing that better utilizes file operations or some-such - great, not questioning that.  i know for myself it helps a lot to stagger network, audio, file operations on startup because some may spawn additional system-level worker threads.

 

i only wanted to comment on the concurrency topic that was brought up - fe, altering a value "simultaneously" from two different event listeners.  that sort of thing doesn't happen.  (at least, not unless you've got some native code in there, like StarCrunch, to implement multithreaded support - and the chaos that ensues! :D)



[TOPIC: post.html]
#38

remiduchalard

[GLOBAL: userInfoPane.html]
remiduchalard
  • Contributor

  • 306 posts
  • Corona SDK

@davebollinger don't worry I don't mishandle what you have written. I just said, that my loading time was more than 30 sec to less than a sec (loading when the user is in the game menu win a lot of time of apparent loading and loading with my algo)



[TOPIC: post.html]
#39

zombiexp2010

[GLOBAL: userInfoPane.html]
zombiexp2010
  • Enthusiast

  • 56 posts
  • Corona SDK

Heeeeey, guys! This is not a problem since you can load resources by yourself one by one, do them visible/invisible and unload them.

 

Much more problem is to draw or find cool progress bars to use and to separate to categories some resources that take a lot of time to be loaded and another only a little while)))))

 

In example you have 20 animations of main character, 10 of are «long» and 10 «fast» to load. So just keep in mind that each sheet of first ones you will fill your progress bar with 7% each (10 sheets x 7% will take 70% of time to load) and 3% for lightweight second part (30%)

 

Look, you just need:

 

Steps:

1.   to show some pretty progress screen with such bar zero percent filled

2.   Enter-Frame listener routine will do our work

      hard-sprite = display.newImageRect(...)

      hard-sprite.alpha = 0

      progressbar.value += 7%

      once again for each

      light-sprite = display.newImageRect(...)

      light-sprite.alpha = 0

      progressbar.value += 3%

      once again for each

3. Unloading progress bar screen resources and arranging all our already loaded but invisible sprites to their places, setting up physics and other properties

4. unpausing physics and timers and in each frame routine we increment alpha of objects to become positive to make fade effect of appearing our objects. 

 

That's it! This approach is very old, time-tested, simplest, easy to use and to understand, but needs from you to do some tests to notice loading time for resources to balance loading to be smoother looking.

 

Also on PCs there is difference in loading time with/without delays. In example, there are situations when same loop handles iterations and finish in 5 seconds without updating GUI and 20 seconds with GUI update.

 

So in this case maybe it's better to show special screen that will notice user that «huge and long loading is in progress so be patient» and to do loading in 10 seconds instead of show him cool smooth progress bar in time of 2 minutes. 

 

You just need to understand that updating GUI will not do some difference in time if you only and just loading your resources, but it will if you do some very long expensive great countings of future effects or datas or something like that while loading main resources.

 

And even in this case you can separate loading operations to show cool smooth progress bar and counting operations while show only one notice splash in beginning and not interrupting your countings by updating your GUI.




[topic_controls]
Page 2 of 2 1 2
 
[/topic_controls]