Hatena::ブログ(Diary)

C++でゲームプログラミング

2009-09-10

[][][]sq_push 関数オーバーロード

スクリプト関数引数を渡すときは、下のような感じに値をpushしていく。

sq_pushinteger(v, 10);                        // in t型
sq_pushfloat  (v, 0.45f);                     // float 型

std::string    str("Squireel");
sq_pushstring(v, "Squireel", str.size());    // 文字列

ただ、これだと渡す型用の関数を逐一選んで呼ばないとだめなので以下のように関数でラッピング。

namesapce squirrel{

    void
    push(HSQUIRRELVM v, int rhs){
        ::sq_pushinteger(v, rhs);
    }

    void
    push(HSQUIRRELVM v, float rhs){
        ::sq_pushfloat(v, rhs);
    }

    void
    push(HSQUIRRELVM v, const char* rhs){
        ::sq_pushstring(v, rhs, strlen(rhs) );
    }

};            // namesapce squirrel{

squirrel::push(v, 10);                // int 型が push される
squirrel::push(v, "Squirrel");        // 文字列も問題なく呼ばれる

引数の型のオーバーロードで解決。

これですっきり。

2009-09-09

[][]スクリプト側の関数の呼び出し方

function main(){
    print("Hello Squrrel World\n");
}

上ののようなスクリプトが定義されていた場合に、

script"main"();

こんな感じでC++側からスクリプト側の関数の呼び出しを行いたい。


で、実装するとこんな感じ?


// 関数戻り値の型を定義
template< typename T >
struct type2type{
	typedef T type;
};
type2type<void>	void_;
type2type<int>	int_;
type2type<char>	char_;

struct script{
    
    template< typename result >
    result operator ()(type2type<result>){
        // 関数の呼び出しの実装
    }
    
    // 関数名を設定
    void set(const char* rhs){
        mFuncName = rhs;
    }
    
    // 演算子[]を使用して関数名を設定
    script& operator [](const char* name){
        set(name);
        return *this;
    }
    
private:
    std::string    mFuncName;
};

script    s;
s["main"](void_);

最初は、operator|()で呼び出しを行っていたんだけど、()演算子の方が優先順位が高く、

(script|"main")(void_)

の様にしてやらないとダメなので[]演算子で対応。

確かに、[]の方がわかりやすいかな?


関数戻り値の型は関数オブジェクトの第一引数に渡してやってます。

他によさげな実装方法が思い浮かびませんでした…。

んーもうちょっと改良の余地があるかな?

次は複数の引数に対応予定

2009-09-06

[][]スクリプト言語

会社で社内スクリプトを触る機会があって、思いのほか興味がわいた。

とりあえず、家でluaでもいじってみようかと思い、

環境構築を終えて、サンプルをちくちく作っていたら

友人から「Squirrel」なるものを教えてもらう ←いまここ。


んーちょっと調べてみたところ、元々ゲームプログラムluaを使っていた人が、

luaを強化した感じのスクリプトらしい。

せっかくなので、こっちをやってみようかなー。

資料はかなり少なそうだけども…。


ちなみにライセンス形態はどうなってるんだろうか?