Changeset 1101 for trunk/core/luascript.c
- Timestamp:
- 03/23/11 04:41:29 (2 years ago)
- Location:
- trunk
- Files:
-
- 2 edited
-
. (modified) (1 prop)
-
core/luascript.c (modified) (5 diffs)
Legend:
- Unmodified
- Added
- Removed
-
trunk
- Property svn:mergeinfo changed
/branches/reyalp-ptp (added) merged: 1083,1090,1095-1096,1100
- Property svn:mergeinfo changed
-
trunk/core/luascript.c
r1036 r1101 15 15 #include "action_stack.h" 16 16 #include "motion_detector.h" 17 #include "ptp.h" 17 18 18 19 #include "../lib/lua/lstate.h" // for L->nCcalls, baseCcalls … … 20 21 lua_State* L; 21 22 lua_State* Lt; 22 int lua_keep_result; 23 24 void *lua_consume_result() 25 { 26 lua_State* r = L; 23 24 static int lua_script_is_ptp; 25 26 static int yield_hook_enabled; 27 28 static void lua_script_disable_yield_hook(void) { 29 yield_hook_enabled = 0; 30 } 31 static void lua_script_enable_yield_hook(void) { 32 yield_hook_enabled = 1; 33 } 34 35 #ifdef CAM_CHDK_PTP 36 // create a ptp message from the given stack index 37 // incompatible types will return a TYPE_UNSUPPORTED message 38 static ptp_script_msg *lua_create_usb_msg( lua_State* L, int index, unsigned msgtype) { 39 // TODO maybe we should just pass the lua type constants 40 unsigned datatype, datasize = 4; 41 int ivalue = 0; 42 void *data = &ivalue; 43 int ltype = lua_type(L,index); 44 switch(ltype) { 45 case LUA_TNONE: 46 return NULL; // nothing on the stack, no message generated 47 break; 48 case LUA_TNIL: 49 datatype = PTP_CHDK_TYPE_NIL; 50 break; 51 case LUA_TBOOLEAN: 52 datatype = PTP_CHDK_TYPE_BOOLEAN; 53 ivalue = lua_toboolean(L,index); 54 break; 55 case LUA_TNUMBER: 56 datatype = PTP_CHDK_TYPE_INTEGER; 57 ivalue = lua_tonumber(L,index); 58 break; 59 case LUA_TSTRING: 60 datatype = PTP_CHDK_TYPE_STRING; 61 data = (char *)lua_tolstring(L,index,&datasize); 62 break; 63 // TODO this converts to a string and returns as STRING, format as described at 64 // http://chdk.setepontos.com/index.php?topic=4338.msg62606#msg62606 65 // for compatibility with current PTPCAM/PTPCAMGUI implementation 66 // later we should switch to a proper serialized table with it's own return type 67 case LUA_TTABLE: 68 lua_script_disable_yield_hook(); // don't want to yeild while converting 69 lua_getglobal(L, "usb_msg_table_to_string"); // push function 70 lua_pushvalue(L, index); // copy specified index to top of stack 71 lua_pcall(L,1,1,0); // this will leave an error message as a string on the stack if call fails 72 lua_script_enable_yield_hook(); 73 // an empty table will be returned as an empty string 74 // a non-string should never show up here 75 if ( !(lua_isstring(L,-1) /*&& ( lua_objlen(L,-1) > 0 )*/)) { 76 return NULL; 77 } 78 datatype = PTP_CHDK_TYPE_STRING; 79 data = (char *)lua_tolstring(L,-1,&datasize); 80 lua_pop(L,1); 81 break; 82 default: 83 datatype = PTP_CHDK_TYPE_UNSUPPORTED; 84 data = (char *)lua_typename(L,ltype); // return type name as message data 85 datasize = strlen(data); 86 } 87 return ptp_script_create_msg(msgtype,datatype,datasize,data); 88 } 89 90 void lua_script_error_ptp(int runtime, const char *err) { 91 if(runtime) { 92 ptp_script_write_error_msg(PTP_CHDK_S_ERRTYPE_RUN, err); 93 script_end(); 94 } else { 95 ptp_script_write_error_msg(PTP_CHDK_S_ERRTYPE_COMPILE, err); 96 lua_script_reset(); 97 } 98 } 99 #endif 100 101 void lua_script_reset() 102 { 103 lua_close( L ); 27 104 L = 0; 28 return r;29 }30 31 void lua_script_reset()32 {33 if ( !lua_keep_result )34 {35 lua_close( L );36 L = 0;37 }38 Lt = 0;39 105 } 40 106 41 107 static void lua_count_hook(lua_State *L, lua_Debug *ar) 42 108 { 43 if( L->nCcalls <= L->baseCcalls )109 if( L->nCcalls <= L->baseCcalls && yield_hook_enabled ) 44 110 lua_yield( L, 0 ); 45 111 } 46 112 47 int lua_script_start( char const* script ) 48 { 49 lua_keep_result = 0; 113 void lua_script_error(lua_State *Lt,int runtime) 114 { 115 const char *err = lua_tostring( Lt, -1 ); 116 script_console_add_line( err ); 117 if(lua_script_is_ptp) { 118 #ifdef CAM_CHDK_PTP 119 lua_script_error_ptp(runtime,err); 120 #endif 121 } else { 122 if(runtime) { 123 if(conf.debug_lua_restart_on_error) { 124 lua_script_reset(); 125 script_start_gui(0); 126 } else { 127 script_wait_and_end(); 128 } 129 } else { 130 script_print_screen_end(); 131 script_wait_and_end(); 132 } 133 } 134 } 135 136 137 // TODO more stuff from script.c should be moved here 138 void lua_script_finish(lua_State *L) 139 { 140 #ifdef CAM_CHDK_PTP 141 if(lua_script_is_ptp) { 142 // send all return values as RET messages 143 int i,end = lua_gettop(L); 144 for(i=1;i<=end; i++) { 145 // if the queue is full return values will be silently discarded 146 // incompatible types will be returned as TYPE_UNSUPPORTED to preserve expected number and order of return values 147 ptp_script_write_msg(lua_create_usb_msg(L,i,PTP_CHDK_S_MSGTYPE_RET)); 148 } 149 } 150 #endif 151 } 152 153 int lua_script_start( char const* script, int ptp ) 154 { 155 lua_script_is_ptp = ptp; 50 156 L = lua_open(); 51 157 luaL_openlibs( L ); … … 55 161 lua_setfield( L, LUA_REGISTRYINDEX, "Lt" ); 56 162 if( luaL_loadstring( Lt, script ) != 0 ) { 57 script_console_add_line( lua_tostring( Lt, -1 ) ); 58 lua_script_reset(); 163 lua_script_error(Lt,0); 59 164 return 0; 60 165 } 61 166 lua_sethook(Lt, lua_count_hook, LUA_MASKCOUNT, 1000 ); 167 lua_script_enable_yield_hook(); 62 168 return 1; 63 169 } … … 1387 1493 return 1; 1388 1494 } 1495 1496 #ifdef CAM_CHDK_PTP 1497 /* 1498 msg = read_usb_msg([timeout]) 1499 read a message from the CHDK ptp interface. 1500 Returns the next available message as a string, or nil if no messages are available 1501 If timeout is given and not zero, wait until a message is available or timeout expires 1502 */ 1503 static int luaCB_read_usb_msg( lua_State* L ) 1504 { 1505 int timeout = luaL_optnumber( L, 1, 0 ); 1506 if(timeout) { 1507 action_push(timeout); 1508 action_push(AS_SCRIPT_READ_USB_MSG); 1509 return lua_yield( L, 0 ); 1510 } 1511 ptp_script_msg *msg = ptp_script_read_msg(); 1512 if(msg) { 1513 lua_pushlstring(L,msg->data,msg->size); 1514 return 1; 1515 } 1516 lua_pushnil(L); 1517 return 1; 1518 } 1519 1520 /* 1521 status = write_usb_msg(msg,[timeout]) 1522 writes a message to the CHDK ptp interface 1523 msg may be nil, boolean, number, string or table (table has some restrictions, will be converted to string) 1524 returns true if the message was queued successfully, otherwise false 1525 if timeout is set and not zero, wait until message is written or timeout expires 1526 NOTE strings will not include a terminating NULL, must be handled by recipient 1527 */ 1528 static int luaCB_write_usb_msg( lua_State* L ) 1529 { 1530 ptp_script_msg *msg; 1531 int timeout = luaL_optnumber( L, 2, 0 ); 1532 // TODO would it be better to either ignore this or return nil ? 1533 // a write_usb_msg(function_which_returns_no_value()) is an error in this case 1534 // replacing with nil might be more luaish 1535 if(lua_gettop(L) < 1) { 1536 return luaL_error(L,"missing argument"); 1537 } 1538 msg=lua_create_usb_msg(L,1,PTP_CHDK_S_MSGTYPE_USER); 1539 // for user messages, trying to create a message from an incompatible type throws an error 1540 if(msg->subtype == PTP_CHDK_TYPE_UNSUPPORTED) { 1541 free(msg); 1542 return luaL_error(L,"unsupported type"); 1543 } 1544 if(!msg) { 1545 return luaL_error(L,"failed to create message"); 1546 } 1547 if(timeout) { 1548 action_push(timeout); 1549 action_push((int)msg); 1550 action_push(AS_SCRIPT_WRITE_USB_MSG); 1551 return lua_yield( L, 0 ); 1552 } 1553 lua_pushboolean(L,ptp_script_write_msg(msg)); 1554 return 1; 1555 } 1556 #endif 1389 1557 1390 1558 void register_lua_funcs( lua_State* L ) … … 1554 1722 #endif 1555 1723 FUNC(reboot); 1556 } 1724 #ifdef CAM_CHDK_PTP 1725 FUNC(read_usb_msg); 1726 FUNC(write_usb_msg); 1727 luaL_dostring(L,"function usb_msg_table_to_string(t)" 1728 " local v2s=function(v)" 1729 " local t=type(v)" 1730 " if t=='string' then return v end" 1731 " if t=='number' or t=='boolean' or t=='nil' then return tostring(v) end" 1732 " return '' end" 1733 " local r=''" 1734 " for k,v in pairs(t) do" 1735 " local s,vs=''" 1736 " if type(v)=='table' then" 1737 " for i=1,table.maxn(v) do" 1738 " s=s..'\\t'..v2s(v[i]) end" 1739 " else" 1740 " vs=v2s(v)" 1741 " if #vs then s=s..'\\t'..vs end" 1742 " end" 1743 " vs=v2s(k)" 1744 " if #vs>0 and #s>0 then r=r..vs..s..'\\n' end" 1745 " end" 1746 " return r" 1747 " end"); 1748 1749 #endif 1750 }
Note: See TracChangeset
for help on using the changeset viewer.