CS changes after version 1.20
- CS changes after version 1.20
- Attribute data
- A big mess: create, destroy, _new, _delete, start, stop, activate THIS, deactivate THIS, activate, deactivate, ProcConstructor, ProcDestructor...
- "constructor" method versus "new" operator
- "startThread" and "stopThread"
- References to front panels
- State machines
- CAEObj class
- What about ObjectVIEW?
- "name2ref", "ref2name" ...
- Does the new CS has a class inheritance toolkit like ObjectVIEW?
This How-To describes the changes for CS for versions 2.00 and newer. In version 2.00, the whole core of the CS framework has been rewritten in order to make it simpler, more transparent and faster.
Until version 1.20, the attribute data was stored on the front panel of the object.vit. With newer versions of CS, the attribute data is stored in so called functional global variables. The main reason for this is performance. Obtaining or setting the attribute data is now about a factor of 100 faster.
Each class of version prior to 2.00 had a method called "object.vit". This was mainly used to store attribute data and to start threads. Now, "object.vit" has become obsolete. If a thread needs to be created, it is created in the constructor of the class concerned. As an example, the constructor of the BaseProcess class creates a thread containing the event handling loop and the periodic action loop; similar, the constructor of the BaseProcessSM class creates the thread required for operating a state machine.
A big mess: create, destroy, _new, _delete, start, stop, activate THIS, deactivate THIS, activate, deactivate, ProcConstructor, ProcDestructor...
Until version 1.20, an object was created in two steps. First, a "create" method was called (which called the _new method). Then, an object containing active code (like loops) was started using the "start" method. Once an object got started, a "BaseProcess.activate THIS" methods was executed to call a "ClassName.activate" method, which called a "ClassName.ProcConstructor" method - very complicated, confusing and badly performing.
Now, an instance of a class is created by calling the "ClassName.constructor" method, just like in C++. Everything that needs to be done (allocating memory for attribute data, starting threads) is done in the constructor itself.
For destroying an object, just call the destructor of its class.
: Until version 1.20, it was possible to use synchronous calls to a SuperProc object (as an example), since the constructor code was only executed after the object was started. Now this has to done with great care, since this can result in a deadlock - a class constructor can not use a synchronous call to a SuperProc, if the constructor is called in the event loop of a SuperProc. As a consequence, creating objects that are used by your class should either be done using the "new" operator or "simple" calls to the SuperProc object.
"constructor" method versus "new" operator
An object can either be created by directly calling the constructor method of its class or by using the .../CSSystem/CSSystem._new operator. Analogous applies for the constructor or the .../CSSystem/CSSystem._delete operator. In principle, it is only design decision whether to call the constructor or to use the "new" operator - within code outside the "constructor" method, there is no big difference. However, note the differences of calling the "constructor" and the "new" operator for a class when being called from the constructor of a class (see Object Orientation).
"startThread" and "stopThread"
In order to ease the dynamic creation of code from VI templates (*.vit) during runtime, two operators .../CSSystem/CSSystem._startThread and .../CSSystem/CSSystem/_stop.Thread are available. I think, they are very convenient. The only thing that is required is a control named "object ref" on the front panel of the VI template. The "startThread" operator will set the value of "object ref" to the reference of the object to which the thread belongs. Comment: For GUI classes, the "startThread" operator is encapsulated in the constructor of the BaseProcessGUI class.
GUI classes should inherit from the BaseGUI class. A dedicated GUI panel (thread) will be started by the constructor of the BaseGUI class. The developer of a GUI class has to provide an VI template (*.vit), typically named "ClassName.panel.vit". The name of that template must be passed to the "data" control of the constructor of BaseGUI. That constructor will take care of creating a run-time panel from the VI template. The only thing that is required is a control named "object ref" on the front panel of the VI template. The constructor of BaseGUI will set the value of "object ref" to the reference of the object to which the panel belongs.
References to front panels
Until version 1.20, the reference of the object was identical to the reference of its front panel (since the front panel was
the object). With newer versions, this is no longer the case. Now a front panel is just one of the properties of a class, just like attribute data or event handling threads. For convenience, the CSObj class provides methods to set or get the reference to the front panel of an object or to open and close a front panel.
Until version 1.20, the use of state machines was confusing because a state machine thread (inheriting from BaseSM) had a different reference than the event handling thread (inheriting from BaseProcess). Thanks to multiple inheritance, only one reference is required making the two methods "getMyProcRef" and "getSMRef" redundant. In addition, the code looks much cleaner now.
As an example, QueueClient and its state machine no longer show up as two different objects but only as one object.
The CAEObj class was (and still is) a class serving as an interface between the BaseProcess class and the core of the CS system. This resulted in several implications. As an example, classes using the CAEObj class as a super class could either be used for event handling (exclusive) or a state machine. Now, all methods required for state machine have been removed from the CAEObj class and these methods are only implemented in the BaseSM class itself.
What about ObjectVIEW?
After version 1.20, CS is no longer using or depending on ObjectVIEW. This has two consequences:
- The core of CS can be developed independently of ObjectVIEW. This has a great impact on the performance and the maintainability of CS.
- Until version 1.20, it was not possible to use the fast event mechanism of CS in parallel to the slower but more general event mechanism of ObjectVIEW. In addition, the use of object nets provided by ObjectVIEW was practically impossible. With newer versions of CS, all possibilities are again open.
"name2ref", "ref2name" ...
For making a clear cut, some methods have been renamed. This was necessary in order to avoid name clashes with ObjectIVEW and to keep open the possibility to use, as an example, the object nets of ObjectVIEW in parallel to CS. The methods that should be used now are named like .../CSSystem/CSSystem.name2ref.vi. As a consequence, all methods like "name2ref" and "ref2name" need to be replaced. Sorry for the inconvenience...
The surprising answer is: No, you no longer need a class inheritance toolkit. Just like in C++, you only need to write a constructor and a destructor. Parent classes are defined by calling their constructors in your constructor. However, you should follow the definitions in Object Orientation.
However, in .../CSClass/CSClassUtilities/...there is a small utility named "CSClassUtilities.InheritClass". It provides some assistance in order to set-up the methods for attribute data and the directory structure in the file system. Moreover, it will give a first order example for a constructor and a destructor.
In addition, there is a tool "CSClassUtilities.EditClass" that allows for more convenient browsing and editing of class methods.
- 06 Jul 2005