Author Topic: Storing all DbObjects derived classes by parents  (Read 3810 times)

0 Members and 1 Guest are viewing this topic.

Jeff H

  • Needs a day job
  • Posts: 6150
Storing all DbObjects derived classes by parents
« on: September 10, 2012, 05:33:01 AM »
Not to clutter up another thread but was inspired from Tony's thread Quick & Easy Managed Wrapper Type Discovery from ObjectIds by Tony T
 
This did not go as planned for a couple of reasons but if someone can find this useful for something then maybe it would not be a complete waste of time. Sorry for mess was trying different things to hopefully get some performance out of it but nothing any better and already accomplished with a much smaller footprint by Tony in link above.
 
 
For some reason I thought I could get the classes added and removed from DynamicLinker.ModuleLoaded & DynamicLinker.ModuleUnLoaded event then could just add or remove them, but I was wrong, that was one reason for storing all as strings for names.
 
I could not get any real performance gain from this, besides what Tony already has pointed out in thread above by checking if it has any children.
 
 
Attached at bottom is text file created from PrintTree method which below is part of it where class name then the children are printed below it indented.
Code: [Select]

 AcDbObject
        AcAeEEMgrObj
        AcDbAssocAction
        AcDbAssocActionBody
        AcDbAssocActionParam
        AcDbAssocDependency
        AcDbAssocDependencyBody
        AcDbAssocExternalPersSubentIdManager
        AcDbAssocManager
        AcDbAssocNamespace
        AcDbAssocPersSubentManager
        AcDbBlockRepresentationData
        AcDbBreakData
        AcDbBreakPointRef
        AcDbCellStyleMap
        AcDbColor
        AcDbDataLink
        AcDbDataTable
        AcDbDictionary
        AcDbDictionaryVar
        AcDbDimAssoc
        AcDbEntity
        AcDbEvalExpr
        AcDbEvalGraph
        AcDbField
        AcDbFilter
        AcDbGeoData
        AcDbGroup
        AcDbIdBuffer
        AcDbIdSet
        AcDbImpNonPersistentObjectsCollection
        AcDbIndex
        AcDbLinkedData
        AcDbLongTransaction
        AcDbLSObject
        AcDbMaterial
        AcDbMLeaderStyle
        AcDbMlineStyle
        AcDbModelDocViewStyle
        AcDbObjectContextData
        AcDbPartialOpenSavedState
        AcDbPersSubentManager
        AcDbPlaceHolder
        AcDbPlotSettings
        AcDbProxyEntityData
        AcDbProxyObject
        AcDbProxyObjectWrapper
        AcDbRasterImageDef
        AcDbRasterImageDefReactor
        AcDbRasterVariables
        AcDbScale
        AcDbSectionManager
        AcDbSectionSettings
        AcDbShHistory
        AcDbSortentsTable
        AcDbSymbolTable
        AcDbSymbolTableRecord
        AcDbTableGeometry
        AcDbTableStyle
        AcDbUnderlayDefinition
        AcDbVbaProject
        AcDbVisualStyle
        AcDbWipeoutVariables
        AcDbXrecord
        ExAcTermXrefMap
        ExAcXREFPanelObject
        vlo_VL
AcDbCurve
        AcDb2dPolyline
        AcDb3dPolyline
        AcDbArc
        AcDbCircle
        AcDbEllipse
        AcDbLeader
        AcDbLine
        AcDbPolyline
        AcDbRay
        AcDbSpline
        AcDbXline
AcDbVertex
        AcDb2dVertex
        AcDb3dPolylineVertex
        AcDbFaceRecord
        AcDbPolyFaceMeshVertex
        AcDbPolygonMeshVertex
.........
.........
.........

 
Here is class that has PrintTree method and the only other method that if intrested to pay attention to is the Initialize method.
Code - C#: [Select]
  1.  
  2.     public sealed class RXClassInfo
  3.     {
  4.         static readonly RXClassInfo current = new RXClassInfo();
  5.         static ChildrenLookup childLookup;
  6.        
  7.        internal ChildrenLookup ChildLookup
  8.         {
  9.             get
  10.             {
  11.                 return childLookup;                
  12.             }
  13.         }
  14.           static RXClassInfo()
  15.             {
  16.                 childLookup = new ChildrenLookup();
  17.                 SystemObjects.DynamicLinker.ModuleLoaded  = new ModuleLoadedEventHandler(DynamicLinker_ModuleLoaded);
  18.                 SystemObjects.DynamicLinker.ModuleUnloaded  = new ModuleUnloadedEventHandler(DynamicLinker_ModuleUnloaded);
  19.                 Intialize();
  20.             }
  21.           RXClassInfo(){ }
  22.           public static RXClassInfo Current
  23.           {
  24.               get
  25.               {
  26.                   return current;
  27.               }
  28.           }
  29.             static void DynamicLinker_ModuleLoaded(object sender, DynamicLinkerEventArgs e)
  30.             {
  31.                RXClassInfo.Current.ChildLookup.Clear();
  32.                 Intialize();
  33.             }
  34.             static void DynamicLinker_ModuleUnloaded(object sender, DynamicLinkerEventArgs e)
  35.             {
  36.                 RXClassInfo.Current.ChildLookup.Clear();
  37.                 Intialize();
  38.             }
  39.  
  40.             static void Intialize()
  41.             {
  42.                 RXClass rxDBObject = RXClass.GetClass(typeof(DBObject));
  43.                 foreach (DictionaryEntry e in SystemObjects.ClassDictionary)
  44.                 {
  45.                     RXClass rxclass = e.Value as RXClass;
  46.                     if (rxclass.IsDerivedFrom(rxDBObject) && !rxclass.Name.StartsWith("Imp"))
  47.                     {
  48.                         RXClass parent = rxclass.MyParent;
  49.                         if (parent != null)
  50.                         {
  51.                             RXClassInfo.Current.ChildLookup.Add(parent.Name, rxclass.Name);
  52.                         }
  53.                     }
  54.                 }
  55.             }
  56.             public void PrintTree()
  57.             {
  58.                 //Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  59.                 //foreach (IGrouping<string, string> group in ChildLookup)
  60.                 //{
  61.                 //    ed.WriteLine(group.Key);
  62.                 //    foreach (string s in group)
  63.                 //    {
  64.                 //        ed.WriteLine("---- "   s);
  65.                 //    }
  66.                 //}
  67.                 using (StreamWriter tw = new StreamWriter(@"C:\Testing\PrintTree.txt"))
  68.                 {
  69.                     foreach (IGrouping<string, string> group in ChildLookup)
  70.                     {
  71.                         tw.WriteLine(group.Key);
  72.                         foreach (string s in group)
  73.                         {
  74.                             tw.WriteLine("        "   s);
  75.                         }
  76.                     }
  77.      
  78.                 }
  79.             }
  80.     }
  81.  

Basically what you have is two classes
ChildrenGrouping which implements IGrouping<string, string>
&
ChildrenLookup which implements ILookup<string,string>
 
It is a editable Lookup
 
The ChildrenGrouping class is a List<string> with a key.
The ChildrenLookUp class is a Dictionary<string, ChildrenGrouping>
 
The ChildrenGrouping
Code - C#: [Select]
  1.    //Inspired by Jon Skeet http://msmvps.com/blogs/jon_skeet/Default.aspx
  2.    //Derivation of Jon Skeet's EditableLookup source: http://www.yoda.arachsys.com/csharp/miscutil/  
  3.    internal class ChildrenGrouping : IGrouping<string, string>
  4.    {
  5.        private readonly string key;
  6.        private List<string> children = new List<string>();
  7.        public ChildrenGrouping(string key)
  8.        {
  9.            this.key = key;
  10.        }
  11.        public string Key
  12.        {
  13.            get { return key; }
  14.        }
  15.        public int Count
  16.        {
  17.            get { return children.Count; }
  18.        }
  19.  
  20.        public void Add(string ptr)
  21.        {
  22.            children.Add(ptr);
  23.        }
  24.        public bool Contains(string ptr)
  25.        {
  26.            return children.Contains(ptr);
  27.        }
  28.        public bool Remove(string ptr)
  29.        {
  30.            return children.Remove(ptr);
  31.        }
  32.        public void TrimExcess()
  33.        {
  34.            children.TrimExcess();
  35.        }
  36.        public IEnumerator<string> GetEnumerator()
  37.        {
  38.            return children.GetEnumerator();
  39.            
  40.        }
  41.        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
  42.        {
  43.            return GetEnumerator();
  44.        }
  45.        public void Clear()
  46.        {
  47.            children.Clear();
  48.        }
  49.    }
  50.  

The ChildrenLookup
Code - C#: [Select]
  1.  
  2.   //Inspired by Jon Skeet http://msmvps.com/blogs/jon_skeet/Default.aspx
  3.    //Derivation of Jon Skeet's EditableLookup source: http://www.yoda.arachsys.com/csharp/miscutil/  
  4.    internal class ChildrenLookup : ILookup<string, string>
  5.    {
  6.        private readonly Dictionary<string, ChildrenGrouping> childrenGroups;
  7.        public ChildrenLookup()
  8.        {
  9.            childrenGroups = new Dictionary<string, ChildrenGrouping>();
  10.        }
  11.        public bool Contains(string key)
  12.        {
  13.            ChildrenGrouping childGroup;
  14.            return childrenGroups.TryGetValue(key, out childGroup) ? childGroup.Count > 0 : false;
  15.        }
  16.        public bool Contains(string key, string value)
  17.        {
  18.            ChildrenGrouping childGroup;
  19.            return childrenGroups.TryGetValue(key, out childGroup) ? childGroup.Contains(value) : false;
  20.        }
  21.        public int Count
  22.        {
  23.            get { return childrenGroups.Count; }
  24.        }
  25.  
  26.        public void Add(string key, string value)
  27.        {
  28.            ChildrenGrouping childGroup;
  29.            if (!childrenGroups.TryGetValue(key, out childGroup))
  30.            {
  31.                childGroup = new ChildrenGrouping(key);
  32.                childrenGroups.Add(key, childGroup);
  33.            }
  34.            childGroup.Add(value);
  35.        }
  36.        public void AddRange(string key, IEnumerable<string> values)
  37.        {
  38.            values.ThrowIfNull("values");
  39.            ChildrenGrouping childGroup;
  40.            if (!childrenGroups.TryGetValue(key, out childGroup))
  41.            {
  42.                childGroup = new ChildrenGrouping(key);
  43.                childrenGroups.Add(key, childGroup);
  44.            }
  45.            foreach (string value in values)
  46.            {
  47.                childGroup.Add(value);
  48.            }
  49.            if (childGroup.Count == 0)
  50.            {
  51.                childrenGroups.Remove(key); // nothing there after all!
  52.            }
  53.        }
  54.        public void AddRange(ILookup<string, string> lookup)
  55.        {
  56.            lookup.ThrowIfNull("lookup"); ;
  57.            foreach (IGrouping<string, string> group in lookup)
  58.            {
  59.                AddRange(group.Key, group);
  60.            }
  61.        }
  62.        public bool Remove(string key)
  63.        {
  64.            return childrenGroups.Remove(key);
  65.        }
  66.  
  67.        public bool Remove(string key, string value)
  68.        {
  69.            ChildrenGrouping childGroup;
  70.            if (childrenGroups.TryGetValue(key, out childGroup))
  71.            {
  72.                bool removed = childGroup.Remove(value);
  73.                if (removed && childGroup.Count == 0)
  74.                {
  75.                    childrenGroups.Remove(key);
  76.                }
  77.                return removed;
  78.            }
  79.            return false;
  80.        }
  81.        public void TrimExcess()
  82.        {
  83.            foreach (var childGroup in childrenGroups.Values)
  84.            {
  85.                childGroup.TrimExcess();
  86.            }
  87.        }
  88.        public static readonly IEnumerable<string> Empty = new string[0];
  89.        public IEnumerable<string> this[string key]
  90.        {
  91.            get
  92.            {
  93.                ChildrenGrouping childGroup;
  94.                if (childrenGroups.TryGetValue(key, out childGroup))
  95.                {
  96.                    return childGroup;
  97.                }
  98.                return Empty;
  99.            }
  100.        }
  101.  
  102.        public IEnumerator<IGrouping<string, string>> GetEnumerator()
  103.        {
  104.            foreach (var childGroup in childrenGroups.Values)
  105.            {
  106.                yield return childGroup;
  107.            }
  108.        }
  109.        System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
  110.        {
  111.            return GetEnumerator();
  112.        }
  113.        public void Clear()
  114.        {
  115.            childrenGroups.Clear();
  116.        }
  117.    }
  118.  

Then used as
Code - C#: [Select]
  1.  
  2.              /// <summary>
  3.             /// Inspired by Tony Tanzillo from http://www.theswamp.org/index.php?topic=41371.msg465493#msg465493
  4.             /// See RXClassInfo class
  5.             /// </summary>
  6.             /// <param name="rxclass"></param>
  7.             /// <returns></returns>
  8.             ///          
  9.             public static bool HasChildren(this RXClass rxclass)
  10.             {
  11.                 return RXClassInfo.Current.ChildLookup.Contains(rxclass.Name);
  12.             }
  13.  

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Storing all DbObjects derived classes by parents
« Reply #1 on: September 10, 2012, 05:54:14 AM »
Just a quick thought,
In the DynamicLinker.ModuleLoaded & DynamicLinker.ModuleUnLoaded event could you check if the filename ends with a .arx or check the SystemObjects.ClassDictionary.Count to see iff you needed to rebuild it?

TheMaster

  • Guest
Re: Storing all DbObjects derived classes by parents
« Reply #2 on: September 10, 2012, 07:18:28 AM »
Just a quick thought,
In the DynamicLinker.ModuleLoaded & DynamicLinker.ModuleUnLoaded event could you check if the filename ends with a .arx or check the SystemObjects.ClassDictionary.Count to see iff you needed to rebuild it?

After having done some testing, I decided to eliminate the caching, and just scan the dictionary every time I need to find out if a class has derived classes.  The time needed to do it is so minute that it's not an issue and certainly not worth all the additional work of trying to keep a cache in-sync.

Also, the module load/unload events are not the only place where the runtime class tree can be rebuilt. While it would be very rare, It can theoretically happen at any time, by calling acrxBuildClassHierarchy(), so the event-based synchronization isn't all that reliable to start with.

From the ObjectARX docs:

Quote

This function is used to rebuild the ObjectARX runtime class tree when new classes need to be added. It can be safely called at any time, but is necessary only after the rxInit() functions have been called for any classes to be added to the runtime tree. This is usually done inside the AcRx::kInitAppMsg case of the acrxEntryPoint() switch statement (or a function called from there). This function needs to be called only once after all the rxInit() calls have been made.

« Last Edit: September 10, 2012, 07:24:01 AM by TT »

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Storing all DbObjects derived classes by parents
« Reply #3 on: September 10, 2012, 07:33:47 AM »
I left out that performance gain mentioned in first post was using it to get all derived classes by its parent to create a collection of InPtr's from the RXClass's Unmanagedpointer property and then checking if it contained a ObjectId.ObjectClass.UnmanagedPointer
 
 
Also would need the following 3 classes
 
Some Object Extensions
Code - C#: [Select]
  1.  public static class ObjectExtensions
  2.     {
  3.         /// <summary>
  4.         /// Indicates if object is null
  5.         /// </summary>
  6.         /// <typeparam name="T">Type of Object</typeparam>
  7.         /// <param name="data">The Object to check</param>
  8.         /// <returns>True if object is null</returns>
  9.         public static bool IsNull<T>(this T data) where T : class
  10.         {
  11.             return data == null;
  12.         }
  13.         /// <summary>
  14.         /// Throws an ArgumentNullException if the given data item is null.
  15.         /// </summary>
  16.         /// <param name="data">The item to check for if null.</param>
  17.         /// <param name="name">Name of parameter to pass to exception</param>
  18.         public static void ThrowIfNull<T>(this T data, string name) where T : class
  19.         {
  20.             if (data == null)
  21.             {
  22.                 throw new ArgumentNullException(name);
  23.             }
  24.         }
  25.         /// <summary>
  26.         /// Throws an ArgumentNullException if the given data item is null.
  27.         /// See overloaded method to pass parameter name
  28.         /// </summary>
  29.         /// <param name="data">The item to check for if null.</param>
  30.         public static void ThrowIfNull<T>(this T data) where T : class
  31.         {
  32.             if (data == null)
  33.             {
  34.                 throw new ArgumentNullException();
  35.             }
  36.         }
  37.     }
  38.  

Some string Extensions
Code - C#: [Select]
  1.  public static class StringExtensions
  2.     {
  3.         /// <summary>
  4.         /// Checks if string is Null or Empty("")
  5.         /// </summary>
  6.         /// <param name="str">The string to check if Null or Empty("")</param>
  7.         /// <returns>True if string is Null or Empty("")</returns>
  8.         public static bool IsNullOrEmpty(this string str)
  9.         {
  10.             return String.IsNullOrEmpty(str);
  11.         }
  12.         /// <summary>
  13.         /// Throws an ArgumentNullException if string is if Null or Empty("").
  14.         /// </summary>
  15.         /// <param name="str">True if string is Null or Empty("")</param>
  16.         public static void ThrowIfNullOrEmpty(this string str)
  17.         {
  18.             if (str.IsNullOrEmpty())
  19.             {
  20.                 throw new ArgumentNullException(str);
  21.             }
  22.         }
  23.         /// <summary>
  24.         /// Checks if string is Null, all whitespaces, or Empty("")
  25.         /// </summary>
  26.         /// <param name="str">The string to check if Null, all whitespaces, or Empty("")</param>
  27.         /// <returns>True if string is Null, all whitespaces, or Empty("")</returns>
  28.         public static bool IsNullOrWhiteSpace(this string str)
  29.         {
  30.             return String.IsNullOrWhiteSpace(str);
  31.         }
  32.  
  33.  
  34.         /// <summary>
  35.         /// Throws an ArgumentNullException if string is Null, all whitespaces, or Empty("")
  36.         /// </summary>
  37.         /// <param name="str">The string to check if Null, all whitespaces, or Empty("")</param>
  38.         public static void ThrowIfNullOrWhiteSpace(this string str)
  39.         {
  40.             if (str.IsNullOrWhiteSpace())
  41.             {
  42.                 throw new ArgumentNullException(str);
  43.             }
  44.         }
  45.     }
  46.  
   
 
Some Editor Extensions to mimc using the Console
 
Code - C#: [Select]
  1.  
  2.      public static class EditorExtensions
  3.     {        
  4.         /// <summary>
  5.         /// Private field holding the Environment's newline ("/r/n")
  6.         /// </summary>
  7.         private static string newLine = Environment.NewLine;
  8.         /// <summary>
  9.         /// Private field holding IFormatProvider
  10.         /// </summary>
  11.         private static IFormatProvider _formatProvider;
  12.         /// <summary>
  13.         /// Property to get current IFormatProvider
  14.         /// </summary>
  15.         private static IFormatProvider formatProvider
  16.         {
  17.             get
  18.             {
  19.                 if (_formatProvider == null)
  20.                 {
  21.                     _formatProvider = Thread.CurrentThread.CurrentCulture;
  22.                 }
  23.                 return _formatProvider;
  24.             }
  25.         }
  26.         /// <summary>
  27.         /// Writes the specified subarray of Unicode characters to the CommandLine
  28.         /// </summary>
  29.         /// <param name="ed">Extension method of Editor</param>
  30.         /// <param name="buffer">An array of Unicode characters.</param>
  31.         /// <param name="index">The starting position in buffer.</param>
  32.         /// <param name="count">The number of characters to write.</param>
  33.         /// <exception cref="System.ArgumentNullException">Thrown if buffer is null</exception>
  34.         /// <exception cref="System.ArgumentOutOfRangeException">Thrown if index is less than zero.</exception>
  35.         /// <exception cref="System.ArgumentOutOfRangeException">Thrown if count is less than zero.</exception>
  36.         /// <exception cref="System.ArgumentException">Thrown if index plus count specify a position that is not within buffer.</exception>
  37.         public static void Write(this Editor ed, char[] buffer, int index, int count)
  38.         {
  39.             buffer.ThrowIfNull("buffer");
  40.             index.ThrowIfLessThanZero("index");
  41.             count.ThrowIfLessThanZero("count");
  42.             if ((buffer.Length - index) < count)
  43.             {
  44.                 throw new ArgumentException("Buffer Invalid Length");
  45.             }
  46.             for (int i = 0; i < count; i++)
  47.             {
  48.                 ed.Write(buffer[index + i]);
  49.             }
  50.         }
  51.         /// <summary>
  52.         /// Writes the specified subarray of Unicode characters to the CommandLine
  53.         /// </summary>
  54.         /// <param name="ed">Extension method of Editor</param>
  55.         /// <param name="buffer"> A Unicode character array.</param>
  56.         public static void Write(this Editor ed, char[] buffer)
  57.         {
  58.             ed.Write(buffer, 0, buffer.Length);
  59.         }
  60.         /// <summary>
  61.         /// Writes the text representation of the specified Boolean value to the CommandLine
  62.         /// </summary>
  63.         /// <param name="ed">Extension method of Editor</param>
  64.         /// <param name="value">The value to write.</param>
  65.         public static void Write(this Editor ed, bool value)
  66.         {
  67.             ed.WriteMessage(value ? "True" : "False");
  68.         }
  69.         /// <summary>
  70.         /// Writes the specified Unicode character value to the CommandLine
  71.         /// </summary>
  72.         /// <param name="ed">Extension method of Editor</param>
  73.         /// <param name="value">The value to write.</param>
  74.         public static void Write(this Editor ed, char value)
  75.         {
  76.             ed.WriteMessage(value.ToString(formatProvider));
  77.         }
  78.         public static void Write(this Editor ed, decimal value)
  79.         {
  80.             ed.WriteMessage(value.ToString(formatProvider));
  81.         }
  82.         public static void Write(this Editor ed, double value)
  83.         {
  84.             ed.WriteMessage(value.ToString(formatProvider));
  85.         }
  86.         public static void Write(this Editor ed, int value)
  87.         {
  88.             ed.WriteMessage(value.ToString(formatProvider));
  89.         }
  90.         public static void Write(this Editor ed, Int64 value)
  91.         {
  92.             ed.WriteMessage(value.ToString(formatProvider));
  93.         }
  94.         public static void Write(this Editor ed, Point2d value)
  95.         {
  96.             ed.WriteMessage(value.ToString(formatProvider));
  97.         }
  98.         public static void Write(this Editor ed, Point3d value)
  99.         {
  100.             ed.WriteMessage(value.ToString(formatProvider));
  101.         }
  102.         public static void Write(this Editor ed, object value)
  103.         {
  104.             if (!value.IsNull())
  105.             {
  106.                 IFormattable formattable = value as IFormattable;
  107.                 if (!formattable.IsNull())
  108.                 {
  109.                     ed.WriteMessage(formattable.ToString(null, formatProvider));
  110.                 }
  111.                 else
  112.                 {
  113.                     ed.Write(value.ToString());
  114.                 }
  115.             }
  116.         }
  117.         public static void Write(this Editor ed, Single value)
  118.         {
  119.             ed.WriteMessage(value.ToString(formatProvider));
  120.         }
  121.         public static void Write(this Editor ed, string value)
  122.         {
  123.             if (!value.IsNullOrEmpty())
  124.             {
  125.                 ed.WriteMessage(value);
  126.             }
  127.         }
  128.         //public static void Write(this Editor ed, UInt32 value)
  129.         //{
  130.         //    ed.WriteMessage(value.ToString(formatProvider));
  131.         //}
  132.         //public static void Write(this Editor ed, UInt64 value)
  133.         //{
  134.         //    ed.WriteMessage(value.ToString(formatProvider));
  135.         //}
  136.         public static void Write(this Editor ed, ObjectId value)
  137.         {
  138.             ed.WriteMessage(value.ToString(formatProvider));
  139.         }
  140.         public static void Write(this Editor ed, string format, object arg0)
  141.         {
  142.             ed.WriteMessage(string.Format(formatProvider, format, new object[] { arg0 }));
  143.         }
  144.         public static void Write(this Editor ed, string format, params object[] arg)
  145.         {
  146.             ed.WriteMessage(string.Format(formatProvider, format, arg));
  147.         }
  148.         public static void Write(this Editor ed, string format, object arg0, object arg1)
  149.         {
  150.             ed.WriteMessage(string.Format(formatProvider, format, new object[] { arg0, arg1 }));
  151.         }
  152.         public static void Write(this Editor ed, string format, object arg0, object arg1, object arg2)
  153.         {
  154.             ed.WriteMessage(string.Format(formatProvider, format, new object[] { arg0, arg1, arg2 }));
  155.         }
  156.         public static void WriteLine(this Editor ed)
  157.         {
  158.             ed.WriteMessage(newLine);
  159.         }
  160.         public static void WriteLine(this Editor ed, char[] buffer, int index, int count)
  161.         {
  162.             ed.Write(buffer, index, count);
  163.             ed.WriteLine();
  164.         }
  165.         public static void WriteLine(this Editor ed, char[] buffer)
  166.         {
  167.             ed.Write(buffer);
  168.             ed.WriteLine();
  169.         }
  170.         public static void WriteLine(this Editor ed, bool value)
  171.         {
  172.             ed.Write(value);
  173.             ed.WriteLine();
  174.         }
  175.         public static void WriteLine(this Editor ed, char value)
  176.         {
  177.             ed.Write(value);
  178.             ed.WriteLine();
  179.         }
  180.         public static void WriteLine(this Editor ed, decimal value)
  181.         {
  182.             ed.Write(value);
  183.             ed.WriteLine();
  184.         }
  185.         public static void WriteLine(this Editor ed, double value)
  186.         {
  187.             ed.Write(value);
  188.             ed.WriteLine();
  189.         }
  190.         public static void WriteLine(this Editor ed, int value)
  191.         {
  192.             ed.Write(value);
  193.             ed.WriteLine();
  194.         }
  195.         public static void WriteLine(this Editor ed, Int64 value)
  196.         {
  197.             ed.Write(value);
  198.             ed.WriteLine();
  199.         }
  200.         public static void WriteLine(this Editor ed, Point2d value)
  201.         {
  202.             ed.Write(value);
  203.             ed.WriteLine();
  204.         }
  205.         public static void WriteLine(this Editor ed, Point3d value)
  206.         {
  207.             ed.Write(value);
  208.             ed.WriteLine();
  209.         }
  210.  
  211.         public static void WriteLine(this Editor ed, object value)
  212.         {
  213.             if (value.IsNull())
  214.             {
  215.                 ed.WriteLine();
  216.             }
  217.             else
  218.             {
  219.                 IFormattable formattable = value as IFormattable;
  220.                 if (!formattable.IsNull())
  221.                 {
  222.                     ed.Write(formattable.ToString(null, formatProvider));
  223.                 }
  224.                 else
  225.                 {
  226.                     ed.WriteMessage(value.ToString());
  227.                 }
  228.                 ed.WriteLine();
  229.             }
  230.         }
  231.         public static void WriteLine(this Editor ed, Single value)
  232.         {
  233.             ed.Write(value);
  234.             ed.WriteLine();
  235.         }
  236.         public static void WriteLine(this Editor ed, string value)
  237.         {
  238.             ed.Write(value);
  239.             ed.WriteLine();
  240.         }
  241.         //public static void WriteLine(this Editor ed, UInt32 value)
  242.         //{
  243.         //    ed.Write(value);
  244.         //    ed.WriteLine();
  245.         //}
  246.         //public static void WriteLine(this Editor ed, UInt64 value)
  247.         //{
  248.         //    ed.Write(value);
  249.         //    ed.WriteLine();
  250.         //}
  251.         public static void WriteLine(this Editor ed, ObjectId value)
  252.         {
  253.             ed.Write(value);
  254.             ed.WriteLine();
  255.         }
  256.         public static void WriteLine(this Editor ed, string format, object arg0)
  257.         {
  258.             ed.Write(format, arg0);
  259.             ed.WriteLine();
  260.         }
  261.         public static void WriteLine(this Editor ed, string format, params object[] arg)
  262.         {
  263.             ed.Write(format, arg);
  264.             ed.WriteLine();
  265.         }
  266.         public static void WriteLine(this Editor ed, string format, object arg0, object arg1)
  267.         {
  268.             ed.Write(format, arg0, arg1);
  269.             ed.WriteLine();
  270.         }
  271.         public static void WriteLine(this Editor ed, string format, object arg0, object arg1, object arg2)
  272.         {
  273.             ed.Write(format, arg0, arg1, arg2);
  274.             ed.WriteLine();
  275.         }
  276.  
  277.  
  278.  
  279.         public static void PrintItems<T>(this Editor ed, IEnumerable<T> items)
  280.         {
  281.             foreach (var item in items)
  282.             {
  283.                 ed.WriteLine(item);
  284.             }
  285.         }
  286.         public static void SendPause(this Editor ed)
  287.         {
  288.            Command.Pause.Execute();
  289.         }
  290.         public static int ExecuteCommand(this Editor ed, Command cmd, bool waitForCommandToEnd = false)
  291.         {
  292.             return cmd.Execute(waitForCommandToEnd);
  293.         }
  294.         public static int ExecuteCommand(this Editor ed, bool waitForCommandToEnd, string commandName, params object[] args)
  295.         {
  296.             Command cmd = new Command(commandName, args);
  297.             return cmd.Execute(waitForCommandToEnd);
  298.         }
  299.         public static bool IsCommandActive(this Editor ed, string commandName)
  300.         {
  301.             string names = (string)Application.GetSystemVariable(("CMDNAMES"));
  302.             return names.ToUpper().IndexOf(commandName) >= 0;
  303.         }
  304.        
  305.        
  306.     }
  307.  

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Storing all DbObjects derived classes by parents
« Reply #4 on: September 10, 2012, 07:47:05 AM »
Just a quick thought,
In the DynamicLinker.ModuleLoaded & DynamicLinker.ModuleUnLoaded event could you check if the filename ends with a .arx or check the SystemObjects.ClassDictionary.Count to see iff you needed to rebuild it?

After having done some testing, I decided to eliminate the caching, and just scan the dictionary every time I need to find out if a class has derived classes.  The time needed to do it is so minute that it's not an issue and certainly not worth all the additional work of trying to keep a cache in-sync.

Also, the module load/unload events are not the only place where the runtime class tree can be rebuilt. While it would be very rare, It can theoretically happen at any time, by calling acrxBuildClassHierarchy(), so the event-based synchronization isn't all that reliable to start with.

From the ObjectARX docs:

Quote

This function is used to rebuild the ObjectARX runtime class tree when new classes need to be added. It can be safely called at any time, but is necessary only after the rxInit() functions have been called for any classes to be added to the runtime tree. This is usually done inside the AcRx::kInitAppMsg case of the acrxEntryPoint() switch statement (or a function called from there). This function needs to be called only once after all the rxInit() calls have been made.

I went ahead posted previous post if anyone wanted those classes, but after spending a hour or two writing the crap in first post there was no gain and if I remeber correctly performed slightly worse than your example that looks for first child.
 
I knew I should of trusted my gut and left it alone, but playing around with it I had another "Ahhhh I see why Tony did that way".

TheMaster

  • Guest
Re: Storing all DbObjects derived classes by parents
« Reply #5 on: September 19, 2012, 01:20:44 PM »

   .......Some Editor Extensions to mimc using the Console........


You don't really need all of that code.

Code - C#: [Select]
  1. // AcConsole.cs   Copyright (c) 2009   Tony Tanzillo
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using System.IO;
  7. using Autodesk.AutoCAD.ApplicationServices;
  8. using Autodesk.AutoCAD.Runtime;
  9.  
  10. namespace System
  11. {
  12.    /// <summary>
  13.    /// Redirects Console output to the AutoCAD Text Window
  14.    /// </summary>
  15.  
  16.    public class AcConsoleTextWriter : TextWriter
  17.    {
  18.       TextWriter stdout = null;
  19.  
  20.       public AcConsoleTextWriter()
  21.       {
  22.          stdout = Console.Out;
  23.          Console.SetOut( this );
  24.       }
  25.  
  26.       public override Encoding Encoding
  27.       {
  28.          get
  29.          {
  30.             return stdout.Encoding;
  31.          }
  32.       }
  33.  
  34.       public override void Write( char[] buffer, int index, int count )
  35.       {
  36.          stdout.Write( buffer, index, count );
  37.          if( buffer != null && buffer.Length > 0 )
  38.          {
  39.             Document doc = TryGetDocument();
  40.             if( doc != null )
  41.                doc.Editor.WriteMessage( "\n[Console]: {0}", new string( buffer ) );
  42.          }
  43.       }
  44.      
  45.       Document TryGetDocument()
  46.       {
  47.          try
  48.          {
  49.             return Application.DocumentManager.MdiActiveDocument;
  50.          }
  51.          catch
  52.          {
  53.             return null;
  54.          }
  55.       }
  56.  
  57.       protected override void Dispose( bool disposing )
  58.       {
  59.          if( stdout != null )
  60.          {
  61.             Console.SetOut( stdout );
  62.             stdout = null;
  63.          }
  64.          base.Dispose( disposing );
  65.       }
  66.    }
  67.  
  68.    /// <summary>
  69.    /// Usage Example:
  70.    /// </summary>
  71.  
  72.    public static class MyCommands
  73.    {
  74.       [CommandMethod( "ACCONSOLE" )]
  75.       public static void AcConsoleExample()
  76.       {
  77.          // This is a transient instance only for
  78.          // demonstration purposes. You would more
  79.          // commonly keep this alive for as long as
  80.          // you want Console IO redirected.
  81.  
  82.          using( new AcConsoleTextWriter() )
  83.          {
  84.             Console.WriteLine( "Hello there 8)" );
  85.             Console.Write( 999 ); // write an int
  86.             Console.Write( true ); // write a bool
  87.          }
  88.       }
  89.    }
  90. }
  91.  

One thing I should mention is that the above code is by no means thread-safe, which means that if Console output is done from a non-AutoCAD thread, it will probably not appear, so caveat emptor.

« Last Edit: September 20, 2012, 12:48:13 PM by TT »

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Storing all DbObjects derived classes by parents
« Reply #6 on: September 20, 2012, 09:19:15 AM »
DOH!
Completely missed that one.
 
That one was staring me in face when I copied methods from reflector and were editing and replacing each calls to its textwriter.
 
Thanks again!!