Author Topic: Resetting system variables  (Read 2862 times)

0 Members and 1 Guest are viewing this topic.

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8698
  • AKA Daniel
Resetting system variables
« on: February 22, 2009, 12:40:53 AM »
Just having a little fun

Code: [Select]
namespace ExecMethod
{
  using System;
  using System.Collections.Generic;
  using Autodesk.AutoCAD.DatabaseServices;
  using AcAp = Autodesk.AutoCAD.ApplicationServices;
  using SysVar = System.Collections.Generic.KeyValuePair<string, object>;

  public class SysVars
  {
    // Fields
    private Stack<SysVar> _varStack;

    public SysVars()
    {
      this._varStack = new Stack<SysVar>();
    }

    // Properties
    public Stack<SysVar> VarStack
    {
      get { return this._varStack; }
    }

    // Methods
    public void SetVar(string name, object value)
    {
      if (value == null)
      {
        throw new ArgumentNullException("Value");
      }
      object o = AcAp.Application.GetSystemVariable(name);
      AcAp.Application.SetSystemVariable(name, value);
      this._varStack.Push(new SysVar(name, o));
    }

    public SysVar Pop(bool set)
    {
      SysVar var = this._varStack.Pop();
      if (set)
      {
        AcAp.Application.SetSystemVariable(var.Key, var.Value);
      }
      return var;
    }

    public void PopAll(bool set)
    {
      if (set)
      {
        foreach (SysVar var in this._varStack)
        {
            AcAp.Application.SetSystemVariable(var.Key, var.Value);
        }
      }
      this._varStack.Clear();
    }
  }
}

and then

Code: [Select]
    [CommandMethod("doit")]
    public static void doit()
    {
      SysVars vars = new SysVars();
      try
      {
        vars.SetVar("CLAYER", "0");
        //do stuff
      }
      catch
      {
         //catch stuff
      }
      finally
      {
        vars.PopAll(true); //reset the vars
      }
    }

ahlzl

  • Guest
Re: Resetting system variables
« Reply #1 on: February 22, 2009, 04:54:33 AM »
my English is very poor!
Daniel is my idol!Thank you help me on many occasions.You are now in Shanghai, it?

TonyT

  • Guest
Re: Resetting system variables
« Reply #2 on: February 22, 2009, 05:28:02 AM »
Just having a little fun



Hi Dan. Cool.

I've yet to come across a situation where I needed a stack-based
approach for that.

I've been using various iterations of this for years:

Code: [Select]

using System;
using System.Collections.Generic;
using System.Text;
using System.Collections;
using Autodesk.AutoCAD.ApplicationServices;
using Acad = Autodesk.AutoCAD.ApplicationServices.Application;

namespace CaddZone.AutoCAD.ApplicationServices
{
   /// example:
  
   public class Example
   {
      public static void someCommandMethod()
      {
         using( SysVarCache sysvars = new SysVarCache() )
         {
            sysvars["CMDECHO"] = 0;
            sysvars["BLIPMODE"] = 0;
            sysvars["OSMODE"] = 0;

            // Do stuff here

         } // previous values of changed sysvars are restored here

      }
   }

   public sealed class SysVarCache : IEnumerable<KeyValuePair<string, object>>, IDisposable
   {
      private Dictionary<string, object> items = new Dictionary<string, object>( StringComparer.InvariantCultureIgnoreCase );
      private bool changing = false;

      public SysVarCache()
      {
         Acad.SystemVariableChanged += OnSystemVariableChanged;
      }

      // Monitor changes made to system variables by user, so that
      // if they change one that's been saved, (e.g., toggles an
      // item on the status bar or what have you), the saved value
      // gets discarded, preserving the user's new setting.

      void OnSystemVariableChanged( object sender, SystemVariableChangedEventArgs e )
      {
         if( !changing && e.Changed && items.ContainsKey( e.Name ) )
            items.Remove( e.Name );
      }

      public void Restore()
      {
         Restore( true );
      }

      public void Restore( bool clear )
      {
         Acad.SystemVariableChanged -= OnSystemVariableChanged;
         try
         {
            foreach( KeyValuePair<string, object> entry in items )
            {
               object oval = Acad.GetSystemVariable( entry.Key );
               if( !object.Equals( oval, entry.Value ) )
                  Acad.SetSystemVariable( entry.Key, entry.Value );
            }
         }
         finally
         {
            Acad.SystemVariableChanged += OnSystemVariableChanged;
         }
         if( clear )
            items.Clear();
      }

      public bool Restore( string name )
      {
         object saved = null;
         if( items.TryGetValue( name, out saved ) && saved != null )
         {
            object oval = Acad.GetSystemVariable( name );
            if( !object.Equals( oval, saved ) )
            {
               this.changing = true;
               try
               {
                  Acad.SetSystemVariable( name, saved );
               }
               finally
               {
                  this.changing = false;
               }
            }
         }
         return items.Remove( name );
      }

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

      public int Count
      {
         get
         {
            return items.Count;
         }
      }

      private void Set( string name, object newval )
      {
         if( newval == null )
            throw new ArgumentNullException( "newval" );
         if( string.IsNullOrEmpty( name ) )
            throw new ArgumentNullException( "name" );
         object oldval = Acad.GetSystemVariable( name );
         if( !object.Equals( oldval, newval ) )
         {
            this.changing = true;
            try
            {
               Acad.SetSystemVariable( name, newval );
               if( !items.ContainsKey( name ) )
                  items.Add( name, oldval );
            }
            finally
            {
               this.changing = false;
            }
         }
      }

      // e.g., SetAll( 0, "CMDECHO", "BLIPMODE", "OSMODE" );

      public void SetAll( object value, params string[] names )
      {
         if( names == null )
            throw new ArgumentNullException( "names" );
         Acad.SystemVariableChanged -= OnSystemVariableChanged;
         try
         {
            foreach( string name in names )
            {
               Set( name, value );
            }
         }
         finally
         {
            Acad.SystemVariableChanged += OnSystemVariableChanged;
         }
      }

      // Saves current value without changing it.
      public void Save( params string[] names )
      {
         if( names != null )
         {
            foreach( string name in names )
            {
               if( !items.ContainsKey( name ) )
                  items.Add( name, Acad.GetSystemVariable( name ) );
            }
         }
      }

      public object this[string name]
      {
         get
         {
            if( items.ContainsKey( name ) )
               return items[name];
            else
               return Acad.GetSystemVariable( name );
         }
         set
         {
            Set( name, value );
         }
      }

      public void Dispose()
      {
         Dispose( true );
      }

      private void Dispose( bool disposing )
      {
         if( disposing )
         {
            Restore();
            Acad.SystemVariableChanged -= OnSystemVariableChanged;
            GC.SuppressFinalize( this );
         }
         disposed = true;
      }

      private bool disposed = false;

      ~SysVarCache()
      {
         if( !disposed )
         {
            Dispose( false );
         }
      }

      public IEnumerator<KeyValuePair<string, object>> GetEnumerator()
      {
         return items.GetEnumerator();
      }

      public bool Contains( string key )
      {
         return items.ContainsKey( key );
      }

      public ICollection<string> Keys
      {
         get
         {
            return items.Keys;
         }
      }

      // Removes saved value without restoring
      public bool Remove( string key )
      {
         return items.Remove( key );
      }

      public ICollection<object> Values
      {
         get
         {
            return items.Values;
         }
      }

      System.Collections.IEnumerator System.Collections.IEnumerable.GetEnumerator()
      {
         return items.GetEnumerator();
      }

   }


}


It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8698
  • AKA Daniel
Re: Resetting system variables
« Reply #3 on: February 22, 2009, 09:03:51 AM »
my English is very poor!
Daniel is my idol!Thank you help me on many occasions.You are now in Shanghai, it?

Not yet, my flight is Thursday morning, Detroit ->Tokyo->Shanghai, 14 hours flying time  :-o

It's Alive!

  • Retired
  • Needs a day job
  • Posts: 8698
  • AKA Daniel
Re: Resetting system variables
« Reply #4 on: February 22, 2009, 09:05:45 AM »
Just having a little fun



Hi Dan. Cool.

I've yet to come across a situation where I needed a stack-based
approach for that.

I've been using various iterations of this for years:

....

Wow Tony, that’s really nice, especially the reactor.   8-)
The idea of using a stack came from looking at SdSysVarStack in ArxDbg.
Thanks for sharing!