1

FarseerPhysics を MonoTouch でコンパイルできるように取り組んでいます。System.Collections.Generic で HashSet を使用すると問題なく動作しますが、Farseer には Xbox 360 と Windows Phone で使用する独自の Hashset クラスがあるため、IPHONE にもそのハッシュセットを含めるのが理にかなっていると思いました。

これは Farseer ハッシュセット コードです。

#if WINDOWS_PHONE || XBOX || IPHONE

//TODO: FIX

using System;
using System.Collections;
using System.Collections.Generic;

namespace FarseerPhysics.Common
{

    public class HashSet<T> : ICollection<T>
    {
        private Dictionary<T, short> _dict;

        public HashSet(int capacity)
        {
            _dict = new Dictionary<T, short>(capacity);
        }

        public HashSet()
        {
            _dict = new Dictionary<T, short>();
        }

        // Methods

#region ICollection<T> Members

        public void Add(T item)
        {
            // We don't care for the value in dictionary, Keys matter.
            _dict.Add(item, 0);
        }

        public void Clear()
        {
            _dict.Clear();
        }

        public bool Contains(T item)
        {
            return _dict.ContainsKey(item);
        }

        public void CopyTo(T[] array, int arrayIndex)
        {
            throw new NotImplementedException();
        }

        public bool Remove(T item)
        {
            return _dict.Remove(item);
        }

        public IEnumerator<T> GetEnumerator()
        {
            return _dict.Keys.GetEnumerator();
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return _dict.Keys.GetEnumerator();
        }

        // Properties
        public int Count
        {
            get { return _dict.Keys.Count; }
        }

        public bool IsReadOnly
        {
            get { return false; }
        }

        #endregion
    }
}
#endif

それらは次のように使用されます:

using System;
using System.Collections.Generic;
using System.Diagnostics;
using FarseerPhysics.Collision;
using FarseerPhysics.Common;
using FarseerPhysics.Controllers;
using FarseerPhysics.Dynamics.Contacts;
using FarseerPhysics.Dynamics.Joints;
using Microsoft.Xna.Framework;

class World
{
(...)
        private HashSet<Body> _bodyAddList = new HashSet<Body>();
        private HashSet<Body> _bodyRemoveList = new HashSet<Body>();
        private HashSet<Joint> _jointAddList = new HashSet<Joint>();
        private HashSet<Joint> _jointRemoveList = new HashSet<Joint>();
}

Farseer ハッシュセット クラス ファイルの #if に IPHONE を追加すると、2 つの問題が発生します。

1 つ目は、HashSet が System.Collections.Generic.HashSet と FarseerPhysics.Common.HashSet の間のあいまいな参照であるとコンパイラが言う宣言でエラーが発生することです。このエラーは、Visual Studios コンパイラでは発生しません。これは、Xbox 360 と Windows Phone .Net API にはない Hashset を MonoTouch が実装しているためだと思われます。どちらにもハッシュセットがない理由はよくわかりませんが、ハッシュセットの Farseers バージョンを使用するのが最善だと思います。

もう 1 つの問題は、iPhone デバイスでアプリを実行する際に FarseerPhysics.Common.Hashset (つまり、新しい FarseerPhysics.Common.HashSet();) を使用する宣言を明示的に設定すると、エラーが発生することです。

「--aot-only で実行中にメソッド 'System.Collections.Generic.Dictionary'2:.ctor()' を JIT コンパイルしようとしています。\n'

また、このエラーはシミュレーターでは発生せず、実際のデバイスでのみ発生することも指摘しておく必要があります。

4

1 に答える 1

2

あいまいな参照に関する最初の問題は、クラスで使用されている HashSet と呼ばれる 2 つのクラスがあり、どちらが必要かを指定していないためです。この行を削除するか、ファイルの先頭にステートメントをusing System.Collections.Generic;追加できます。using HashSet = FarseerPhysics.Common.HashSet;これにより、コンパイラは具体的にどれを使用するかを知ることができます。

あなたが得ている JIT コンパイル エラーは、monotouch のいくつかの制限の 1 つです。mono コンパイラが比較オブジェクトをインスタンス化しようとする方法のため、辞書キーで値型を実際に使用することはできません。詳細については、http: //monotouch.net/Documentation/Limitations (「辞書キーとしての値の型」を検索) を参照してください。

この問題を回避するには、IEqualityComparer インターフェイスを新しい型で実装し、その型のインスタンスを Dictionary(IEqualityComparer) コンストラクターに提供する必要があります。

于 2011-05-26T13:37:44.863 に答える