This code outputs the txt file in a url.
local loader = UrlLoader.new("<a href="http://www.catonmat.net/download/awk.cheat.sheet.txt"" rel="nofollow">http://www.catonmat.net/download/awk.cheat.sheet.txt"</a><img class="emoji" src="http://forum.gideros.rocks/resources/emoji/wink.png" title=";)" alt=";)" height="20" />
local function onComplete(event)
local myString=event.data -- We got the string here.
--local timer = Timer.new(1000, 8)
--timer:addEventListener(Event.TIMER, onComplete)---
local length = string.len(myString)
local i = 1
local echoString = ""
while (i < length+1) do
echoString = echoString .. string.sub(myString,i,i)
i = i+1;
end
print (echoString)
--timer:start()
end
local function onError()
print("error")
end
local function onProgress(event)
print("progress: " .. event.bytesLoaded .. " of " .. event.bytesTotal)
end
loader:addEventListener(Event.COMPLETE, onComplete)
loader:addEventListener(Event.ERROR, onError)
loader:addEventListener(Event.PROGRESS, onProgress) |
I want to add a timer to the code and it is the code with timer.
local loader = UrlLoader.new("<a href="http://www.catonmat.net/download/awk.cheat.sheet.txt"" rel="nofollow">http://www.catonmat.net/download/awk.cheat.sheet.txt"</a><img class="emoji" src="http://forum.gideros.rocks/resources/emoji/wink.png" title=";)" alt=";)" height="20" />
local function onComplete(event)
local myString=event.data -- We got the string here.
local timer = Timer.new(1000, 8)
timer:addEventListener(Event.TIMER, onComplete)---
local length = string.len(myString)
local i = 1
local echoString = ""
while (i < length) do
echoString = echoString .. string.sub(myString,i,i)
i = i+1;
end
print (echoString)
timer:start()
end
local function onError()
print("error")
end
local function onProgress(event)
print("progress: " .. event.bytesLoaded .. " of " .. event.bytesTotal)
end
loader:addEventListener(Event.COMPLETE, onComplete)
loader:addEventListener(Event.ERROR, onError)
loader:addEventListener(Event.PROGRESS, onProgress) |
It outputs the results correctly and then suddenly gave the error :
main.lua:9: bad argument #1 to 'len' (string expected, got nil)
stack traceback:
Why i'm taking this error? How could i fix it?
Thanks in advance
Comments
timer:addEventListener(Event.TIMER, onComplete)
and
loader:addEventListener(Event.COMPLETE, onComplete)
?
When i did
--timer:addEventListener(Event.TIMER, onComplete)
and
loader:addEventListener(Event.COMPLETE, onComplete)
It gives the output correctly but doesn't update.
When i did
timer:addEventListener(Event.TIMER, onComplete)
and
--loader:addEventListener(Event.COMPLETE, onComplete)
There is no error but there is no output ,either.
#MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
I'M outputting the myString , and you are right @MikeHart . myString gives the output correctly at first trying but then it only outputs nil .Namely:
(Correct Output)
nil
nil
nil
nil
nil
nil
nil
.
.
.
So interesting.. Why can't it get the txt file from the url after first trying? I would expect that it outputs the text again and again.
Thanks in advance
#MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
I'm also having problems with the UrlLoader class - making multiple calls seems to really mess things up for me.
Am I right in thinking you want to periodically download the file and dump it's contents. it's something similar to what I'm currently trying (and failing) to do
#MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
When onComplete is called the complete downloaded file should be in event.data. If this is the only file to download then the loader:eventListeners should be removed.
I think that once a file is finished loading, it is sent to the Event.COMPLETE listener and then the string is cleared. If the listener is called again then this nil string is what will be sent. I may have this wrong but it makes sense in my head
Website: http://www.castlegateinteractive.com
https://play.google.com/store/apps/developer?id=Castlegate+Interactive
What I would say is use a different function for the Timer on complete event as opposed to the download on complete event (also makes the code easier to read).
I'm also struggling with multiple downloads using a single connection (which is basically what your doing). If I get any more info I'll post some more.
I was hoping @Atilim (or @Gorkem ) might jump in with the single bit of info I need to make it all work flawlessly but I guess they're a bit busy at the moment.
#MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
When i remove the line :
loader:addEventListener(Event.COMPLETE, onComplete)
It never give correct output , give all nil .
unless i remove , it gives at least one Correct output if we don't mind rest of it is all nil
Something weird is going on here - I've been at this all day - making multiple calls to the same UrlLoader instance doesn't appear to work, after the second call to :load() is made, none of the event listeners seem to get called - can anyone else confirm this?
#MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
To download a single file you must create an instance of a UrlLoader and assign the appropriate event handlers to it.
Once the download is complete you are free to work with the data - BUT you can't reuse the connection (ie make a subsequent :load() call), other than removing the event handlers you also CAN'T do anything with the instance of the connection (ie the original return value from UrlLoader:new()) - you certainly can't create a NEW connection and assign it to the variable (don't ask me why!) otherwise the any attempt to download will just cause it to crash.
The way I got round the problem was to have a table of UrlLoader instances and create one per file.
Initially the table was empty - and I used a onEnterFrame listener to watch the state of a flag that was set each time a download completed and was then used to trigger the next load from the onEnterFrame listener.
Once all the files had been downloaded I then set a different flag which caused the onEnterFrame listener to pickup the fact that all the files had been downloaded and then nil out all the references to the UrlLoader instances before continuing.
I'm not sure if this the best method to use but until I get official word from those "in the know" it'll do.
I'll cross post this in the thread I started in case anyone else is struggling with this...
#MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
if it is, then have two functions,
1. To download the file from the internet
2. A timer that will keep calling this function every XX period.
You will have to also keep in mind to start the timer only when the download is complete, so XX after the file download is completed. That way you will not have an overlap.
Hope that helps, BTW, Basket Weaving is quite an impressive task
Author of Learn Lua for iOS Game Development from Apress ( http://www.apress.com/9781430246626 )
Cool Vizify Profile at https://www.vizify.com/oz-apps
@techdojo , you make me thought that it is impossible to do it :S
@OZApps ,you understand right. Moreover, I almost tried everywhere.I put the timer everywhere but didn't work . When i change the place of timer , the order of correct output change but it gives still only one correct output and rest all nil.For instance:
(correct output)
nil
nil
nil
.
.
.
or
nil
nil
(correct output)
nil
nil
.
.
.
or etc.
You've already done the bit with the download - separate out the timer stuff and try and keep each section of your code as separate as possible, write a function that just get's called on a timer and do a print so that you know it's working ok, then look at calling your download function from within that timer callback. Just remember to create a NEW UrlLoader instance each time you want to download and DON'T try and schedule anything to do with the current UrlLoader instance from within the download complete callback.
#MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
Yes you're right. Second call to load doesn't seem to work. It's a bug. The workaround is creating a new UrlLoader for each load:
#MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
@atilim , it worked correctly , but it cause a new problem when It gives output on Simulator.
When it is updated with a new one , old and new textfields are seen . I should delete old one in every cycle . For this reason , where should i put " stage:removeChild(text) " I can't already put it in onComplete function .Also, I tried outside but it gives errors
#MakeABetterGame! "Never give up, Never NEVER give up!" - Winston Churchill
Website: http://www.castlegateinteractive.com
https://play.google.com/store/apps/developer?id=Castlegate+Interactive
main.lua:10: bad argument #1 to 'contains' (Sprite expected, got nil)
stack traceback:
When i define a new function and call it from somewhere, it gives the similar error:
Here is the code
main.lua:20: bad argument #1 to 'removeChild' (Sprite expected, got nil)
stack traceback:
--- I hate nil ---
--- Maybe my brain dream it as if it was python :S ---
but you try to remove text2:
stage:removeChild(text2)
Although you defined only variable text1
So text2 is nil