1

これは、Lua C API を使用して C++ で実行したいことです。

ユーザーデータを基本ユーザーデータオブジェクトから派生させる良い方法を見つけようとしています。

私はこれを行うことができるようにしたい:

local item = me:GetCurrentItem()
print(item:GetPos())

それ以外の:

local item = me:GetCurrentItem()
print(item:GetBaseObject():GetPos())

これらの例では、me:GetCurrentItem() はいくつかの関数でユーザーデータを返しますが、item:GetBaseObject() が返す基本関数がありません。

学習目的で Crysis Wars SDK に Lua をバインドしています。SDK は、構造体である基本エンティティへのインターフェイスを提供します。IItem 構造体 (me:GetCurrentItem()) は同​​じです。これらは構造体であるため、それらを基本構造体にキャストしたり、その基本関数を呼び出したりすることはできません。IEntity *GetEntity() 関数を使用する必要があります。

__index で自己ポインタを変更しようとしましたが、ローカル変数「item」が「entity」になるのは明らかですが、GetPos 関数を呼び出した後に元に戻したいのですが、これはどういうわけか非論理的です。

誰かがこの問題の良い解決策を持っていますか?

4

1 に答える 1

2

明らかな解決策は、リダイレクトを行う item:GetPos() 関数を定義することです。

function Item:GetPos()
  return self:GetBaseObject():GetPos()
end

Item はアイテムのメタテーブルです。

これは、メタテーブルに変更を加えるのと同じくらい効率的であり、問​​題も少なくなります。

編集:反復性についても少しお手伝いできます。

次の 2 つの関数を実装できます。

function delegate(klass, methodName, memberName)
  klass[methodName] = function(self, ...)
    local member = self[memberName]
    if type(member) == 'function' then member = self[memberName](self) end
    return member[methodName](member, ...)
  end
end

そして、次のように使用します。

delegate(Item, 'GetPos', 'GetBaseObject')

Item:GetPosその 1 行は、上記の 3 行の定義と同じことを行う必要があります。

これを何度も繰り返す必要がある場合は、次の別の関数を使用してさらに最適化できます。

function delegateMany(klass, methodNames, memberName)
  for _,methodName in ipairs(methodNames) do
    delegateMethod(klass, methodName, memberName)
  end
end

これにより、次のことが可能になります。

deletageMany(Item, {'GetPost', 'SetPos', 'GetColor', 'SetColor'}, 'GetBaseObject')

私はこれらの機能をテストしていないので、バグに気をつけてください。それらは「取得したプロパティ」(self:GetSomething()および単純なアクセスself.something)の両方で機能する必要があります。このコードは、委任されたメソッドを呼び出すために常に「:」を使用することを想定しているためself、必要に応じて追加されます。

于 2011-07-07T07:39:29.350 に答える