Exemplo n.º 1
0
        private static void DoInit()
        {
            DoValidateTypes();

            List <ClassEntry> exports = new List <ClassEntry>();

            foreach (Assembly assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                foreach (Type type in assembly.GetTypes())
                {
                    ExportClassAttribute attr = Attribute.GetCustomAttribute(type, typeof(ExportClassAttribute), false) as ExportClassAttribute;
                    if (attr != null)
                    {
                        exports.Add(new ClassEntry(type, attr));
                    }

                    RegisterAttribute attr2 = Attribute.GetCustomAttribute(type, typeof(RegisterAttribute), false) as RegisterAttribute;
                    if (attr2 != null)
                    {
                        string name = attr2.Name ?? type.Name;

                        if (type.IsValueType)
                        {
                            TypeEncoder.Register(type, name);
                        }
                        else
                        {
                            NSObject.Register(type, name);
                        }
                    }
                }
            }

            for (int i = 0; i < exports.Count; ++i)                                     // must process base types before derived types
            {
                for (int j = i + 1; j < exports.Count; ++j)                             // crappy O(N^2) sort, but it's difficult to use a more efficient sort because we cannot meaningfully compare two elements in isolation
                {                                                                       // should be OK though, because this is only for exported types, not registered types
                    if (ClassEntry.LeftDerivesFromRight(exports[i], exports[j]))
                    {
                        ClassEntry temp = exports[i];
                        exports[i] = exports[j];
                        exports[j] = temp;
                    }
                }
            }

            foreach (ClassEntry export in exports)
            {
                if (ms_typeNames.ContainsKey(export.Attr.DerivedName))
                {
                    throw new ArgumentException(string.Format("{0} exports {1} but that class name has already been exported.", export.Type, export.Attr.DerivedName));
                }

                ms_typeNames.Add(export.Attr.DerivedName, export.Type);
                ms_classNames.Add(export.Type, export.Attr.DerivedName);

                DoInitClass(export.Attr.DerivedName, export.Attr.BaseName, export.Type, export.Attr.Outlets);
            }
        }
Exemplo n.º 2
0
            public ClassEntry(Type type, ExportClassAttribute attr)
            {
                Type = type;
                Attr = attr;

                ExportClassAttribute baseAttr = Attribute.GetCustomAttribute(type.BaseType, typeof(ExportClassAttribute), false) as ExportClassAttribute;

                if (baseAttr != null)
                {
                    Base = new ClassEntry(type.BaseType, baseAttr);
                }
            }
Exemplo n.º 3
0
        private static void DoValidateType(Type type)
        {
            foreach (MethodInfo info in type.GetMethods(BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.Instance))
            {
                ExportClassAttribute attr = Attribute.GetCustomAttribute(type, typeof(ExportClassAttribute), false) as ExportClassAttribute;
                if (attr != null)
                {
                    if (!typeof(NSObject).IsAssignableFrom(type))
                    {
                        throw new ArgumentException(string.Format("{0} uses ExportClassAttribute, but does not descend from NSObject.", type));
                    }
                }

                DoValidateMethod(type, info);
            }
        }
Exemplo n.º 4
0
        private static void DoValidateMethod(Type type, MethodInfo info)
        {
            ExportClassAttribute klassAttr  = Attribute.GetCustomAttribute(type, typeof(ExportClassAttribute), false) as ExportClassAttribute;
            RegisterAttribute    methodAttr = Attribute.GetCustomAttribute(info, typeof(RegisterAttribute), false) as RegisterAttribute;

            if (klassAttr != null)
            {
            }
            else
            {
                if (methodAttr != null)
                {
                    throw new ArgumentException(string.Format("{0} uses RegisterAttribute, but not ExportClassAttribute.", type));
                }
            }
        }
Exemplo n.º 5
0
        /// <summary>Constructs a managed object which is associated with an unmanaged object.</summary>
        /// <remarks>In general multiple NSObject instances can be associated with the same unmanaged object.
        /// The exception is that only one <see cref = "ExportClassAttribute">ExportClassAttribute</see> object can be associated with an
        /// unmanaged object. If an attempt is made to construct two NSObjects pointing to the same
        /// exported object an exception will be thrown. (The reason for this is that exported instances may
        /// have managed state which should be associated with one and only one unmanaged instance).</remarks>
        public NSObject(IntPtr instance)
        {
            m_instance = instance;                                      // note that it's legal to send messages to nil
            m_class    = IntPtr.Zero;

            if (m_instance != IntPtr.Zero)
            {
                // It's a little inefficient to always grab this information, but it makes
                // dumping objects much easier because we can safely do it even when ref
                // counts are zero.
                IntPtr exception = IntPtr.Zero;
                m_class = DirectCalls.Callp(m_instance, Selector.Class, ref exception);
                if (exception != IntPtr.Zero)
                {
                    CocoaException.Raise(exception);
                }

                m_baseClass = DirectCalls.Callp(m_class, Selector.SuperClass, ref exception);
                if (exception != IntPtr.Zero)
                {
                    CocoaException.Raise(exception);
                }

#if DEBUG
                if (SaveStackTraces)
                {
                    var stack = new System.Diagnostics.StackTrace(1);
                    StackTrace = new string[stack.FrameCount];
                    for (int i = 0; i < stack.FrameCount; ++i)                          // TODO: provide a MaxStackDepth method?
                    {
                        StackFrame frame = stack.GetFrame(i);

                        if (!string.IsNullOrEmpty(frame.GetFileName()))
                        {
                            StackTrace[i] = string.Format("{0}|{1} {2}:{3}", frame.GetMethod().DeclaringType, frame.GetMethod(), frame.GetFileName(), frame.GetFileLineNumber());
                        }
                        else
                        {
                            StackTrace[i] = string.Format("{0}|{1}", frame.GetMethod().DeclaringType, frame.GetMethod());
                        }
                    }
                }
#endif

                lock (ms_instancesLock)
                {
                    bool exported;
                    Type type = GetType();
                    if (!ms_exports.TryGetValue(type, out exported))                            // GetCustomAttribute turns out to be very slow
                    {
                        ExportClassAttribute attr = Attribute.GetCustomAttribute(type, typeof(ExportClassAttribute)) as ExportClassAttribute;
                        exported = attr != null;
                        ms_exports.Add(type, exported);
                    }

                    if (exported)
                    {
                        if (ms_instances.ContainsKey(instance))
                        {
                            throw new InvalidOperationException(type + " is being constructed twice with the same id, try using the Lookup method.");
                        }

                        ms_instances.Add(instance, this);
                    }
                }
#if DEBUG
                ms_refs.Add(this);
#endif
            }
        }