Author Topic: has ExtendedDataRegAppName any real purpose?  (Read 4092 times)

0 Members and 1 Guest are viewing this topic.

nekitip

  • Guest
has ExtendedDataRegAppName any real purpose?
« on: May 08, 2013, 11:42:38 AM »
I expect you that you say "yes!" to this provocative subject, but I think, maybe an interesting one.
 
But I ask you where?
Because, if we take our time and plant xdata with registered appname into some entity, then the only time it can be useful is when we know ahead that user will need to select "ours" entities and so we prepare selectionfilter ahead. It has a purpose like: "hey user, go select some of yellow circles that our app has created".
But it we have 10 different types of user objects (meaning to human something like cable_type 1, cable_type 2, pipe100,pipe200...) but in autocad, they are just yellow circles, and we give them ExtendedDataRegAppName , then, what we have?
App must also read xrecord or xdata anyway to find out more about that "yellow circle", then and if we want, return SetImpliedSelection.
 
I know that it must have a purpose, orelse it will not exist, but I didn't stumble into it yet.

Gasty

  • Newt
  • Posts: 90
Re: has ExtendedDataRegAppName any real purpose?
« Reply #1 on: May 08, 2013, 12:20:31 PM »
Hi,

I'm not sure to understand, but the main objective of regaps is to isolate data between applications, so if you have app A and app B each one write in its own regap data space, that permit to filter by regap, but not by xdata itself. If you need something more elaborated like distinct graphic representation based on xdata or something else, you can use the overrule API to do that. Xdata it's not user friendly but programmer (almost) friendly, so the use of xdata is up to the programmer and should be transparent to the final user.

Gaston Nunez

WILL HATCH

  • Bull Frog
  • Posts: 450
Re: has ExtendedDataRegAppName any real purpose?
« Reply #2 on: May 08, 2013, 04:07:13 PM »
I thought it also played into performance.  Applications like CadWORX which use xdata to manage their custom objects/groups etc can add a handler to modify their objects without much overhead involved with checking if the object is owned by the application.

nekitip

  • Guest
Re: has ExtendedDataRegAppName any real purpose?
« Reply #3 on: May 08, 2013, 06:24:19 PM »
this quick and ugly code here is showing that ExtendedDataRegAppName is doing nothing in xrecord.
Code - vb.net: [Select]
  1.  <CommandMethod("test_writexrec")> _
  2.         Public Shared Sub test4()
  3.             Const AppName As String = "testap1"
  4.             Dim db As Database = HostApplicationServices.WorkingDatabase
  5.             Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
  6.             Dim psr As PromptEntityResult = ed.GetEntity("Select entity")
  7.             If psr.Status = PromptStatus.OK Then
  8.                 Using trans As Transaction = db.TransactionManager.StartTransaction()
  9.                     Dim xrb As New ResultBuffer(New TypedValue(DxfCode.ExtendedDataAsciiString, "can stand alone"))
  10.                     writeToXrec(AppName, xrb, psr.ObjectId, trans)
  11.                     trans.Commit()
  12.                 End Using
  13.             End If
  14.         End Sub
  15.  
  16.         Public Shared Sub writeToXrec(ByVal name As String, ByVal data As ResultBuffer, ByVal oid As ObjectId, ByRef trans As Transaction)
  17.             Dim ent As Entity = trans.GetObject(oid, OpenMode.ForRead)
  18.             If ent.ExtensionDictionary.IsNull Then
  19.                 ent.UpgradeOpen()
  20.                 ent.CreateExtensionDictionary()
  21.             End If
  22.             Dim extensionDict As DBDictionary = trans.GetObject(ent.ExtensionDictionary(), OpenMode.ForWrite)
  23.             Dim newxrec As New Xrecord
  24.             newxrec.Data = data
  25.             extensionDict.SetAt(name, newxrec)
  26.             trans.AddNewlyCreatedDBObject(newxrec, True)
  27.         End Sub
  28.  
  29. 'if you change resultbuffer with  = New ResultBuffer(New TypedValue(DxfCode.ExtendedDataRegAppName, AppName), New TypedValue(DxfCode.ExtendedDataAsciiString, "can stand alone"))
  30. 'nothing will happen
  31.  
  32.   <CommandMethod("test_showobjects")> _
  33.         Public Shared Sub test1()
  34.             Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
  35.  
  36.             Dim tv = New TypedValue(DxfCode.ExtendedDataRegAppName, "testap1")
  37.             Dim sf = New SelectionFilter(New TypedValue() {tv})
  38.  
  39.             Dim res = ed.GetSelection(sf)
  40.             Dim psRes As PromptSelectionResult = ed.SelectAll(sf)
  41.             If psRes.Status = PromptStatus.OK Then
  42.                 ed.WriteMessage("Number of found: {0}", psRes.Value.Count)
  43.             End If
  44.         End Sub

but when you write to xdata, you need appname (as a first value).
Code - vb.net: [Select]
  1.  <CommandMethod("test_addxdata")> _
  2.         Public Shared Sub test3()
  3.             Const AppName As String = "testap1"
  4.  
  5.             Dim db As Database = HostApplicationServices.WorkingDatabase
  6.             Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
  7.             Dim psr As PromptEntityResult = ed.GetEntity("Select entity")
  8.             If psr.Status = PromptStatus.OK Then
  9.                 Using trans As Transaction = db.TransactionManager.StartTransaction()
  10.                     Dim regAT As RegAppTable = trans.GetObject(db.RegAppTableId, OpenMode.ForRead)
  11.                     If Not regAT.Has(AppName) Then
  12.                         Dim regATR As New RegAppTableRecord()
  13.                         regATR.Name = AppName
  14.                         regAT.UpgradeOpen()
  15.                         regAT.Add(regATR)
  16.                         trans.AddNewlyCreatedDBObject(regATR, True)
  17.                     End If
  18.  
  19.                     Dim ent As Entity = trans.GetObject(psr.ObjectId, OpenMode.ForWrite)
  20.                     ent.XData = New ResultBuffer(New TypedValue(DxfCode.ExtendedDataRegAppName, AppName), New TypedValue(DxfCode.ExtendedDataAsciiString, "can not stand alone"))
  21.  
  22.                     trans.Commit()
  23.                 End Using
  24.  
  25.             End If
  26.  
  27.         End Sub

First question was (and I admit I was wrong and I am ashame, but it is a good thing, now that it's here, someone will make use of this knowlage). So appname is required to write in xdata, and only there.
And the second question was: where to use it? The way selection filters work is - to prepare filter ahead, but we don't have enough info in advance. We must open some data container anyway (and 16kb of xdata is not that) to find out more, to find out if this is the object user really wants. RegAppName is not all that usefull. And you will say - but it will make boundary between aps.  But I don't know even how to see how much of my data is in it (size). And no way to reserve space for what i need, because - although you have "appname" that will make my boundary and space - mine, it still not gives me right to even that tiny 16kb! (it is shared).
So, it will cost to open it (filter it, mess with it), but not much will be gain, because of a few KB that can be put in.
Xrecord can hold a lot. But i don't see that it can be selected by selection filter by appname. Why not there?
(think i'm just frustrated right now, and it's late night overhere)

where i am wrong?

WILL HATCH

  • Bull Frog
  • Posts: 450
Re: has ExtendedDataRegAppName any real purpose?
« Reply #4 on: May 08, 2013, 06:48:24 PM »
Code - vb.net: [Select]
  1.             Dim tv = New TypedValue(DxfCode.ExtendedDataRegAppName, "testap1")
I think the way you're trying to use a selection filter is faulty.  You are asking the editor to select only a peice of xdata, it will not return any sort of objects for you as xdata is not a geometric object.

I think the real purpose for xdata surrounds functionality like "ObjectOverrule.SetXDataFilter Method" allowing us to provide customized interaction with our objects (as I mentioned for CadWORX)

I'm not sure of a way to do a selection filter based on xdata without opening objects but I'm sure somebody on here knows.

TheMaster

  • Guest
Re: has ExtendedDataRegAppName any real purpose?
« Reply #5 on: May 09, 2013, 12:22:44 AM »
I expect you that you say "yes!" to this provocative subject, but I think, maybe an interesting one.
 
But I ask you where?
Because, if we take our time and plant xdata with registered appname into some entity, then the only time it can be useful is when we know ahead that user will need to select "ours" entities and so we prepare selectionfilter ahead. It has a purpose like: "hey user, go select some of yellow circles that our app has created".
But it we have 10 different types of user objects (meaning to human something like cable_type 1, cable_type 2, pipe100,pipe200...) but in autocad, they are just yellow circles, and we give them ExtendedDataRegAppName , then, what we have?
App must also read xrecord or xdata anyway to find out more about that "yellow circle", then and if we want, return SetImpliedSelection.
 
I know that it must have a purpose, orelse it will not exist, but I didn't stumble into it yet.

It has the same purpose that the 'key' in a managed Dictionary<TKey, TValue> or HashTable has - to associate xdata with a unique key.  Perhaps the use of the term 'Application' has you confused. The application name is more simply, a unique key.

XData is stored in a LIST. Since many applications can store XData in the same list, doesn't there need to be a way to distinguish the xdata of one application from the xdata of other applications?


gile

  • Gator
  • Posts: 2507
  • Marseille, France
Re: has ExtendedDataRegAppName any real purpose?
« Reply #6 on: May 09, 2013, 04:04:51 AM »
Hi,

I'm not certain to understand what you want to do, but to you can have one registered application name per "type of user objects" ("Cable1App", "Cable2App", "Pipe100App", "Pipe200App", ...) so that ou can use them to select one or more tye of objects .
And to avoid any issue with the the available data size, store the data within an extension dictionary Xrecord.

Here's a little example:

Code - C#: [Select]
  1. using System;
  2. using System.Linq;
  3. using Autodesk.AutoCAD.ApplicationServices;
  4. using Autodesk.AutoCAD.DatabaseServices;
  5. using Autodesk.AutoCAD.EditorInput;
  6. using Autodesk.AutoCAD.Runtime;
  7.  
  8. namespace XdataXrecordSample
  9. {
  10.     public class CommandMethods
  11.     {
  12.         [CommandMethod("SET")]
  13.         public void Set()
  14.         {
  15.             Document doc = Application.DocumentManager.MdiActiveDocument;
  16.             Database db = doc.Database;
  17.             Editor ed = doc.Editor;
  18.  
  19.             PromptEntityResult per = ed.GetEntity("\nSelect an object: ");
  20.             if (per.Status != PromptStatus.OK) return;
  21.  
  22.             ResultBuffer data = new ResultBuffer(
  23.                 new TypedValue(1, "Test"),
  24.                 new TypedValue(70, 42),
  25.                 new TypedValue(40, 3.14159));
  26.  
  27.             using (Transaction tr = db.TransactionManager.StartTransaction())
  28.             {
  29.                 DBObject obj = tr.GetObject(per.ObjectId, OpenMode.ForWrite);
  30.                 SetData(obj, data, "TestRegAppName", "TestXrecKey");
  31.                 tr.Commit();
  32.             }
  33.         }
  34.  
  35.         [CommandMethod("GET")]
  36.         public void Get()
  37.         {
  38.             Document doc = Application.DocumentManager.MdiActiveDocument;
  39.             Database db = doc.Database;
  40.             Editor ed = doc.Editor;
  41.  
  42.             TypedValue[] filter = { new TypedValue(1001, "TestRegAppName") };
  43.             PromptSelectionResult psr = ed.SelectAll(new SelectionFilter(filter));
  44.             if (psr.Status != PromptStatus.OK) return;
  45.  
  46.             using (Transaction tr = db.TransactionManager.StartTransaction())
  47.             {
  48.                 foreach (ObjectId id in psr.Value.GetObjectIds())
  49.                 {
  50.                     Entity ent = (Entity)tr.GetObject(id, OpenMode.ForRead);
  51.                     ResultBuffer data = GetData(ent, "TestRegAppName");
  52.                     Application.ShowAlertDialog(string.Format(
  53.                         "{0}\n{1}",
  54.                         ent.GetType().Name,
  55.                         String.Join("\n", data.AsArray().Select(tv => tv.Value.ToString()))));
  56.                 }
  57.             }
  58.         }
  59.  
  60.         private void SetData(DBObject obj, ResultBuffer data, string regAppName, string xrecKey)
  61.         {
  62.             Database db = obj.Database;
  63.             Transaction tr = db.TransactionManager.TopTransaction;
  64.             if (tr == null)
  65.                 throw new Autodesk.AutoCAD.Runtime.Exception(ErrorStatus.NoActiveTransactions);
  66.             RegAppTable rat = (RegAppTable)tr.GetObject(db.RegAppTableId, OpenMode.ForRead);
  67.             if (!rat.Has(regAppName))
  68.             {
  69.                 RegAppTableRecord ratr = new RegAppTableRecord();
  70.                 ratr.Name = regAppName;
  71.                 rat.UpgradeOpen();
  72.                 rat.Add(ratr);
  73.                 tr.AddNewlyCreatedDBObject(ratr, true);
  74.             }
  75.             ResultBuffer xdata = new ResultBuffer(new TypedValue(1001, regAppName), new TypedValue(1000, xrecKey));
  76.             obj.XData = xdata;
  77.             if (obj.ExtensionDictionary == ObjectId.Null)
  78.             {
  79.                 obj.UpgradeOpen();
  80.                 obj.CreateExtensionDictionary();
  81.             }
  82.             DBDictionary xdict = (DBDictionary)tr.GetObject(obj.ExtensionDictionary, OpenMode.ForWrite);
  83.             Xrecord xrec;
  84.             if (xdict.Contains(xrecKey))
  85.             {
  86.                 xrec = (Xrecord)tr.GetObject((ObjectId)xdict[xrecKey], OpenMode.ForWrite);
  87.             }
  88.             else
  89.             {
  90.                 xdict.UpgradeOpen();
  91.                 xrec = new Xrecord();
  92.                 xdict.SetAt(xrecKey, xrec);
  93.                 tr.AddNewlyCreatedDBObject(xrec, true);
  94.             }
  95.             xrec.Data = data;
  96.         }
  97.  
  98.         private ResultBuffer GetData(DBObject obj, string regAppName)
  99.         {
  100.             Transaction tr = obj.Database.TransactionManager.TopTransaction;
  101.             if (tr == null)
  102.                 throw new Autodesk.AutoCAD.Runtime.Exception(ErrorStatus.NoActiveTransactions);
  103.             ResultBuffer xdata = obj.GetXDataForApplication(regAppName);
  104.             if (xdata == null)
  105.                 return null;
  106.             string xrecKey = (string)xdata.AsArray()[1].Value;
  107.             if (obj.ExtensionDictionary == ObjectId.Null)
  108.                 return null;
  109.             DBDictionary xdict = (DBDictionary)tr.GetObject(obj.ExtensionDictionary, OpenMode.ForRead);
  110.             if (!xdict.Contains(xrecKey))
  111.                 return null;
  112.             Xrecord xrec = (Xrecord)tr.GetObject((ObjectId)xdict[xrecKey], OpenMode.ForRead);
  113.             return xrec.Data;
  114.         }
  115.     }
  116. }
  117.  
« Last Edit: May 09, 2013, 04:14:59 AM by gile »
Speaking English as a French Frog

nekitip

  • Guest
Re: has ExtendedDataRegAppName any real purpose?
« Reply #7 on: May 09, 2013, 09:10:39 AM »
After coding long into the nights and not getting expected results, one can become frustrated easily and become erratic. So have I.  :|
Thank you all for the patience, and trying to guess my problems, especially gile for this code. It appears that I have a deeper problems and will have to rethink the whole app strategy and start not far from scratch. I have been betting on the wrong horses all along.
But I'll be back ;)