LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Dr. Damien's Development - Object Based File I/O IX - Design Redux

I have fixed quite a few bugs and created a couple of benchmarks comparing the performance to the standard LabVIEW text read VIs. The object–oriented code is about twice as fast reading multiple lines from a file (large line counts) and on the order of as fast as the standard code for small line counts. I was fairly happy with the result. See the attached code for details.

 

However, when I started to implement the write code, I ran into a circular object reference issue. There are three primary objects:

 

  1. File
  2. Location
  3. DataAccess

In the original design, File contained Locations and Location contained DataAccess. I changed this during implementation of the write functionality so that both File and DataAccess contain Location. I also added File inputs to the DataAccess VIs, since they need the file reference to do anything. However, File needs to be able to call a flush function on the DataAccess objects (they are buffered), but DataAccess needs to know the file reference from File and location information from Location. Simply putting objects of each into the others will not work, since I end up with circular object references.

 

After talking with many people about this issue, I had a list of several solutions:

 

  • Collapse the File, Location, and DataAccess objects into a single object. We thrashed out the reasons why this would not work in earlier posts, but it boils down to a parent object with many abstract classes which do not need to be overridden to handle the many different types of data I/O. As Aristos Queue remarked, “That would be bad design.”
  • Use a functional global to pass the objects to each other. The functional global would be reentrant and launched using VI server for each instance of the class created. It would be accessed through its VI reference, which would be a data member of the class using it. This requires some infrastructure which could very easily leave VIs in memory when everything closes if something goes wrong. It also somewhat hides the data.
  • Always read or write as binary/string and use DataAccess as a translator from the binary to the final type. This keeps all read and write in File, but offloads translation so that LabVIEW's strict typing does not get in the way. Due to the translation layer, this could have serious performance issues.
  • Use a delegate class. This is a separate class which contains all the shared data and is a data member of all classes which need it. At the top level, it is abstract and has no data and no methods. Child classes for each file type will contain all data and methods needed for the particular file type.

As you can see from the UML diagram, I opted to go with the delegate class model and went back to the original relationship between the top–level objects. This will allow a more transparent programming model while keeping direct read and write efficiency. As a side issue, I realized I will need to make all the top level objects reference objects, not just File to avoid issues with forking wires. Hopefully, I will have most of this implemented by my next post.

 

FileIOClassDiagram.png

 

As always, I encourage comments and suggestions. This is definitely a work in progress.

 

Previous Posts In This Series:

  1. Representative File Types with conversation on design
  2. Requirements
  3. Top Level Design
  4. Design II
  5. Design III
  6. Implementation I
  7. Implementation II — Base Classes
  8. Text Files I
Download All
Message 1 of 12
(4,416 Views)

Damien,

 

Did you upload the correct version? The File.lvclass.Open.vi is broken as shown:

 

FileIO_Binary.lvlibFile.lvclassOpen.vi Block Diagram on ObjectBasedFileIO.lvpr_2011-10-09_21-54-03.png

 

 

 

ps: any way to type File.lvclass:_Open (_ deliberately inserted) without getting the emoticon

0 Kudos
Message 2 of 12
(4,356 Views)

The Binary folder contains incomplete code and should not have been included.  The Text and FileIOParent should be working.  My apologies.

0 Kudos
Message 3 of 12
(4,332 Views)

ok, thanks.

0 Kudos
Message 4 of 12
(4,302 Views)

I've just stumbled upon these posts for the first time whilst considering UML and OOP. These look like a fantastic learning model, one which I will read in depth, but I see this latest post is 10 months old and leaves the current state of the project as unfinished. Have there been any further developments since?

Thoric (CLA, CLED, CTD and LabVIEW Champion)


0 Kudos
Message 5 of 12
(4,214 Views)

There has, but I have not posted anything yet.  The largest issue is that I redesigned it yet again. The largest issue was a good "reference" architecture.  Files, by their nature, need serialized access.  However, LabVIEW allows simultaneous access from multiple locations.  There are two main methods for dealing with this:

 

  1. Use a data value reference or similar locking mechanism to ensure serialized access to the file.
  2. Use a "daemon" based architecture where all I/O to the file is done through a top-level, free running task handler.

I looked at both architectures.  The first appears to be easier, but in practice was not.  And the second has several more advantages, so I picked a variant of it.  My current architecture has three pieces - the user API, a coordinator task handler, and a file-specific task handler.  When a user opens a file, the open VI queries the coordinator VI for communication references to the file specific VI.  The coordinator launches the file specific VI, if needed, and returns the communication references to the Open VI.  These communication references are encapsulated in a LabVIEW object, which will be the file "reference".  At that point, all communications will go to the file specific VI.  The user gets an automatic, efficient producer/consumer architecture without doing anything but putting down a standard "railroad track" set of VIs.  Both the coordinator and file specific VIs will be object-oriented, queue-based command patterns (they may be the same VI).  Here is a UML sequence diagram of a standard open/read/close operation to whet your appetite.

 

FileIOSequenceDiagram.png

 

API - user API

GFS - general file server

SFS - specific file server

Message 6 of 12
(4,189 Views)

Thanks for the post, and the effort you must have put in.This approach has clear advantages over the previous, how much development have you found time for so far?

 

I'm still learning UML, and although your diagram makes sense to me and is clear to follow, it's not like any UML diagram I've seen previously which show objects and methods/attributes. I really must find myself a good reference material (book?) and get a few early nights with it! Smiley Very Happy

Thoric (CLA, CLED, CTD and LabVIEW Champion)


Message 7 of 12
(4,184 Views)

@Thoric wrote:

Thanks for the post, and the effort you must have put in.This approach has clear advantages over the previous, how much development have you found time for so far?

 

I'm still learning UML, and although your diagram makes sense to me and is clear to follow, it's not like any UML diagram I've seen previously which show objects and methods/attributes. I really must find myself a good reference material (book?) and get a few early nights with it! Smiley Very Happy


 

That is a SSD - System Sequence Diagram

 

You may have been thinking about a Domain Model.

 

A Domain model shows how the various components of a system relate but they do not reveal any timing information.

 

An SSD on the other hand does show timing to illustate whcih Classes invoke what methods and in what order. They also show the parameters snet and returned.

 

THe arrow coming back on a Class indicates it is invoking one of its method.

 

"Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development" by Craig Larman see here was a good intro book that worked for me.

 

He anayzes a couple of familiar systems like the game of Monopoly and a Cash Register application (POS Point Of Sales) and using a recursive approah develops a system design based on the GoF Models.

 

The examples are all Java or some such thing.

 

If I had more time I would doa Nugget Series based on his designs to realize the app in LV.

 

Have fun!

 

Ben

 

Retired Senior Automation Systems Architect with Data Science Automation LabVIEW Champion Knight of NI and Prepper LinkedIn Profile YouTube Channel
Message 8 of 12
(4,179 Views)

Ben wrote:

 

"Applying UML and Patterns: An Introduction to Object-Oriented Analysis and Design and Iterative Development" by Craig Larman see here was a good intro book that worked for me.

 

 

If I had more time I would doa Nugget Series based on his designs to realize the app in LV.

 


Thanks Ben, I'll look into the book. Maybe, if I get it and find the time , I might realise the examples as LV code myself which could prove a useful teaching aid for others.

Thoric (CLA, CLED, CTD and LabVIEW Champion)


Message 9 of 12
(4,169 Views)

If you don't have lots of time to study UML, you may want to check out UML Distilled.  I have been using it for a few years and find it a nice, concise reference.

 

In answer to Thoric's previous question about where I am in development, I have almost finished design and have some of the communication base classes implemented (i.e. not very far).  I will be reusing the code I wrote for the ASCII read, so reimplementing that should be a relatively straightforward repackaging.  The biggest issue is the standard LabVIEW OO issue - there are a lot of VIs (and icons) to write in an OO design.  I hope to make it easier for end developers by supplying template classes, but that will come after I get a working, top-to-bottom implementation I am happy with.

 

For those of you who are following it, this design is similar to the actor framework, but is more efficient for file I/O (fewer data copies).

0 Kudos
Message 10 of 12
(4,162 Views)