2016-03-23 10 views
1

私はSeleneを使用して、Luaからアクセス可能なC++クラスと関数をラップしています。LuaでアクセスできるようにSeleneで列挙をラップします

:私は1

最初の試みをLuaの中に「Motion.DOWN」のようなものを言うし、得ることができるように

enum class Motion { 
    UP = 0, 
    DOWN = 1, 
    REPEAT = 2, 
}; 

私はLuaの状態の内部でこれをラップしたい:私は、単純な列挙型クラスを持っています

void register(sel::State &L) { 
    L["Motion"].SetClass<Motion>(); 
} 

コンパイラはクラスではないと不平を言っています。

... 
/source/desktop/../external/Selene/include/selene/Class.h:41:10: 
    error: creating pointer to member of non-class type 'Motion' 
void _register_member(lua_State *state, 
... 

第二の試み:

void register(sel::State &L) { 
    L["Motion"] = Motion; 
} 

これは、有効なC++はない "と期待して一次式" に関するエラーを取得するには、コンパイルされません。 &Motionを使用しようとすると同じエラーが発生します。

これを行う方法はありますか?好ましくは、すべての列挙定数を再度リストアップすることに関与しないもの。

答えて

0

これはセレンでは不可能です。

私が採用した解決策は、ラベルと値を追跡するために内部的にマップを使用するクラスDynEnumを定義することです。

/** 
* Simple class for enum values 
*/ 
class DynEnum { 
    public: 
    DynEnum(std::map<std::string, int> tbl) : tbl(tbl) {} 

    int of(std::string tag) { 
     if (tbl.count(tag) > 0) { 
      return tbl[tag]; 
     } 
     throw std::runtime_error("Enum tag not found"); 
    } 

    std::string lookup(int v) { 
     for (auto &p : tbl) { 
      if (p.second == v) { 
       return p.first; 
      } 
     } 
     throw std::runtime_error("Enum value not found"); 
    } 

    private: 
    std::map<std::string, int> tbl; 
}; 

次に、このようなオブジェクトインスタンス化:

DynEnum Motion({ 
    {"UP", 0}, 
    {"DOWN", 1}, 
    {"REPEAT", 2}, 
}); 

を次にセレーネを使用してバインド:

L["Motion"].SetObj(Motion, 
    "of", &DynEnum::of, 
    "lookup", &DynEnum::lookup); 

この方法では、パフォーマンス上のオーバーヘッドを持っていますが、私のアプリケーションでは、それは大したことではありません。また、デバッグに役立つLuaの数値から文字列への変換を可能にするという利点もあります。