Lua Error handling in stop and wait routine calls

瀏覽次數:47 次
跳到第一則未讀訊息

sillybear

未讀,
2012年7月29日 上午10:21:522012/7/29
收件者:lua-alc...@googlegroups.com
Hi All,

In the normal doString, the lua Alchemy will return an array with error information back to Actionscript if script execution failed.

However, we have a situation that we use stop and wait concept, two issues encountered. The attached code is the wrapper.lua library code we are using in stop-wait situation. 

Two issues:

(1) error code is always returning 0, no matter whether --%%LUA-SCRIPT%%-- block execution failed or succeed, Is there a way to set errorCode properly?
(2) How can we capture the error messages when --%%LUA-SCRIPT%%-- block execution failed like in doString call? Is there some return results of --%%LUA-SCRIPT%%-- block execution? can we assign them to an array like we do in doString call?

Thanks in advance for any help. 

===========================================================================
-- Begin lua core coroutine wrapper
local run = coroutine.create( function( )
-- The threadTaskID is assigned from the global taskID identifier because THIS coroutine will notify
-- the containing component with its assigned ID that this task was resumed and ended successfully in the case of a
-- coroutine.yield() call.
local threadTaskID = as3.tolua(taskID)

-- This is the errorCode that will be processed after the script block is run.
local errorCode = 0

-- Add this coroutine to this lua engine's environment using threadTaskID 
waiting_threads[ threadTaskID ] = coroutine.running()

-- Set the running_thread variable so functions calls that communicate with the application core
-- can provide it as a reference
running_thread = threadTaskID
-- LUA script block follows
--%%LUA-SCRIPT%%--
    
-- LUA script block precedes
-- Remove this task from the list of threads, because it's now complete
-- We use threadTaskID here since the global value taskID will be different if a coroutine
-- yielded control (e.g. a script called waitForResponse )
waiting_threads[ threadTaskID ] = nil
-- Clear the target var. The script will be able to access it via targets[ threadTaskID ]
target = nil
if (errorCode == 0) then
modelCore.taskComplete( threadTaskID ) -- Notify the As3 component containing the lua engine that this script is complete
else
modelCore.taskFailed( threadTaskID ) --- Notify the As3 component containing the lua engine that this script failed.
end
-- return threadTaskID
end)

assert(coroutine.resume( run ))

====================================================================================================

Alexander Gladysh

未讀,
2012年7月30日 凌晨1:28:492012/7/30
收件者:lua-alc...@googlegroups.com
Hi,

On Sun, Jul 29, 2012 at 6:21 PM, sillybear <jxy...@yahoo.ca> wrote:
> Two issues:
>
> (1) error code is always returning 0, no matter whether --%%LUA-SCRIPT%%--
> block execution failed or succeed, Is there a way to set errorCode properly?

This errorCode convention is not part of neither Lua nor LuaAlchemy
and I did not find any code that changes it in the code you posted, so
I can't help you here.

> (2) How can we capture the error messages when --%%LUA-SCRIPT%%-- block
> execution failed like in doString call? Is there some return results of
> --%%LUA-SCRIPT%%-- block execution? can we assign them to an array like we
> do in doString call?

As I already suggested several times, please use pcall or xpcall:
www.lua.org/manual/5.1/manual.html#pcall

Here is an example that captures results (this assumes that
%%LUA-SCRIPT%% have return statement at the end — otherwise nil would
be always returned implicitly). (Note that I did not run this example,
it may contain minor mistakes.)

-- This is needed since called function may return nils in the middle
local pack = function(...)
return { n = select("#", ...), ... }
end

local results = pack(xpcall(
function()
%%LUA-SCRIPT%%
end,
function(msg)
return debug.traceback(msg)
end
))

if not results[1] then -- execution failed
local error_message = results[2]
-- do something with that
else
-- results[1]..results[results.n] contain whatever %%LUA-SCRIPT%%
returned if any.
end

Please tell me if I may help you further.

HTH,
Alexander.

P.S. Note that pasting %%LUA-SCRIPT%% directly in code is usually not
a good idea and is a bad programming style. Use loadstring() instead.

sillybear

未讀,
2012年8月3日 上午11:58:322012/8/3
收件者:lua-alc...@googlegroups.com
Thanks Alexander for your reply.

However, I do not think pcall will work in my case. my  --%%LUA-SCRIPT%%--  block might contain coroutine.yield() function call. I do not know whether this behaviors will be supported in lua alchemy or not as if calling yield function from a script executed from pcall will not be supported in standard Lua which will throw an exceptions out in turn.

Kind Regards,

Bobby Parker

未讀,
2012年8月3日 下午1:15:372012/8/3
收件者:lua-alc...@googlegroups.com
This looks like the code from the "Lua-Alchemy Port" project that I posted to the list a few months ago.

The idea behind the --%%LUA-SCRIPT%%-- pattern was to have something to replace it with like so


var scriptPattern:RegExp = /--%%LUA-SCRIPT%%--/;

var stack:Array = lua.doString( scriptWrapper.replace( scriptPattern, script ));

Where the scriptWrapper is the wrapper.lua file, and script is the string that's being INSERTED into the wrapper script.


About the errorCode variable:

The errorCode will ALWAYS return zero UNLESS YOUR SCRIPT SETS IT TO ONE. The errorCode variable is the mechanism by which you, the script author, inform the modelCore that the outcome of your script was either successful, or failed. The errorCode variable DOES NOT mean that the script itself failed to parse, or encountered a nil where a variable was needed or whatever. In other words, the errorCode variable is not magic, and it's there for you to use as you see fit within your code. It has nothing to do with the lua engine whatsoever

Hope this helps.


Bobby

Alexander Gladysh

未讀,
2012年8月3日 下午1:19:492012/8/3
收件者:lua-alc...@googlegroups.com
On Fri, Aug 3, 2012 at 7:58 PM, sillybear <jxy...@yahoo.ca> wrote:
> Thanks Alexander for your reply.
>
> However, I do not think pcall will work in my case. my --%%LUA-SCRIPT%%--
> block might contain coroutine.yield() function call. I do not know whether
> this behaviors will be supported in lua alchemy or not as if calling yield
> function from a script executed from pcall will not be supported in standard
> Lua which will throw an exceptions out in turn.

Have you tried https://github.com/keplerproject/coxpcall/blob/master/src/coxpcall.lua
?

Alexander.

sillybear

未讀,
2012年8月3日 下午1:38:132012/8/3
收件者:lua-alc...@googlegroups.com
Hi Bobby,

Thank you for your reply. You are absolutely right regarding the errorCode stuff. The example code I post here is exactly copied and pasted from your project.

The question I want to ask here is: how can I achieve error handling with your code. 

with your example code, I can achieve stop and wait through coroutine.create, yield and resume. However, I can not get error msg back like normal dostring call.

Alexander posted a solution by using pcall or xpcall. It works perfect in the normal case without coroutine.yield call in pcall function. However, it wont work if pcall function contains yield call as it is not supported.

Any suggestions how I can get error message back in this case?

Kind Regards,

sillybear

未讀,
2012年8月3日 下午1:43:562012/8/3
收件者:lua-alc...@googlegroups.com
Nope, I will give it a try.Thanks for the help. 

sillybear

未讀,
2012年8月3日 下午3:47:522012/8/3
收件者:lua-alc...@googlegroups.com
Hi Alexander,

I tested with coxpcall.lua. It fixed the yield inside the pcall exception issue. The error messages are captured properly in both main script and child script (lua reenter case). Excellent.

However, the "stop and wait" feature stop working.

We have script like following in --%%LUA-SCRIPT%%-- block

luaclient.alert("testing") 
coroutine.yield()
== remaining script here == 
local a = 3
.....

the alert function is implemented in AS3 as following. It mainly dispatch an event when user click button on screen to tell lua to resume execution:
var arguments:Array = new Array();
   var func:Function = function(items:Array):void{
alert(msg, 
function(ret:int):void{
      dispatch script resume event;
        });}

And resume event function is implemented in lua library to resume the remaining script.  
resume = as3.toas3(function (event) coroutine.resume( thread, event.eventData, err ) end)

However, after using coxpcall.lua, the coroutine.resume(co, ...) call in performResume in coxpcall.lua did not hold execution to wait this process to be finished to continue the remaining script like before. which end up with my remaining script never get executed.

Any idea of how I can work around this?

Thanks again for all helps.


On Friday, August 3, 2012 1:19:49 PM UTC-4, Alexander Gladysh wrote:

Alexander Gladysh

未讀,
2012年8月6日 凌晨4:37:362012/8/6
收件者:lua-alc...@googlegroups.com

sillybear

未讀,
2012年8月7日 上午11:06:152012/8/7
收件者:lua-alc...@googlegroups.com
Hi Alexander,

Yield_Outer is just what I want. How can I combine lua-nucleo's pcall with coxpcall as function can contain native lua coroutine.yield().

Thanks for all your help.

Kind Regards,

Alexander Gladysh

未讀,
2012年8月17日 下午1:29:512012/8/17
收件者:lua-alc...@googlegroups.com
Hi,

Apologies for a very late reply.

If you use yield_outer, you do not need coxpcall (but I may be wrong —
I'm somewhat rusty on the details).

The idea is this:

1) Replace Lua pcall with lua-nucleo's version.
2) Replace all yields that should go to AS3 with yield_outer.
3) Replace all AS3-level resumes with resume_inner.

I think this should work. If it does not, tell me, I'll look deeper
into the issue.

HTH,
Alexander.
回覆所有人
回覆作者
轉寄
0 則新訊息