Author Topic: Third Routine - Working Progress  (Read 12323 times)

0 Members and 1 Guest are viewing this topic.

TheMaster

  • Guest
Re: Third Routine - Working Progress
« Reply #15 on: February 05, 2013, 11:42:45 AM »
You misunderstood what I said ... certainly there is no dissention on the use of all caps, it is certainly difficult to read ... the dissention is on what constitutes the "correct" standard by which one should write code.

I think most of us have come to terms with the fact that there are two things that we all know better than to debate, one of which is Religion.


TheMaster

  • Guest
Re: Third Routine - Working Progress
« Reply #16 on: February 05, 2013, 12:02:36 PM »

....If it's helpful, I spent a lot of my very early time on through the interface.....


Kean's blog is great for seeing examples of how to use the very complicated managed API, but at the same time, it is not a good place to learn a programming language like C#, because Kean's code routinely exhibits examples of poor coding.

For example, in a recent post he shows an example of a method that uses LINQ internally, but which  returns an array, something that you should never do in a general-purpose, resuable method.

If he posted that code on StackOverflow or CodeProject, they would just eat him alive.   :laugh:


bchapman

  • Guest
Re: Third Routine - Working Progress
« Reply #17 on: February 05, 2013, 12:10:59 PM »
Thanks Will... I'll keep that in consideration. I stress that I'm "learning" to do exactly what you're asking... tell people what I don't know.  I don't know anything. I went straight from Autolisp, to cutting and pasting C# code together, creating variables, and debugging it as necessary, til it worked. Using visual lisp with the COM helped me understand a little bit about using namespaces, which in Lisp I'd use to invoke methods.  With C# I know I have to start transactions. I know I have to pick an object, then define it as something else, then define that as something else to use it how I want but I don't know why.  As you can see I don't even know the appropriate terms.  I know visual lisp well, some visual basic as needed to create various excel forms, active script for company flash websites, and java for html sites so I can look at the c# code and it's almost like looking through muddy glasses... can make out what I am looking at...but can really see the details clearly.  I know ZERO coding terms. So when someone in C# talks about classes, and methods, and namespaces, etc. or whatever for c# I don't even know what they are talking about.  I haven't even looked through the tutorials... I skipped them.  Obviously the first thing every programmer here will do is tell me to go back and figure that stuff out...  I get incredibaly board with "hello world" and basic functions... and would never make it through... lol 

As far as them helping, I understand that.



BC,

At the risk of being perceived to be a member of the male genitalia I'd like to offer my protest to your thoughts of leaving the swamp.

IMO:

The swamp is the best place on the net for AutoCAD programming.  You're a fool to not utilize it.

You need to forget your ego.  I've read several times about how you're learning and you're new, but frankly I don't care.  I get the impression that you're used to knowing what you're doing and this step into unknown muddy waters is a little scary (especially with the potential ogres [yes at the swamp I like to think of them as ogres rather than trolls {hope that's ok with you kerry}]) but it's wasting everybody's time reiterating that you're learning.  Instead of telling me what you don't know, I'd like to see you tell me what you're doing, what you know (or think you know) , and what you need to know.

These guys do want to help you, they've gone as far as telling you what they want from you to minimize the time they have to spend looking through your code (they are doing it for free...) to understand what you're trying to do, considering you don't provide any explanation or comments.

That said, I suggest you suck it up and stick it out.  I don't want to see you quit, this is a very powerful application and you've made the right choice in stepping beyond lisp.  Stop complaining about what is being provided for free help, these guys know everything, you want them to be able to read your code.

If it's helpful, I spent a lot of my very early time on through the interface.  It took about a year of working on cad customizations before I came across anything really unique that I couldn't find in another post somewhere, so I didn't have any need to post any questions or comments until recently.  I was disappointed to get very little criticism, so it really irritates me to see you getting good critical input and not appreciating it.

Cheers

WILL HATCH

  • Bull Frog
  • Posts: 450
Re: Third Routine - Working Progress
« Reply #18 on: February 05, 2013, 01:21:04 PM »

....If it's helpful, I spent a lot of my very early time on through the interface.....


Kean's blog is great for seeing examples of how to use the very complicated managed API, but at the same time, it is not a good place to learn a programming language like C#, because Kean's code routinely exhibits examples of poor coding.

For example, in a recent post he shows an example of a method that uses LINQ internally, but which  returns an array, something that you should never do in a general-purpose, resuable method.

If he posted that code on StackOverflow or CodeProject, they would just eat him alive.   :laugh:

You've shown me the way in that sense, thanks!  I've since learned better methods of handling problems through examples posted here.  The one that stands out in my mind the most was his method of handling anonymous/dynamic blocks with this long messy routine of looking through xdata when you showed me a very elegant method using GetBlockReferenceIds and GetAnonymousBlockIds.

Thanks!

WILL HATCH

  • Bull Frog
  • Posts: 450
Re: Third Routine - Working Progress
« Reply #19 on: February 05, 2013, 01:22:44 PM »
Thanks Will... I'll keep that in consideration. I stress that I'm "learning" to do exactly what you're asking... tell people what I don't know.  I don't know anything. I went straight from Autolisp, to cutting and pasting C# code together, creating variables, and debugging it as necessary, til it worked. Using visual lisp with the COM helped me understand a little bit about using namespaces, which in Lisp I'd use to invoke methods.  With C# I know I have to start transactions. I know I have to pick an object, then define it as something else, then define that as something else to use it how I want but I don't know why.  As you can see I don't even know the appropriate terms.  I know visual lisp well, some visual basic as needed to create various excel forms, active script for company flash websites, and java for html sites so I can look at the c# code and it's almost like looking through muddy glasses... can make out what I am looking at...but can really see the details clearly.  I know ZERO coding terms. So when someone in C# talks about classes, and methods, and namespaces, etc. or whatever for c# I don't even know what they are talking about.  I haven't even looked through the tutorials... I skipped them.  Obviously the first thing every programmer here will do is tell me to go back and figure that stuff out...  I get incredibaly board with "hello world" and basic functions... and would never make it through... lol 

As far as them helping, I understand that.


I'd suggest explaining what you want to do, and you'll find you get directed on how to do it.  You can figure out the why as you go.

Keith™

  • Villiage Idiot
  • Seagull
  • Posts: 16899
  • Superior Stupidity at its best
Re: Third Routine - Working Progress
« Reply #20 on: February 05, 2013, 02:26:45 PM »
You misunderstood what I said ... certainly there is no dissention on the use of all caps, it is certainly difficult to read ... the dissention is on what constitutes the "correct" standard by which one should write code.

I think most of us have come to terms with the fact that there are two things that we all know better than to debate, one of which is Religion.



which is exactly why I gave up trying to discuss it here ... I think the only thing standard is how you spell "standard" .. but then, some folks might even question that :lmao:
Proud provider of opinion and arrogance since November 22, 2003 at 09:35:31 am
CadJockey Militia Field Marshal

Find me on https://parler.com @kblackie

Jeff H

  • Needs a day job
  • Posts: 6150
Re: Third Routine - Working Progress
« Reply #21 on: February 05, 2013, 02:39:24 PM »
DON"T LEAVE BC!!!


I completely understand it hard to express ideas where you missing knowledge of the core fundamentals.
Just hang in there & here.

Off to get back to work on some drawings where all text is CAPITALIZED. :D 

bchapman

  • Guest
Re: Third Routine - Working Progress
« Reply #22 on: February 05, 2013, 09:41:14 PM »
Didn't mean to give the impression I was going anywhere :/ but see how I did. This forum is great! :) with the best there seems to be in the related fields. I should have accepted Kerry's comment as constructive criticism, instead, being me, I read it "I prefer just not to read that garbage"... paraphrased in my own words lol... I believe that wasn't Kerry's intention... All of you continue to provide great advice that helps me get where I hope to be :) I really do appreciate it....  Thanks!

Kean

  • Newt
  • Posts: 48
Re: Third Routine - Working Progress
« Reply #23 on: February 07, 2013, 02:10:29 PM »
Kean's blog is great for seeing examples of how to use the very complicated managed API...

Thank you - that's really what it's there for.

... it is not a good place to learn a programming language like C#, because Kean's code routinely exhibits examples of poor coding.

"Routinely" is a bit strong - I prefer "occasionally". :-)

Just to state my position on this... my primary goals for the blog are to create clear code that works correctly. Now there may be optimizations that can be done to tweak extra performance out of certain routines - and that's especially true when I'm playing around with features such as LINQ, which I haven't used heavily - but my personal choice is to cover more topics rather than fewer topics with perfectly optimal code.

It's great that The Swamp - and Code Project / Stack Overflow, which I do my best to use to get as close to optimal efficiency in my code as time permits - exist to help people go that extra mile. I don't pretend in any way to compete with these resources - that's not my intention, even if I were arrogant enough to think I had the capability & capacity to do so.

Oh yes, and I do miss the odd AutoCAD API or feature that could do something more efficiently too, of course. It's a broad API and no-one knows (let alone remembers) it perfectly. But if you call me on it, I'll update the problematic post and thank you for your help.

Kean

bchapman

  • Guest
Re: Third Routine - Working Progress
« Reply #24 on: February 07, 2013, 03:27:32 PM »
lol

dgorsman

  • Water Moccasin
  • Posts: 2437
Re: Third Routine - Working Progress
« Reply #25 on: February 07, 2013, 04:27:06 PM »
Knowing the basics of object-oriented programming (classes,methods, properties, static/instance objects, exceptions and handling, and to a lesser extent things like inheritance, abstract/sealed/override) are essential.  Its boring, and repetitive, and takes a lot of work to get it straight, but like most things along those lines the payoff is worth it.  Trying to back into the subject through AutoCAD will raise a lot of questions of "Why do that?" or "Thats pretty vague", or "I don't understand when you say XXXX".  Like when you are asking why define this, then redefine as that, then redefine as something else - this may simply be a matter of a line being an entity being an object, but an object not necessarily being an entity, which is not necessarily a line (inheritance).

Plus, the basics are common across a lot of different samples in VB.NET, C#, C++, along with the host of support namespaces in dotNET like System.XML and System.Data.  A strong base allows you to figure out how to implement somethng even if its not exactly what you are looking for.
If you are going to fly by the seat of your pants, expect friction burns.

try {GreatPower;}
   catch (notResponsible)
      {NextTime(PlanAhead);}
   finally
      {MasterBasics;}

TheMaster

  • Guest
Re: Third Routine - Working Progress
« Reply #26 on: February 07, 2013, 04:49:11 PM »
Kean's blog is great for seeing examples of how to use the very complicated managed API...

Thank you - that's really what it's there for.

... it is not a good place to learn a programming language like C#, because Kean's code routinely exhibits examples of poor coding.

"Routinely" is a bit strong - I prefer "occasionally". :-)

Hi Kean.

I don't bother to visit often, but whenever I do and see code, there's always something that sticks out like a sore thumb. :laugh:

And how's this for occasionally - I just put a comment on your post about stripping XData from entities created by OFFSET, but was kind enough to not lambaste you about the wasteful practice of full-time handling of both the commandWillStart and the three command-ending events, when in reality, you only have to handle the former, and add the handlers for the latter from the handler of the former, only when the command that's starting is a command of interest (along with having the end-command handlers remove themselves from their respective events, when they fire).


Quote

Just to state my position on this... my primary goals for the blog are to create clear code that works correctly. Now there may be optimizations that can be done to tweak extra performance out of certain routines - and that's especially true when I'm playing around with features such as LINQ, which I haven't used heavily - but my personal choice is to cover more topics rather than fewer topics with perfectly optimal code.

It's great that The Swamp - and Code Project / Stack Overflow, which I do my best to use to get as close to optimal efficiency in my code as time permits - exist to help people go that extra mile. I don't pretend in any way to compete with these resources - that's not my intention, even if I were arrogant enough to think I had the capability & capacity to do so.

Oh yes, and I do miss the odd AutoCAD API or feature that could do something more efficiently too, of course. It's a broad API and no-one knows (let alone remembers) it perfectly. But if you call me on it, I'll update the problematic post and thank you for your help.

Kean

And just for fun, here's my take on how to deal with stripping xdata from entities in the OFFSET command, written in about 7 minutes, using mostly reusable classes that I routinely use for lots of things. No time for comments, and that'd take all the fun out of it, but please do give it a good looking over. I hope it proves enlightening.

Code - C#: [Select]
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Linq;
  4. using System.Text;
  5. using Autodesk.AutoCAD.DatabaseServices;
  6. using Autodesk.AutoCAD.Runtime;
  7. using System.ComponentModel;
  8.  
  9. /// Quick/dirty - strip xdata from entities created by
  10. /// the OFFSET command, in this example uses the XDATA
  11. /// appname "MYXDATA"
  12.  
  13. namespace Autodesk.AutoCAD.ApplicationServices.MyExtensions
  14. {
  15.    public class MyApplication : IExtensionApplication
  16.    {
  17.       public void Initialize()
  18.       {
  19.          OffsetCommandObserver.Inititlize();
  20.       }
  21.  
  22.       public void Terminate()
  23.       {
  24.       }
  25.    }
  26.    
  27.    public abstract class XDataManagerOverrule : ObjectOverrule
  28.    {
  29.       string appname = null;
  30.       TypedValue[] empty = null;
  31.       Document doc = null;
  32.       Database db = null;
  33.  
  34.       public XDataManagerOverrule( Document doc, string appname )
  35.       {
  36.          this.appname = appname;
  37.          this.doc = doc;
  38.          this.db = doc.Database;
  39.          empty = new TypedValue[] { new TypedValue( 1001, appname ) };
  40.          AddOverrule( RXClass.GetClass( typeof( Entity ) ), this, true );
  41.          SetXDataFilter( appname );
  42.       }
  43.  
  44.       public override void Close( DBObject dbObject )
  45.       {
  46.          if( dbObject.IsNewObject && dbObject.IsWriteEnabled && dbObject.Database == db )
  47.          {
  48.             using( ResultBuffer rb = dbObject.GetXDataForApplication( appname ) )
  49.             {
  50.                if( rb != null )
  51.                {
  52.                   UpdateXData( dbObject, rb );
  53.                }
  54.             }
  55.          }
  56.          base.Close( dbObject );
  57.       }
  58.  
  59.       protected virtual void UpdateXData( DBObject dbObject, ResultBuffer rb )
  60.       {
  61.       }
  62.  
  63.       bool disposed = false;
  64.  
  65.       protected override void Dispose( bool disposing )
  66.       {
  67.          if( disposing && ! disposed )
  68.             RemoveOverrule( RXClass.GetClass( typeof( Entity ) ), this );
  69.          disposed = true;
  70.          base.Dispose( disposing );
  71.       }
  72.    }
  73.  
  74.    /// <summary>
  75.    /// Avoids full-time handling of end-command events;
  76.    /// </summary>
  77.    
  78.    public abstract class CommandObserver : IDisposable
  79.    {
  80.       bool disposed = false;
  81.       Document doc = null;
  82.       bool handled = false;
  83.  
  84.       public CommandObserver( Document doc )
  85.       {
  86.          if( doc == null )
  87.             throw new ArgumentNullException( "doc" );
  88.          this.doc = doc;
  89.          this.doc.CommandWillStart += commandWillStart;
  90.       }
  91.  
  92.       public enum State
  93.       {
  94.          Starting = 0,
  95.          Ended = 1,
  96.          Cancelled = 2,
  97.          Failed = 3
  98.       }
  99.  
  100.       public Document Document
  101.       {
  102.          get
  103.          {
  104.             return this.doc;
  105.          }
  106.       }
  107.  
  108.       void commandWillStart( object sender, CommandEventArgs e )
  109.       {
  110.          if( OnCommandStarting( e.GlobalCommandName ) )
  111.          {
  112.             AddEndHandlers();
  113.          }
  114.       }
  115.  
  116.       void AddEndHandlers()
  117.       {
  118.          if( !this.handled )
  119.          {
  120.             doc.CommandEnded += doc_CommandEnded;
  121.             doc.CommandFailed += doc_CommandFailed;
  122.             doc.CommandCancelled += doc_CommandCancelled;
  123.             this.handled = true;
  124.          }
  125.       }
  126.  
  127.       void RemoveEndHandlers()
  128.       {
  129.          if( this.handled )
  130.          {
  131.             doc.CommandEnded -= doc_CommandEnded;
  132.             doc.CommandFailed -= doc_CommandFailed;
  133.             doc.CommandCancelled -= doc_CommandCancelled;
  134.             this.handled = false;
  135.          }
  136.       }
  137.  
  138.       /// Overrides should return true to be notified
  139.       /// when a command ends (otherwise, there is no
  140.       /// end-of-command notification).
  141.      
  142.       protected virtual bool OnCommandStarting( string name )
  143.       {
  144.          return false;
  145.       }
  146.  
  147.       protected virtual void OnCommandEnded( string name, State state )
  148.       {
  149.       }
  150.  
  151.       void doc_CommandCancelled( object sender, CommandEventArgs e )
  152.       {
  153.          RemoveEndHandlers();
  154.          OnCommandEnded( e.GlobalCommandName, State.Cancelled );
  155.       }
  156.  
  157.       void doc_CommandFailed( object sender, CommandEventArgs e )
  158.       {
  159.          RemoveEndHandlers();
  160.          OnCommandEnded( e.GlobalCommandName, State.Failed );
  161.       }
  162.  
  163.       void doc_CommandEnded( object sender, CommandEventArgs e )
  164.       {
  165.          RemoveEndHandlers();
  166.          OnCommandEnded( e.GlobalCommandName, State.Ended );
  167.       }
  168.  
  169.       protected virtual void Dispose( bool disposing )
  170.       {
  171.          if( !disposed )
  172.          {
  173.             doc.CommandWillStart -= this.commandWillStart;
  174.             RemoveEndHandlers();
  175.             disposed = true;
  176.          }
  177.       }
  178.  
  179.       public void Dispose()
  180.       {
  181.          Dispose( true );
  182.       }
  183.    }
  184.  
  185.    public class OffsetCommandObserver : CommandObserver
  186.    {
  187.       OffsetXDataOverrule overrule = null;
  188.       static DocData<OffsetCommandObserver> manager = null;
  189.  
  190.       public static void Inititlize()
  191.       {
  192.          // Dummy method to invoke static c'tor
  193.       }
  194.  
  195.       static OffsetCommandObserver()
  196.       {
  197.          manager = new DocData<OffsetCommandObserver>(
  198.                            doc => new OffsetCommandObserver( doc ) );
  199.       }
  200.  
  201.       public OffsetCommandObserver( Document doc )
  202.          : base( doc )
  203.       {
  204.       }
  205.  
  206.       protected override bool OnCommandStarting( string name )
  207.       {
  208.          if( name.Equals( "OFFSET", StringComparison.OrdinalIgnoreCase ) )
  209.          {
  210.             overrule = new OffsetXDataOverrule( this.Document, "MYXDATA" );
  211.             return true;
  212.          }
  213.          return false;
  214.       }
  215.  
  216.       protected override void OnCommandEnded( string name, State state )
  217.       {
  218.          if( overrule != null )
  219.          {
  220.             overrule.Dispose();
  221.             overrule = null;
  222.          }
  223.       }
  224.  
  225.       class OffsetXDataOverrule : XDataManagerOverrule
  226.       {
  227.          TypedValue[] empty = null;
  228.          public OffsetXDataOverrule( Document doc, string appname )
  229.             : base( doc, appname )
  230.          {
  231.             empty = new TypedValue[] { new TypedValue( 1001, appname ) };
  232.          }
  233.  
  234.          protected override void UpdateXData( DBObject dbObject, ResultBuffer rb )
  235.          {
  236.             using( ResultBuffer buffer = new ResultBuffer( empty ) )
  237.             {
  238.                dbObject.XData = buffer;
  239.             }
  240.          }
  241.       }
  242.    }
  243.  
  244.    public class DocData<T>
  245.    {
  246.       static Type key = typeof( T );
  247.       Func<Document, T> factory = null;
  248.  
  249.       public DocData( Func<Document, T> factory )
  250.       {
  251.          this.factory = factory;
  252.          DocumentCollection docs = Application.DocumentManager;
  253.          foreach( Document doc in docs )
  254.          {
  255.             Add( doc );
  256.          }
  257.          docs.DocumentCreated += documentCreated;
  258.          docs.DocumentToBeDestroyed += documentToBeDestroyed;
  259.       }
  260.  
  261.       void documentToBeDestroyed( object sender, DocumentCollectionEventArgs e )
  262.       {
  263.          if( e.Document.UserData.ContainsKey( key ) )
  264.          {
  265.             IDisposable disposable = e.Document.UserData[key] as IDisposable;
  266.             if( disposable != null )
  267.                disposable.Dispose();
  268.          }
  269.       }
  270.  
  271.       void documentCreated( object sender, DocumentCollectionEventArgs e )
  272.       {
  273.          Add( e.Document );
  274.       }
  275.  
  276.       private void Add( Document document )
  277.       {
  278.          document.UserData[key] = factory( document );
  279.       }
  280.  
  281.    }
  282. }
  283.  
  284.  
« Last Edit: February 07, 2013, 08:00:39 PM by TT »

bchapman

  • Guest
Re: Third Routine - Working Progress
« Reply #27 on: February 07, 2013, 08:48:57 PM »
Geez...

Kerry

  • Mesozoic relic
  • Seagull
  • Posts: 11654
  • class keyThumper<T>:ILazy<T>
Re: Third Routine - Working Progress
« Reply #28 on: February 07, 2013, 08:55:20 PM »
< .. >  It's a broad API and no-one knows (let alone remembers) it perfectly. But if you call me on it, I'll update the problematic post and thank you for your help.

Kean

That sounds like a perfect reason to document the API  ..   :evil:

oh, wait, we've heard this before haven't we ..
kdub, kdub_nz in other timelines.
Perfection is not optional.
Everything will work just as you expect it to, unless your expectations are incorrect.
Discipline: None at all.

owenwengerd

  • Bull Frog
  • Posts: 451
Re: Third Routine - Working Progress
« Reply #29 on: February 07, 2013, 09:08:50 PM »
Tony & Kean, when I saw that post my reaction was that removing xdata this way is an awful solution. If the xdata is not wanted in the copy, then it should not be cloned in the first place. But I don't know off the top of my head how much access you have to cloning operations from the managed API, so I said nothing.