2010-05-25 17 views
8

कहा जाता है जाओ मैं सी में एक ही कार्य करने के लिए लुआ में कई अलग अलग समारोह नाम रजिस्टर अब, हर मेरी सी समारोह कहा जाता है, यह तय करने के जो कार्य करते हैं नाम लागू किया गया था एक तरीका है?माना lua आदेश जब एक सी समारोह

उदाहरण के लिए

:

int runCommand(lua_State *lua) 
{ 
    const char *name = // getFunctionName(lua) ? how would I do this part 
    for(int i = 0; i < functions.size; i++) 
    if(functions[i].name == name) 
     functions[i].Call() 
} 

int main() 
{ 
    ... 

    lua_register(lua, "delay", runCommand); 
    lua_register(lua, "execute", runCommand); 
    lua_register(lua, "loadPlugin", runCommand); 
    lua_register(lua, "loadModule", runCommand); 
    lua_register(lua, "delay", runCommand); 
} 

तो, मैं क्या कभी समारोह में यह कहा जाता है के नाम पर मिलता है? अन्य बातों के अलावा, क्योंकि लुआ में कार्य वास्तव में सब पर एक नाम है की जरूरत नहीं है -

+0

क्यों आप सभी कार्यों में एक ही दिनचर्या को मैप करना चाहते हैं? –

+0

मैं एक समारोह भी एक इस सूचक है कि कॉल करने के लिए सक्षम होने के लिए चाहते हैं, लेकिन मौजूदा व्यवस्था को देखते हुए, मैं केवल स्थिर/वैश्विक कार्यों कॉल कर सकते हैं। –

उत्तर

11

एक और तरीका है अपने प्रश्न पर हमला करने के upvalues उपयोग करना है। मूल रूप से, आप नीचे दिए गए बजाय समारोह के साथ सी कार्यों रजिस्टर lua_register:

void my_lua_register(lua_State *L, const char *name, lua_CFunction f) 
{ 
     lua_pushstring(L, name); 
     lua_pushcclosure(L, f, 1); 
     lua_setglobal(L, name); 
} 

फिर, getFunctionName सीधे आगे है

const char* getFunctionName(lua_State* L) 
{ 
    return lua_tostring(L, lua_upvalueindex(1)); 
} 

जिसके अनुसार, तुम क्या करने की कोशिश कर गड़बड़ लगता है - आप क्या प्रयास कर रहे हैं प्राप्त करने के लिए? runCommand समारोह सवाल में तैनात कुछ है कि लुआ वैसे भी आप के लिए करता है करने के लिए एक बुरी अक्षम रास्ता तरह दिखता है।

+0

आप एक 'यह' पॉइंटर को एक अपग्रेड/क्लोजर में भी डाल सकते हैं। –

+0

अपग्रेड का उपयोग करते समय अन्य पैरामीटर और उनमें से अलग संख्या का उपयोग करने के बारे में क्या? –

+0

@ मारियसके: मुझे यकीन नहीं है कि आपका क्या मतलब है, क्या आप विस्तारित कर सकते हैं? – sbk

0

दुर्भाग्य से, कि संभव नहीं है। (पर विचार करें: (loadstring("a=1"))() एक अनाम समारोह loadstring से लौटे क्रियान्वित किया जाता है।)

2

आप lua_getinfo उपयोग कर सकते हैं: http://pgl.yoyo.org/luai/i/lua_getinfo

यह काम हो सकता है:

:

const char* lua_getcurrentfunction(lua_State* L) { 
    lua_Debug ar; 
    lua_getstack(L, 1, &ar); 
    lua_getinfo(L, "f", &ar); 
    return ar.name; 
} 

एक चेतावनी है नाम: दिए गए फ़ंक्शन के लिए उचित नाम। चूंकि लुआ में कार्य प्रथम श्रेणी के मान हैं, उनके पास निश्चित नाम नहीं है: कुछ फ़ंक्शन एकाधिक वैश्विक चर का मान हो सकते हैं, जबकि अन्य केवल तालिका फ़ील्ड में संग्रहीत किए जा सकते हैं। Lua_getinfo फ़ंक्शन जांचता है कि उपयुक्त नाम खोजने के लिए फ़ंक्शन को कैसे बुलाया गया था। अगर इसे कोई नाम नहीं मिल रहा है, तो नाम न्यूल पर सेट है।

2

एक वैकल्पिक समाधान लुआ पर्यावरण तालिका कि इन कार्यों कॉल भेजने के लिए __index metamethod लागू करता है के लिए एक metatable रजिस्टर करने के लिए किया जाएगा।

0

आप सभी अज्ञात समारोह फांसी ऊपर slurp करने को तैयार हैं, तो आप setmetatable और currying के साथ खेल खेलने के लिए सक्षम हो सकता है:

 
    -- This function would not be in lua in your example, 
    -- you'd be doing lua_register(lua, "runCommandNamed", runCommandNamed) 
    -- and writing a runCommandNamed in C. 
    function runCommandNamed(cmd, ...) 
     print("running command", cmd, "with arguments", ...) 
    end 

    -- The rest would be somewhere in lua-land: 
    local utilMetaTable = { 
     __index = function (t, key) 
      return function(...) -- mmm, curry 
       runCommandNamed(key, ...) 
      end 
     end 
    } 

    _util = {} 
    setmetatable(_util, utilMetaTable) 

    -- prints "running command CommandOne  with arguments arg1 arg2 arg3" 
    _util.CommandOne("arg1", "arg2", "arg3") 

    -- prints "running command CommandTwo  with arguments argA argB" 
    _util.CommandTwo("argA", "argB") 

इस उदाहरण में, मैं केवल अज्ञात फांसी अप slurped गए वैश्विक तालिका के बजाय _util के तहत।

+0

(लुआ गुरु: कृपया बेहतर वाक्यविन्यास या स्टाइल परिवर्तनों का सुझाव देने के लिए स्वतंत्र महसूस करें, मुझे उन्हें शामिल करने में खुशी होगी। दुर्भाग्यवश, मैं काम पर हमारे इंजन में एकीकृत होने के बावजूद, लुआ का उपयोग नहीं करता हूं।) – leander

संबंधित मुद्दे