Author Topic: n00b conceptual questions - transaction manager, blocktables  (Read 2128 times)

0 Members and 1 Guest are viewing this topic.

gsfidler

  • Guest
Working my way through the autodesk .net lab projects, and there are a few things I want to make sure I'm understanding at a conceptual level:

BlockTable/BlockTableRecord (Please correct me if I've got any of this wrong):
As I understand it, the BlockTable is a dictionary of the graphical entities in the database.  For each record, the key is an ObjectId, and the value is some object that is essentially an array of entities (What is the root object type?  DBObject?Entity?)

A BlockTableRecord is conceptually equivalent to a block definition.  A "space" such as modelspace is a type of BTR.  When a dwg file is inserted as a block, it is the modelspace BTR that gets imported.

Transaction Manager Questions:
1.  Can someone explain what is happening inside .AddNewlyCreatedDBObject?  When I add an entity to a BTR, the argument is that new object; then I pass that same object to the transaction manager.  For some reason that doesn't seem intuitive.
2.  What is the purpose of the boolean in .AddNewlyCreatedObject?  I did a search on code that's been posted on this board, and I don't see it ever being passed as false.

Thanks in advance.

Jeff H

  • Needs a day job
  • Posts: 6150
Re: n00b conceptual questions - transaction manager, blocktables
« Reply #1 on: May 30, 2011, 02:10:12 AM »
Here is some basic info and links that might help out.

I would look at drawings using MgdDbg and here is a link to download MgdDbg_2010.zip

Things that helped me with MdbDbg
1. Before you run code that adds something to a drawing look at the drawing with MgdDbg then run the code and look at it again.
2. Look at a drawing with MgdDbg that has information you want extract then write code to go get it.


Here is link to .Net Developer's guide about drawing structure .NET Developer Guide


Following quotes are from arxdoc.chm in ObjectArx SDK files downloaded From Here
On my computer located at  C:\ObjectARX 2012\docs\arxdoc.chm
Use the arxdoc.chm most Arx documentation pertains to .NET API

Quote from: AutoCAD Database Overview
An AutoCAD drawing is a collection of objects stored in a database. Some of the basic database objects are entities, symbol tables, and dictionaries. Entities are a special kind of database object that have a graphical representation within an AutoCAD drawing. Lines, circles, arcs, text, solids, regions, splines, and ellipses are examples of entities. A user can see an entity on the screen and can manipulate it.

Symbol tables and dictionaries are containers used to store database objects. Both container objects map a symbol name (a text string) to a database object. An AutoCAD database includes a fixed set of symbol tables, each of which contains instances of a particular class of symbol table record. You cannot add a new symbol table to the database. Examples of symbol tables are the layer table (AcDbLayerTable), which contains layer table records, and the block table (AcDbBlockTable), which contains block table records. All AutoCAD entities are owned by block table records.

Dictionaries provide a more generic container for storing objects than symbol tables. A dictionary can contain any object of the type AcDbObject or subclass thereof. The AutoCAD database creates a dictionary called the named object dictionary when it creates a new drawing. The named object dictionary can be viewed as the master “table of contents” for all of the dictionaries associated with the database. You can create new dictionaries within the named object dictionary and add new database objects to them.

The following figure shows the key components of the AutoCAD database.


Quote from: ObjectId Structure
Since the Release of AutoCAD R13, there has been a mechanism for dealing with database-resident objects in memory. The scheme has two parts for each object. First there is the database-resident object itself, which resides in memory and can be paged out to disk if memory needs to be freed up. The second part is a "stub" object that always resides in memory and acts as the access point for the database-resident object.

When an object or entity is first added to the database, a new stub object is created and set to point to the object or entity being added to the database. The address of this stub in memory is the ObjectId value for the object or entity added to the database. The same mechanism applies when a database is read into memory from disk.

When a database-resident object is opened, the ObjectARX application sees that the database-resident object's objectId is passed into the open call and a pointer to the actual database-resident object is returned. What's actually going on is that the objectId is the address of the stub in memory, so the stub is accessed to get a pointer to the actual database-resident object. If the database-resident object is paged out, it is paged in and its new address is returned.

So, an ObjectId object is a container for the address of a database-resident object's stub. As such, it is an extremely important object because it contains the only session-persistent locator for the database-resident object.


Another great resource is Through the Interface below are links from blog
AutoCAD .NET Training DevTV Session 1: Getting Started
AutoCAD .NET Training DevTV Session 2: User Interaction – User Input
AutoCAD .NET Training DevTV Session 3: Database Fundamentals
AutoCAD .NET Training DevTV Session 4: Database Events, PaletteSet

pkohut

  • Bull Frog
  • Posts: 483
Re: n00b conceptual questions - transaction manager, blocktables
« Reply #2 on: May 30, 2011, 04:58:39 AM »
BlockTable/BlockTableRecord (Please correct me if I've got any of this wrong):
As I understand it, the BlockTable is a dictionary of the graphical entities in the database.  For each record, the key is an ObjectId, and the value is some object that is essentially an array of entities (What is the root object type?  DBObject?Entity?)
It's better to think of AcDbSymbolTable's as a collection and not worry about the plumbing under the hood except what is shown through public API's. The records stored in AcDbSymbolTable's are keyed by a string value associated with an AcDbObjectId object. The AcDbDatabase maintains an association of AcDbObjectId's to the AcDbObject's that own the Id's. So given an AcDbObjectId the AcDbObject can be retrieved, and if you already have a database resident AcDbObject then calling ::objectId() on the object gives you the AcDbObjectId.

There are multiple ways to get an AcDbObjectId or AcDbObject, in the case of AcDbSymbolTable's the AcDbSymbolTableIterator::getRecord and getRecordId can be used.

What is the base type for any given object? That's best figured out by looking the the ARX documentation. I'm biased towards the ARX docs (2008 version) rather than the Managed ARX docs. I feel that the 2008 (maybe 2009) ARX docs are ***way better*** than the 2010+ versions. The ARX docs (2008) information is more complete and better organized than the managed ARX version, YMMV.

How do you know what base types a container class can hold? Again, look at the ARX docs. For objects derived from AcDbSymbolTable, they hold types derived from AcDbSymbolTableRecord. AcDbSymbolTableRecord types can hold...depends on the table record type. Some like AcDbLinetypeTableRecord and AcDbLayerTableRecord are not containers for other objects, others like AcDbBlockTableRecord are containers and hold AcDbEntity derived types.

A BlockTableRecord is conceptually equivalent to a block definition.  A "space" such as modelspace is a type of BTR.
Sounds about right.

Transaction Manager Questions:
1.  Can someone explain what is happening inside .AddNewlyCreatedDBObject?  When I add an entity to a BTR, the argument is that new object; then I pass that same object to the transaction manager.  For some reason that doesn't seem intuitive.
At the ARX level there are 2 choices after adding an object or entity to the database (DBR = database resident). 1) close the object 2) hand the object off to the transaction manager.
addNewlyCreatedDBRObject maintains a collection of AcDbObject(s) to be committed or "uncreated" depending endTransaction or abortTransaction being called. If the manager commits then each object is simply closed. When aborted is called, each object is uncreated (which I presume the object is physically removed from the DB, rather than the objects erase bit set and closed, never looked into it)
 
2.  What is the purpose of the boolean in .AddNewlyCreatedObject?  I did a search on code that's been posted on this board, and I don't see it ever being passed as false.
Flag to add or remove an object (defaults to true)

Quote
From the ARX docs
virtual Acad::ErrorStatus
addNewlyCreatedDBRObject(
AcDbObject* obj,
bool add = true) = 0;

obj Input pointer to the object to be added or removed
add Input Boolean indicating whether to add or remove the object

If add == Adesk::kTrue, the object pointed to by pObject is added to the top transaction. If add == Adesk::kFalse, then the object is removed from whatever transaction it's within.

pObject must point to an object that is newly created (that is, it has never been closed) and is already database resident (that is, it's been added to an AcDbDatabase so it has an objectId).

Returns Acad::eOk if successful. If pObject points to an object that is not newly created, then Acad::eNotNewlyCreated is returned.
New tread (not retired) - public repo at https://github.com/pkohut

gsfidler

  • Guest
Re: n00b conceptual questions - transaction manager, blocktables
« Reply #3 on: May 30, 2011, 01:04:28 PM »
Thank you both for the detailed replies.  I've got a lot of reading ahead of me, but if I'm going to go to the trouble to learn to work with the language, I'd like to think I'm going to learn what I'm doing, rather than just what to type.