See the top rated post in this thread. Click here

Page 2 of 2 FirstFirst 12
Results 11 to 19 of 19

Thread: .NET Return Conversion to TypedValue

  1. #11
    Certifiable AUGI Addict
    Join Date
    2015-11
    Location
    Jo'burg SA
    Posts
    4,512
    Login to Give a bone
    0

    Default Re: .NET Return Conversion to TypedValue

    Oh stupid me ... I really screwed up the enumerable types. It would convert all nested enumerables to strings of ResultBuffers . So ignore my previous codes. Also, notice I've finally figured out what went wrong with the colour coding (Augi keeps on turning my WYSIWYG editor off - thus all pastes are unformatted text), yet another nice thing SharpDevelop does which VS doesn't: Copying code places it on the clipboard together with its formatting and colours!

    Here's the fixed version in C#
    Code:
    public static class ObjectToTypedValue {
        #region Public Converter functions
        //  Blank (like returned by princ)
        public static object Convert() {
            return new TypedValue((int)LispDataType.None);
        }
        
        // Integers (32 bit or other)
        public static object Convert(int value) {
            return new TypedValue((int)LispDataType.Text, value);
        }
        
        // 16 bit integers
        public static object Convert(Int16 value) {
            return new TypedValue((int)LispDataType.Int16, value);
        }
        
        // Doubles
        public static object Convert(double value) {
            return new TypedValue((int)LispDataType.Double, value);
        }
        
        // Strings
        public static object Convert(string value) {
            return new TypedValue((int)LispDataType.Text, value);
        }
        
        // Booleans
        public static object Convert(bool value) {
            if ((bool) value)
                return new TypedValue((int)LispDataType.T_atom);
            return  new TypedValue((int)LispDataType.Nil);
        }
        
        // 2d Points
        public static object Convert(Point2d value) {
            return new TypedValue((int)LispDataType.Point2d, value);
        }
        
        // 3d Points
        public static object Convert(Point3d value) {
            return new TypedValue((int)LispDataType.Point3d, value);
        }
        
        // Catch all other objects including null
        public static object Convert(object value) {
            if (value == null)
                return new TypedValue((int)LispDataType.Nil);
            if (value is IEnumerable) {
                ResultBuffer rb = new ResultBuffer();
                AddToRB(rb, value);
                return rb;
            }
            return Convert(value as string);
        }
        #endregion
        
        #region Private helper functions for enumerable types
        // Unhandled objects in enumerables
        private static void AddToRB(ResultBuffer rb, object value) {
            rb.Add(Convert(value));
        }
        
        // Tuples to dotted pairs
        private static void AddToRB(ResultBuffer rb, Tuple<object, object> value) {
            rb.Add(new TypedValue((int)LispDataType.DottedPair));
            AddToRB(rb, value.Item1);
            AddToRB(rb, value.Item2);
            rb.Add(new TypedValue((int)LispDataType.ListEnd));
        }
        
        // Dictionary entry to association pair
        private static void AddToRB(ResultBuffer rb, DictionaryEntry value) {
            IEnumerable en = value.Value as IEnumerable;
            if (en == null) {
                rb.Add(new TypedValue((int)LispDataType.DottedPair));
                AddToRB(rb, value.Key);
                AddToRB(rb, value.Value);
            } else {
                rb.Add(new TypedValue((int)LispDataType.ListBegin));
                rb.Add(Convert(value.Key));
                foreach (object element in en) {
                    AddToRB(rb, element);
                }
            }
            rb.Add(new TypedValue((int)LispDataType.ListEnd));
        }
        
        // Hash tables to association lists
        private static void AddToRB(ResultBuffer rb, IDictionary value) {
            rb.Add(new TypedValue((int)LispDataType.ListBegin));
            IDictionaryEnumerator en = value.GetEnumerator();
            while (en.MoveNext()) {
                AddToRB(rb, en.Current);
            }
            rb.Add(new TypedValue((int)LispDataType.ListEnd));
        }
        
        // Lists, collections and arrays to Lisp Lists
        private static void AddToRB(ResultBuffer rb, IEnumerable value) {
            rb.Add(new TypedValue((int)LispDataType.ListBegin));
            foreach (object element in value) {
                AddToRB(rb, element);
            }
            rb.Add(new TypedValue((int)LispDataType.ListEnd));
        }
        #endregion
    }

  2. #12
    Certifiable AUGI Addict
    Join Date
    2015-11
    Location
    Jo'burg SA
    Posts
    4,512
    Login to Give a bone
    0

    Default Re: .NET Return Conversion to TypedValue

    And the VB.Net version
    Code:
    Public NotInheritable Class ObjectToTypedValue
        Private Sub New()
        End Sub
    
        #Region "Public Converter functions"
        '  Blank (like returned by princ)
        Public Shared Function Convert() As Object
            Return New TypedValue(CInt(LispDataType.None))
        End Function
    
        ' Integers (32 bit or other)
        Public Shared Function Convert(value As Integer) As Object
            Return New TypedValue(CInt(LispDataType.Text), value)
        End Function
    
        ' 16 bit integers
        Public Shared Function Convert(value As Int16) As Object
            Return New TypedValue(CInt(LispDataType.Int16), value)
        End Function
    
        ' Doubles
        Public Shared Function Convert(value As Double) As Object
            Return New TypedValue(CInt(LispDataType.[Double]), value)
        End Function
    
        ' Strings
        Public Shared Function Convert(value As String) As Object
            Return New TypedValue(CInt(LispDataType.Text), value)
        End Function
    
        ' Booleans
        Public Shared Function Convert(value As Boolean) As Object
            If CBool(value) Then
                Return New TypedValue(CInt(LispDataType.T_atom))
            End If
            Return New TypedValue(CInt(LispDataType.Nil))
        End Function
    
        ' 2d Points
        Public Shared Function Convert(value As Point2d) As Object
            Return New TypedValue(CInt(LispDataType.Point2d), value)
        End Function
    
        ' 3d Points
        Public Shared Function Convert(value As Point3d) As Object
            Return New TypedValue(CInt(LispDataType.Point3d), value)
        End Function
    
        ' Catch all other objects including null
        Public Shared Function Convert(value As Object) As Object
            If value Is Nothing Then
                Return New TypedValue(CInt(LispDataType.Nil))
            End If
            If TypeOf value Is IEnumerable Then
                Dim rb As New ResultBuffer()
                AddToRB(rb, value)
                Return rb
            End If
            Return Convert(TryCast(value, String))
        End Function
        #End Region
    
        #Region "Private helper functions for enumerable types"
        ' Unhandled objects in enumerables
        Private Shared Sub AddToRB(rb As ResultBuffer, value As Object)
            rb.Add(Convert(value))
        End Sub
    
        ' Tuples to dotted pairs
        Private Shared Sub AddToRB(rb As ResultBuffer, value As Tuple(Of Object, Object))
            rb.Add(New TypedValue(CInt(LispDataType.DottedPair)))
            AddToRB(rb, value.Item1)
            AddToRB(rb, value.Item2)
            rb.Add(New TypedValue(CInt(LispDataType.ListEnd)))
        End Sub
    
        ' Dictionary entry to association pair
        Private Shared Sub AddToRB(rb As ResultBuffer, value As DictionaryEntry)
            Dim en As IEnumerable = TryCast(value.Value, IEnumerable)
            If en Is Nothing Then
                rb.Add(New TypedValue(CInt(LispDataType.DottedPair)))
                AddToRB(rb, value.Key)
                AddToRB(rb, value.Value)
            Else
                rb.Add(New TypedValue(CInt(LispDataType.ListBegin)))
                rb.Add(Convert(value.Key))
                For Each element As Object In en
                    AddToRB(rb, element)
                Next
            End If
            rb.Add(New TypedValue(CInt(LispDataType.ListEnd)))
        End Sub
    
        ' Hash tables to association lists
        Private Shared Sub AddToRB(rb As ResultBuffer, value As IDictionary)
            rb.Add(New TypedValue(CInt(LispDataType.ListBegin)))
            Dim en As IDictionaryEnumerator = value.GetEnumerator()
            While en.MoveNext()
                AddToRB(rb, en.Current)
            End While
            rb.Add(New TypedValue(CInt(LispDataType.ListEnd)))
        End Sub
    
        ' Lists, collections and arrays to Lisp Lists
        Private Shared Sub AddToRB(rb As ResultBuffer, value As IEnumerable)
            rb.Add(New TypedValue(CInt(LispDataType.ListBegin)))
            For Each element As Object In value
                AddToRB(rb, element)
            Next
            rb.Add(New TypedValue(CInt(LispDataType.ListEnd)))
        End Sub
        #End Region
    End Class

  3. #13
    Member
    Join Date
    2009-11
    Posts
    5
    Login to Give a bone
    0

    Default Re: .NET Return Conversion to TypedValue

    hi everyone,
    this code does exctly what i need,
    but there is no usage sample, and by the way i do, i've a System.StackOverflowException error
    This code is complicated for my level with surcharge and something like recursivity,
    and when i make a step to step debugging, it seems to turn into an infinite loop.
    My sample is just designed to show interactions between lisp and .net, so it's really silly.

    so here my code :

    Code:
    'for sample, definy myvar like following :
    '(setq myvar "myValue")
    'then answer 'myvar' at the prompt
    
            <CommandMethod("EvalLispSymbol")> _
            Public Sub EvalLispSymbol()
                Dim doc As Document = Application.DocumentManager.MdiActiveDocument
                Dim ed As Editor = doc.Editor
                Dim strEval As String = ed.GetString("Name of the lisp symbol ?").StringResult
    
                ed.WriteMessage(vbLf & "NetGetLispSym " & strEval & " :")
                ' get the 'lst2' variable value
                'Dim output As ResultBuffer = AcadExtensions.LispExtensions.NetGetLispSym(strEval)
                Dim output As Object = doc.GetLispSymbol(strEval)
    			Dim Rboutput As ResultBuffer = ObjectToTypedValue.Convert(output)
                
                ' print the value to the commande line
                ed.WriteMessage(vbLf & "Value of  the lisp symbol '" & strEval & " as resultBuffer :")
                For Each tv As TypedValue In Rboutput
                    ed.WriteMessage(vbLf & "Type: {0}" & vbTab & "Value: {1}", tv.TypeCode, tv.Value)
                Next
                           
                ed.WriteMessage(vbLf & "Now make a !lst to verify that lst = " & strEval & " :")
                doc.SetLispSymbol("lst", output)
    			
            End Sub
    gégé

  4. #14
    Certifiable AUGI Addict
    Join Date
    2015-11
    Location
    Jo'burg SA
    Posts
    4,512
    Login to Give a bone
    0

    Default Re: .NET Return Conversion to TypedValue

    It seems the issue is that a string type is considered an IEnumerable. Thus that code generates an infinite recursive loop - i.e. a stack frame overflow error. Very strange that I didn't pick it up before, I've not heard that it was changed recently. The fix would be to check for string types before checking for enumerable types. Something like this:

    C#
    Code:
    // Catch all other objects including null
    public static object Convert(object value)
    {
        if (value == null)
            return new TypedValue((int)LispDataType.Nil);
        if (value is string)
        {
            return Convert(value as string);
        }
        if (value is IEnumerable)
        {
            ResultBuffer rb = new ResultBuffer();
            AddToRB(rb, value);
            return rb;
        }
        return value;
    }
    And converted to VB.NET using SnippetConverter
    Code:
    ' Catch all other objects including null
    Public Shared Function Convert(value As Object) As Object
    	If value Is Nothing Then
    		Return New TypedValue(CInt(LispDataType.Nil))
    	End If
    	If TypeOf value Is String Then
    		Return Convert(TryCast(value, String))
    	End If
    	If TypeOf value Is IEnumerable Then
    		Dim rb As New ResultBuffer()
    		AddToRB(rb, value)
    		Return rb
    	End If
    	Return value
    End Function

  5. #15
    Member
    Join Date
    2009-11
    Posts
    5
    Login to Give a bone
    0

    Default Re: .NET Return Conversion to TypedValue

    Hi,
    thanks for the quick reply,
    now there is no more loop, but i've always a problem to correctly use your conversion:
    i've an error because the conversion return an object else to a result-buffer:
    What is wrong with that :
    Code:
    Dim Rboutput As ResultBuffer = ObjectToTypedValue.Convert(output)
    Thanks,
    Gégé

  6. #16
    Certifiable AUGI Addict
    Join Date
    2015-11
    Location
    Jo'burg SA
    Posts
    4,512
    Login to Give a bone
    0

    Default Re: .NET Return Conversion to TypedValue

    It always returns a TypedValue. If the object input into it is a collection of objects (i.e. an IEnumerable), that TypedValue wraps around a result buffer of TypedValues (one each for each item in the collection).

    If it always returns a ResultBuffer, then it will work wrong: If that was the case and you sent it (say) a number, the result buffer would thus turn it into a list with a number inside it. I.e. it would be like you did the following:
    Code:
    (setq var 100)
    !var
    (100) ;Instead of just 100

  7. #17
    Member
    Join Date
    2009-11
    Posts
    5
    Login to Give a bone
    0

    Default Re: .NET Return Conversion to TypedValue

    hello,
    so i've changed my usage of your class,
    no i check what it returns :
    this wor fine with
    (setq myvar "mystringvalue")
    Code:
    Dim strEval As String =  "myvar"
                Dim output As Object = doc.GetLispSymbol(strEval)
                Dim ResOTTV As Object = ObjectToTypedValue.Convert(output)
                Dim Rboutput As New ResultBuffer
    
                If TypeOf ResOTTV Is TypedValue Then
                    Rboutput.Add(ResOTTV)
    
                ElseIf TypeOf ResOTTV Is ResultBuffer Then
                    Rboutput = ResOTTV
    
                Else
                    Rboutput = Nothing
    
                End If
    But with (setq myvar '(1 1) )
    output type is point2d
    but the class ObjectToTypedValue does'nt intercept it as point2d:
    only
    Code:
     ' Catch all other objects including null
        Public Shared Function Convert(value As Object) As Object
    is evaluated, so it returns nothing

    My deserve is to prepare a template Vb project inclunding everythings needed to work with LIsp>NET>lisp
    so your class is realy usefull
    Gégé

  8. #18
    Certifiable AUGI Addict
    Join Date
    2015-11
    Location
    Jo'burg SA
    Posts
    4,512
    Login to Give a bone
    0

    Default Re: .NET Return Conversion to TypedValue

    A few items to note here:
    1. The intent of this is to convert a DotNet type into a TypedValue ready for sending back to Lisp, not to take what lisp gives you and convert it back to what lisp expects. I.e. reading from the lisp symbol, you get it converted to DotNet types only if it converts to a basic DotNet type. If the symbol contains something like a list, then the GetLispSymbol actually gives you a TypedValue - i.e. again, you're trying to convert a typedvalue into a typedvalue - makes no sense.
    2. The library is intended to work on operator overloads. This won't work if you simply box all the values into an object. If you want that, then look at Peter's original code - though as I stated in the 2nd post, it would be more efficient to select on TypeCode instead of Type.
    3. My code is definitely just intended to show what can be done.
    4. Please be patient as I'm not very into DotNet for ACad anymore, rather more focused on Revit and C# than ACad and VB. So may make a few mistakes, miss some point in the VB codes, or forget something I only did a few years ago.


    However, looking through that I must say I'd definitely go with some form of combination between my codes and Peter's. The reason being that mine would only work well if your values are statically typed and not boxed. Peter's would work in all cases, just being a bit slower as it uses reflection to obtain the type of the boxed object.

  9. #19
    Member
    Join Date
    2009-11
    Posts
    5
    Login to Give a bone
    0

    Default Re: .NET Return Conversion to TypedValue

    Hi,
    i think i've made a big mismatch with (setq myvar '(1 1) ) !
    now i know it must work,
    so i 've to find a better sample for your class ...
    regards,
    Gégé
    Last edited by gegematic; 2015-10-15 at 06:29 AM.

Page 2 of 2 FirstFirst 12

Similar Threads

  1. Replies: 10
    Last Post: 2016-06-27, 12:04 AM
  2. RETURN TO LDD
    By Wish List System in forum Civil 3D Wish List
    Replies: 13
    Last Post: 2015-10-08, 03:40 PM
  3. Why does this return nil...
    By chris.mackay434411 in forum AutoLISP
    Replies: 7
    Last Post: 2013-11-26, 03:21 PM
  4. Field return Z value WITH conversion factor
    By Kernal_CAD_Monkey in forum AutoCAD Fields
    Replies: 3
    Last Post: 2012-11-09, 03:00 PM
  5. How do you create a Boxed Return or Cornice Return?
    By rgecy in forum Revit Architecture - General
    Replies: 7
    Last Post: 2004-05-20, 04:42 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •