How to Create an instance of ResultBuffer.

How to Create an instance of ResultBuffer.

MarkJamesRogolino
Advocate Advocate
2,793 Views
15 Replies
Message 1 of 16

How to Create an instance of ResultBuffer.

MarkJamesRogolino
Advocate
Advocate

Hello, everyone. Now I am making a small project .NET. There I should embed a JSON data into DWG file.

I thought it maybe possible to use Xrecord. Followings are my portion of code.

 

 

public class roomrule
{
        public Polyline pl;
        public double width;
        public double height;
        public ObjectId objid;
        public Handle hnd;
}
public void WriteToNOD()
{
	List<JsonItems> jsonlists = new List<JsonItems>();
	public static List<roomrule> aroomrule = new List<roomrule>();
	IEnumerable<roomrule> rmrulelst = aroomrule.Distinct();
	//I added some data to aroomrule already.
	foreach (roomrule wrule in rmrulelst)
        {
                jsonlists.Add(new JsonItems
                {
                    layer = "_Room",
                    OId = wrule.objid.ToString(),
                    width = wrule.width,
                    height = wrule.height,
                    hndle = wrule.hnd.ToString(),
                    projtype = (int)Plugin.projtypestate,
                });
         }
            try
            {
                using (Transaction trans = db.TransactionManager.StartTransaction())
                {                    
                    DBDictionary nod = (DBDictionary)trans.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForWrite);
                    Xrecord myXrecord = new Xrecord();
                    ResultBuffer resbuf = new ResultBuffer(new TypedValue((int)DxfCode.Text, jsonlists[0].layer), new TypedValue((int)DxfCode.Int64, jsonlists[0].OId),
                    new TypedValue((int)DxfCode.Int64, jsonlists[0].OId), new TypedValue((int)DxfCode.Int32,jsonlists[0].height),
                    new TypedValue((int)DxfCode.Int64,jsonlists[0].hndle),new TypedValue((int)DxfCode.Int32,jsonlists[0].projtype));
                    foreach(TypedValue tv in resbuf)
                    {
                        Application.ShowAlertDialog(
                                  "===== Now write: " + tv.TypeCode.ToString()
                                  + ". " + tv.Value.ToString());
                    }
                    myXrecord.Data = resbuf;
                    nod.SetAt("PrevalData", myXrecord);
                    trans.AddNewlyCreatedDBObject(myXrecord, true);                    
                    trans.Commit();
                }
            }
            catch (Exception e)
            {
                System.Diagnostics.Debug.Print(e.ToString());
            }
}

 

 
0 Likes
Accepted solutions (2)
2,794 Views
15 Replies
Replies (15)
Message 2 of 16

_gile
Consultant
Consultant

What is your question ?

 

Note it is a better practice to get or create your own dictionary(ies) in the NOD and add the xrecords to this dictionary then to directly add xrecords to the NOD.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 3 of 16

MarkJamesRogolino
Advocate
Advocate

Thanks _gile. You were kindly helping me. Can you tell me specifically how to implement it? Thank you again. 

0 Likes
Message 4 of 16

_gile
Consultant
Consultant

Sorry I can't help you. The code you posted is incomprehensible.
Where does this JsonItems type come from?
You create an empty list (aroomrule), then an IEnumerable<roomrule> (rmrulelst) by applying the Dinstinct method to the empty list, what do you expect to happen?
You then launch a foreach on this sequence, what do you expect to happen?

Please, if you want to get help, try to make an effort on your side not to post inconsistent code.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 5 of 16

MarkJamesRogolino
Advocate
Advocate

Hi, _gile. It is difficult to describe the process of putting values in all lists here, so I omitted that part. 

public class windowrule
    {
        public Polyline pl;
        public float width;
        public float height;
        public ObjectId objid;
        public Handle hnd;
    }

ResultBuffer resbuf = new ResultBuffer(new TypedValue((int)DxfCode.Text, jsonlists[0].layer), new TypedValue((int)DxfCode.Int64, jsonlists[0].OId),
                    new TypedValue((int)DxfCode.Int64, jsonlists[0].OId), new TypedValue((int)DxfCode.Int32,jsonlists[0].height),
                    new TypedValue((int)DxfCode.Int64,jsonlists[0].hndle),new TypedValue((int)DxfCode.Int32,jsonlists[0].projtype));
                  

 

How can I put an instance of this class(windowrule) into DBDictionary. In my previously posted code I get the values of jsonlists, but in the line of creating resbuf my function returns. I want example code for you. Thank you in advance.

0 Likes
Message 6 of 16

_gile
Consultant
Consultant

Some remarks

  • The 'roomrule' or 'windowrule' class should not have a Polyline field because you should never use DBObjects outside of the scope of the transaction use to get or create them. Use their ObjectId or Handle instead.
  • You should choose between ObjectId or Handle because you can get one from the other. Keep in mind that an ObjectId is unique per session and non persistent; a handle is unique per drawing and persistent between sessions (see this topic)
  • If you need to store more than one "JsonItems" in the NOD, you must have some key per item to be able differentiate the Xrecords.


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 7 of 16

_gile
Consultant
Consultant
Accepted solution

Here is an example of how to structure this process.
Do not simply copy/paste this code. Try to understand how it works a rewrite it to suit your needs instead.

 

A RoomRule structure

 

 

    public struct RoomRule
    {
        public double Width { get; set; }
        public double Height { get; set; }
        public ObjectId ObjectId { get; set; }
    }

 

 

 

A JsonItem class

EDIT: added a WriteToNod and CreateFromNod methods.

 

 

    public class JsonItem
    {
        // properties
        public string Layer { get; set; }
        public double Width { get; set; }
        public double Height { get; set; }
        public string Handle { get; set; }
        public int ProjType { get; set; }

        // constructors
        public JsonItem(RoomRule roomRule)
        {
            Layer = "_Room";
            Width = roomRule.Width;
            Height = roomRule.Height;
            Handle = roomRule.ObjectId.Handle.ToString();
            ProjType = Plugin.projtypestate;
        }

        public JsonItem(ResultBuffer resbuf)
        {
            if (resbuf != null)
            {
                var data = resbuf.AsArray();
                if (data.Length == 5)
                {
                    if (long.TryParse(
                        data[3].Value.ToString(),
                        System.Globalization.NumberStyles.HexNumber,
                        System.Globalization.CultureInfo.InvariantCulture,
                        out long longHandle))
                    {
                        var db = HostApplicationServices.WorkingDatabase;
                        var handle = new Handle(longHandle);
                        if (db.TryGetObjectId(new Handle(longHandle), out ObjectId id))
                        {
                            Layer = (string)data[0].Value;
                            Width = (double)data[1].Value;
                            Height = (double)data[2].Value;
                            Handle = handle.ToString();
                            ProjType = Convert.ToInt32(data[4].Value);
                        }
                    }
                }
            }
        }

        public ResultBuffer ToResultBuffer()
        {
            return new ResultBuffer(
                new TypedValue(1, Layer),
                new TypedValue(40, Width),
                new TypedValue(40, Height),
                new TypedValue(5, Handle),
                new TypedValue(71, ProjType));
        }

        public void WriteToNod(string key)
        {
            var db = HostApplicationServices.WorkingDatabase;
            using (var tr = db.TransactionManager.StartTransaction())
            {
                var Nod = (DBDictionary)tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead);

                // Get or create the GOLDHORSE dictionary
                DBDictionary goldhorseDict;
                if (Nod.Contains("GOLDHORSE"))
                {
                    goldhorseDict = (DBDictionary)tr.GetObject(Nod.GetAt("GOLDHORSE"), OpenMode.ForRead);
                }
                else
                {
                    tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForWrite);
                    goldhorseDict = new DBDictionary();
                    Nod.SetAt("GOLDHORSE", goldhorseDict);
                    tr.AddNewlyCreatedDBObject(goldhorseDict, true);
                }

                // Get or create an Xrecord in GOLDHORSE dictionary with the supplied key
                Xrecord xrec;
                if (goldhorseDict.Contains(key))
                {
                    xrec = (Xrecord)tr.GetObject(goldhorseDict.GetAt(key), OpenMode.ForWrite);
                }
                else
                {
                    tr.GetObject(Nod.GetAt("GOLDHORSE"), OpenMode.ForWrite);
                    xrec = new Xrecord();
                    goldhorseDict.SetAt(key, xrec);
                    tr.AddNewlyCreatedDBObject(xrec, true);
                }

                // Set the xrecord data
                xrec.Data = ToResultBuffer();
                tr.Commit();
            }
        }

        public static JsonItem CreateFromNod(string key)
        {
            var db = HostApplicationServices.WorkingDatabase;
            using (var tr = db.TransactionManager.StartTransaction())
            {
                var Nod = (DBDictionary)tr.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead);

                // Get the GOLDHORSE dictionary
                if (!Nod.Contains("GOLDHORSE"))
                    return null;
                var goldhorseDict = (DBDictionary)tr.GetObject(Nod.GetAt("GOLDHORSE"), OpenMode.ForRead);

                // Get the Xrecord in GOLDHORSE dictionary with the supplied key
                if (!goldhorseDict.Contains(key))
                    return null;
                var xrec = (Xrecord)tr.GetObject(goldhorseDict.GetAt(key), OpenMode.ForRead);

                // Get the xrecord data
                var data = xrec.Data;
                if (data == null) 
                    return null;

                return new JsonItem(data);
            }
        }
    }

 

 

 

 

 

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 8 of 16

MarkJamesRogolino
Advocate
Advocate

Yes, in fact I use this class to add ResultBuffer.

 

public class JsonItems
    {
        public string layer { get; set; }
        public string OId { get; set; }
        public double width { get; set; }
        public double height { get; set; }
        public string hndle { get; set; }
        public int projtype { get; set; }
    }

In my opinion first parameter was mistake in this code.

new TypedValue((int)DxfCode.Text, jsonlists[0].layer)

This code works.

myXrecord.Data = new ResultBuffer(
              new TypedValue((int)DxfCode.Int16, 1234),
              new TypedValue((int)DxfCode.Text,
                              "This drawing has been processed"));

What is the main cause? I think you know why.

 

0 Likes
Message 9 of 16

_gile
Consultant
Consultant

Again it is impossible for me to diagnose with the informations you provide which are both incomplete and confusing.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 10 of 16

_gile
Consultant
Consultant

@MarkJamesRogolino  a écrit :

In my opinion first parameter was mistake in this code.

new TypedValue((int)DxfCode.Text, jsonlists[0].layer)

Why do say that ?

The reasons why this line of would not work are:

  • 'jsonlists' is null or empty
  • 'jasonlists[0].layer' is null or empty


Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 11 of 16

MarkJamesRogolino
Advocate
Advocate

Hi, _gile. have a good weekend?

Thanks for your help.  But some code does not work.

As you can see in my picture already PrevalData DBDictionary exists.

goldhorsemillion_0-1676291954181.png

But this code does not get DBDictionary.

var nod = (DBDictionary)trans.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead);
                    DBDictionary prevaldict;
                    if (nod.Contains("PrevalData"))
                    {
                        prevaldict = (DBDictionary)trans.GetObject(nod.GetAt("PrevalData"), OpenMode.ForRead);                        
                    }

Can you tell me about this? Thanks in advance.

0 Likes
Message 12 of 16

_gile
Consultant
Consultant

What is the type of "PrevalData' ? DBDictionary or Xrecord ?



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 13 of 16

MarkJamesRogolino
Advocate
Advocate

Sorry, _gile. my mistake. above code works well. but one more problem.

my source code is as  followings.

using (Transaction trans = db.TransactionManager.StartTransaction())
                {
                    var nod = (DBDictionary)trans.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead);
                    DBDictionary prevaldict;
                    if (nod.Contains("PrevalData"))
                    {
                        prevaldict = (DBDictionary)trans.GetObject(nod.GetAt("PrevalData"), OpenMode.ForRead);                        
                    }
                    else
                    {
                        trans.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForWrite);
                        prevaldict = new DBDictionary();
                        nod.SetAt("PrevalData", prevaldict);
                        trans.AddNewlyCreatedDBObject(prevaldict, true);
                    }
                    Xrecord myXrecord = new Xrecord();
                    prevaldict.SetAt("JSonData", myXrecord);
                    trans.AddNewlyCreatedDBObject(myXrecord, true);

                    foreach (JsonItems item in jsonlists)
                    {
                        ResultBuffer resbuf = item.ToResultBuffer();
                        myXrecord.Data.Add(resbuf);
                    }

                    ObjectId myDataId = nod.GetAt("PrevalData");
                    Xrecord readBack = (Xrecord)trans.GetObject(
                                                  myDataId, OpenMode.ForRead);
                    foreach (TypedValue value in readBack.Data)
                        Application.ShowAlertDialog("===== OUR DATA: " + value.TypeCode.ToString()
                                  + ". " + value.Value.ToString());
                    trans.Commit();
                }

Here jsonlists has 375 values. my code returns when runs "myXrecord.Data.Add(resbuf);" .

0 Likes
Message 14 of 16

_gile
Consultant
Consultant

I do not know what is jsonlists.

You never clearly explain what you're trying to achieve neither how you want these data to be stored.

It is very hard to try to help you in this context.



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes
Message 15 of 16

MarkJamesRogolino
Advocate
Advocate

Sorry for not clear context. I will explain more in code. The resbuf has correct value runtimely in below code.

But myrecord.Data.Add function does not works.

foreach (JsonItems item in jsonlists)
                    {
                        ResultBuffer resbuf = item.ToResultBuffer();
                        myXrecord.Data.Add(resbuf);
                    }

 

 

public class JsonItems
    {
        public string layer { get; set; }
        public string OId { get; set; }
        public double width { get; set; }
        public double height { get; set; }
        public string hndle { get; set; }
        public int projtype { get; set; }
        public ResultBuffer ToResultBuffer()
        {
            return new ResultBuffer(
                new TypedValue(1, layer),
                new TypedValue(5, OId),
                new TypedValue(40, width),
                new TypedValue(40, height),
                new TypedValue(5, hndle),
                new TypedValue(71, projtype));
        }
    }
List<JsonItems> jsonlists = new List<JsonItems>();
// I did not describe the function adds jsonlists value. But jsonlists has value really.

 

0 Likes
Message 16 of 16

_gile
Consultant
Consultant
Accepted solution

@MarkJamesRogolino  a écrit :

But myrecord.Data.Add function does not works.

foreach (JsonItems item in jsonlists)
                    {
                        ResultBuffer resbuf = item.ToResultBuffer();
                        myXrecord.Data.Add(resbuf);
                    }

The Xrecord.Data type is ResultBuffer and the ResultBuffer.Add method requires a TypedValue as argument not another Resultbuffer.

The correct syntax would be (as shown upper):

myXrecord.Data = resbuf;

But doing this within your foreach loop  should ovewrite the XrecordData at each iteration and the data would be the one of the last item of 'jsonlists'.

 

Before writing any line of code, you must clearly define how you want to record this data. Usually, data is stored in a way that it can be easily retrieved. Dictionaries and xrecords are a convenient way to do this as long as you don't put all the data in a single xrecord.


A dictionary can contain one or more dictionaries and one or more xrecords (like a folder can contain folders and files). Each dictionary and each xrecord is named so that the name serves as a key to access it.
The data stored in an xrecord can only be differentiated by their index.


Knowing this, you have to choose how to organize the storage of these data in the "PrevalData" dictionary.

  • A single xrecord which contains the data of 375 "JsonItems", that is 375 * 6 = 2250 TypedValues.
  • One xrecord per "JsonItems" (each of the 375 xrecords must be named differently) which contains 6 TypedValues, that is one TypedValue per property of the JsonItems instance.
  • One dictionary per "JsonItems" (each of the 375 dictionaries must be named differently) which contains one xrecord per property of the "JsonItems". Each xrecord is named like the property and contains only one TypedValue.

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

0 Likes