2

hscriptそのため、スクリプトに公開するすべての静的メソッドを含む「インターフェイス クラス」を作成しました。次のようになります。

package com.application.interfaces.Terrain;

import com.application.TerrainCore

class Terrain {

    private static var terrain:TerrainCore;

    public static function _init(inTerrain:TerrainCore):Void {
        terrain = inTerrain;
    }

    public static function test(s:Int):Void {
        terrain.test(s);
    }
}

問題は、terrain何らかの方法でオブジェクトを設定する必要があることですが、スクリプトに公開したくないということです。クラス全体を

var interp = new Interp();
var module = Type.resolveClass("com.application.interfaces.Terrain");
interp.variables.set("Terrain", module)

という名前のメソッドを実行しないようにメソッドcallをオーバーライドするというアイデアでしたが、その方法がわかりません。元の方法は次のようになります。hscript.Interp_initcall

function call( o : Dynamic, f : Dynamic, args : Array<Dynamic> ) : Dynamic {
    return Reflect.callMethod(o,f,args);
}
4

2 に答える 2

2

静的メンバーを使用する代わりに、Terrain のクラス インスタンスを使用できますか? 例えば:

interp.variables.set("Terrain", new Terrain(new TerrainCore()));

スクリプト ユーザーは、静的メソッドを使用しているかインスタンス メソッドを使用しているかを認識しません。

Terrain.test(123);

スクリプトで。

別のオプション (clemos に基づく) は、rtti を使用して (リストを維持する代わりに) 何が許可されているかを判断することです。たとえば、次のようになります。

Terrain._init(new TerrainCore());

_init は現在プライベート関数であるため@:allow、呼び出し元のクラス (以下を参照) から実行する必要があります。また、@:rtti実行時に関数に関する情報を取得できるように注釈を付ける必要があるため、Terrain は次のようになります。

@:rtti
class Terrain {

    private static var terrain:TerrainCore;

    @:allow(test.hscript.demo.Main)
    private static function _init(inTerrain:TerrainCore):Void {
        terrain = inTerrain;
    }

    public static function test(s:Int):Void {
        terrain.test(s);
    }
}

最後に、スクリプト interpfcallは、フィールドがパブリックかプライベートかを尊重するようになりました。つまり、次のようになります。

public override function fcall(o:Dynamic, f:String, args:Array<Dynamic>):Dynamic 
    var rtti = haxe.rtti.Rtti.getRtti(o);
    for (field in rtti.statics) {
        if (field.name == f && field.isPublic == false) {
            error(EInvalidAccess(f));
        }
    }
    return super.fcall(o, f, args);
}

明らかな理由staticsではなく、私が使用したことは注目に値します。fieldsまた、これがループと rtti でどのようなオーバーヘッドを引き起こすかはわかりません。

于 2015-10-25T10:33:33.593 に答える
2

トップレベルの呼び出しのみに使用されるためfcall、オーバーライドする必要があると思います:call

https://github.com/HaxeFoundation/hscript/blob/master/hscript/Interp.hx#L328-L331

f次のような引数を簡単にフィルタリングできるはずです。

if ( FORBIDDEN_FIELDS.indexOf( f ) > -1 ) throw EInvalidAccess( f );

また

if ( f.indexOf('_') == 0 ) throw EInvalidAccess( f );
于 2015-10-25T10:33:48.030 に答える