ABSTRACT

This thesis focuses on the modeling concept....

 

 

NEATTOOLS-A FINE GRAIN DATA FLOW NETWORK PROGRAMMING ENVIRONMENT

 

 

By

YUH-JYE CHANG

 

 

 

DISSERTATION

 

Submitted in partial fulfillment of the requirements for the degree of Doctor of Philosophy in Computer Information Science in the Graduate School of Syracuse University

Dec 1998

 

 

Approved _________________________

Professor Geoffrey Fox

 

Date _____________________________

 

 

 

 

Copyright 1998 Yuh-Jye Chang

All rights Reserved

 

CONTENTS

 

1. Introduction

2. Project Requirements

3. C++ vs. Java

3.1 Java Background

3.2 Benchmark

3.3 Benchmark Analyze

3.4 Conclusion

4. NeatTools Architecture Analyze

4.1 Module Abstraction

4.1.1 Data

4.1.1.1 The presentation

4.1.1.2 Access privilege

4.1.1.3 The desktop

4.1.2 Actions

4.1.2.1 Active (Output) action

4.1.2.2 Reactive (Input) action

4.1.3 Connections

4.2 Implementation Concept

4.3 Benchmark Information on NeatTools

4.4 Benchmark Analyze on NeatTools

4.5 Conclusion

5. NeatTools and Object Management Environments

5.1 CORBA

5.1.1 Object Definition

5.1.2 CORBA provide Object Interoperability

5.1.3 OMA provide Application-Level Integration

5.2 COM/DCOM

5.2.1 Objects and Interfaces

5.2.2 Interface Description Language (IDL)

5.2.3 Service Control Manager (SCM)

5.3 Compare COBRA and COM/DCOM

5.4 Benchmark Information on CORBA

5.5 Benchmark Analyze on CORBA

5.6 Conclusion

6. NeatTools and Modeling Languages

6.1 Colored Petri-Net

6.2 UML (Unified Modeling Language)

6.3 Conclusion

7. NeatTools and Other Visual Programming Tools

7.1 Visual C++

7.2 Visual Basic

7.3 Java Bean

7.4 J++

7.5 LabView

7.6 AVS

7.7 Conclusion

8. NeatTools' Visual Programming Features

8.1 Multimedia Database

8.2 Transfer Focus among Text Fields

8.3 Polymorph Data Type

8.4 Container Nest Structure (Complex Module)

8.5 Data Flow Controls

8.6 Multimedia Features

8.7 Multi-Thread Features

8.8 Keyboard and Mouse Event Simulator/Filter

8.9 External Module and Dynamic Link Library

8.10 Modules for External Devices

8.11 Networking and TCP/IP

8.12 State Machine

9. Examples/Applications

10. Conclusion

11. Appendix

11.1 NeatTools Reference Manual

11.1.1 NeatTools Module Specification:

11.1.2 NeatTools Class Hierarchy:

11.2 Module Programming Examples

11.3 Visual Programming Examples

11.4 NeatTools Architecture

11.4.1 Three-Layer Architecture

11.4.2 Package structure

11.4.3 OS and C++ runtime Package

11.4.4 Java-like API package

11.4.4.1 LANG package

11.4.4.2 UTIL package

11.4.4.3 IO package

11.4.4.4 NET package

11.4.4.5 AWT package

11.4.5 NeatTools application package

11.4.5.1 NEAT package

11.4.5.2 Modules package

11.4.5.3 External modules package

11.4.5.4 DESKTOP package

12. Bibliography

 

 

FIGURES

Figure 1: Top-level packages

Figure 2: OS and C++ runtime layer

Figure 3: Java like cross-platform API layer

Figure 4: Exceptions class diagram in Java like API layer

Figure 5: NeatTools application layer

Figure 5: Property in NEAT package

Figure 7: NEAT package (continue)

 

TABLES

Table 1: Summary of layers

Table 2: Classes of LANG package

Table 3: Classes of UTIL package

Table 4: Classes of IO package

Table 5: Classes of NET package

Table 6: Classes of AWT package

Table 7: Classes of NEAT package

 

 

  1. Introduction
  2. NeatTools is a visual programming software package with which a user can create module linkage networks for data collection, gesture recognition, control of external devices, virtual world control, remote collaboration, and perceptual modulation. Some of NeatTools' functionality is ported from Neat Software developed for Dr. Dave Warner at the Institute for Interventional Informatics from 1993 to 1996.

    NeatTools' visual interface is similar to AVS. Different modules are selected, placed in a work area, and then connected by lines. These connections indicate a data flow from one module to another. The data flow may be comprised of various data types (e.g., integer, real number, string, MIDI event, wave stream, video stream, etc.). NeatTools provides multi-threaded, real time support in module design which is not supported by AVS. These features bring a NeatTools user full power to access the resources inside the computer.

    The software is written in C++ and built on top of a Java-like Cross Platform C++ API (application programming interface). We decided against using Java because we need the software to be capable of handling real time computationally intensive tasks like audio, video, compression, decompression, VR, etc. We designed the graphical user interface (GUI) API after the Java API standard as all features implemented in a Java API are intrinsic to standard windows systems like Microsoft Windows and X Windows. By hiding all platform-dependent code inside the API, we achieve our goal of a cross platform application by maintaining only one code package. Currently, NeatTools can compile and run on Win95, WinNT, LINUX, Sun, and SGI. On Win95, or WinNT we use Microsoft Visual C++ 5.0. On UNIX we use GNU GCC 2.7.2.

    The NeatTools environment is extensible. New modules can be added by invoking dynamic linkage libraries which specify an implementation of the module. Later, a user can use it just like any predefined module and create new module linkage networks.

  3. Project Requirements
  1. General Human Interface Tool. Can adapt to any external industry or in-house devices.
  2. Able to handle complex, real-time, and calculate intensive task.
  3. Support full multimedia function. Enable user to control, manipulate and transform different multimedia data and information.
  4. A visual programming environment. Enable user to design and implementation complete application without the need to write any textual code.
  5. Scalability and cross platform.
  1. C++ vs. Java
  2. NeatTools is an experimental computer science project. Before we can make any experiment, we have to have a tool or environment. On top of it, we than can build and test our design concept and proceed the experiment itself. So, the first step was to implement such a visual programming tool. The question was which language to use to implement the tool so it will meet all the requirements and has the potential for the future development. Here, C/C++ is the industry standard and Java is a rapid develop and well adopted new language. I dedicated the following sections to discuss the cons and pros of this two popular language.

    1. Java Background
    2. Java is an object-oriented programming language developed by Sun Microsystems, a company best known for its high-end Unix workstations. Modeled after C++, the Java language was designed to small, simple, and portable across platforms and operating systems, both at the source and at the binary level.

      Platform independence is one of the significant advantages that Java has over other programming languages. At the source level, Java's primitive data types have consistent sizes across all development platforms. Java's foundation class libraries make it easy to write code that can be moved from platform to platform without the need to rewrite it to work with that platform. Java binary files are also platform-independent and can run on multiple platforms without the need to recompile the source. How this work? Java binary files are actually in a form called bytecodes. Unlike most other programming language, Java development environment has two parts: a Java compiler and a Java interpreter. The Java compiler takes Java program and instead of generating machine code from source files, it generates bytecodes. To run a Java program, user run a program called a bytecode interpreter, which in turn executes Java program. User can either run the interpreter by itself, or for applets there is a bytecode interpreter built into Java-capable or enabled browser like Netscape or Microsoft Internet Explorer that runs the applet.

      The disadvantage of using bytecodes is in execution speed. Because system-specific programs run directly on the hardware for which they are compiled, they run significantly faster than Java bytecodes which must be processed by the Java interpreter. In order to increase the performance of Java bytes, some companies are dedicate on accelerating the bytecode. JIT (just in time) interpreter is one of the technology that are widely adapted into the commercial Web browser. JIT interpreter usually load the Java bytecodes preprocess it into system-specific code in a dynamically fashion and then execute the system-specific code directly.

    3. Benchmark
    4. I wrote a simple Java benchmark program:

      import java.applet.Applet;

       

      public class benchmark extends Applet {

      public int dummy(int i) { return i;}

      public void start() {

      int i, x;

      x = 0;

      System.out.println("Benchmark Start");

      long b1 = System.currentTimeMillis(), b2;

      for (i=0; i<100000000; i++) {

      }

      b2 = System.currentTimeMillis();

      System.out.println("Empty For Loop "+(b2-b1));

      b1 = b2;

      for (i=0; i<100000000; i++) {

      x += i;

      }

      b2 = System.currentTimeMillis();

      System.out.println("For Loop with + and assign "+(b2-b1));

      b1 = b2;

      for (i=0; i<100000000; i++) {

      x *= i;

      }

      b2 = System.currentTimeMillis();

      System.out.println("For Loop with * and assign "+(b2-b1));

      b1 = b2;

      for (i=0; i<100000000; i++) {

      x += dummy(i);

      }

      b2 = System.currentTimeMillis();

      System.out.println("For Loop with function call and assign "+(b2-b1));

      }

      }

      Translate the Java program into C++ would be:

      #include <stdio.h>

      #include <sys/timeb.h>

       

      long currentTimeMillis() {

      struct _timeb tstruct;

      _ftime(&tstruct);

      return tstruct.time*1000+tstruct.millitm;

      }

       

      class benchmark {

      public:

      int dummy(int i) { return i;}

      void start() {

      int i, x;

      x = 0;

      printf("Benchmark Start\n");

      long b1 = currentTimeMillis(), b2;

      for (i=0; i<100000000; i++) {

      }

      b2 = currentTimeMillis();

      printf("Empty For Loop %d\n", b2-b1);

      b1 = b2 = currentTimeMillis();

      for (i=0; i<100000000; i++) {

      x += i;

      }

      b2 = currentTimeMillis();

      printf("For Loop with + and assign %d\n", b2-b1);

      b1 = b2 = currentTimeMillis();

      for (i=0; i<100000000; i++) {

      x *= i;

      }

      b2 = currentTimeMillis();

      printf("For Loop with * and assign %d\n", b2-b1);

      b1 = b2 = currentTimeMillis();

      for (i=0; i<100000000; i++) {

      x += dummy(i);

      }

      b2 = currentTimeMillis();

      printf("For Loop with function call and assign %d\n",

      b2-b1);

      }

      };

       

      void main() {

      benchmark bm;

      bm.start();

      }

      The test data are following (Test on PC with AMD-233MHZ CPU, Win95) :

      Units (ms)

      for loop 108

      x += i

      x *= i

      x += dummy(i)

      C++, VC++

      0 *

      880

      1810

      880

      JDK 1.1

      29000

      50420

      51300

      110730

      JDK 1.0

      43830

      82340

      83210

      170210

      IE 4.0

      42400

      63330

      63820

      175550

      IE 4.0 (JIT)

      0*

      930

      2250

      9010

      Netscape 4.05

      940

      1810

      2690

      8510

      * Optimized and eliminated by compiler or interpreter.

      Units (us/loop)

      for loop

      x += i

      x *= i

      x += dummy(i)

      C++, VC++

      0 *

      0.0088

      0.0181

      0.0088

      JDK 1.1

      0.29

      0.5042

      0.513

      1.1073

      JDK 1.0

      0.4383

      0.8234

      0.8321

      1.7021

      IE 4.0

      0.424

      0.6333

      0.6382

      1.7555

      IE 4.0 (JIT)

      0*

      0.0093

      0.0225

      0.0901

      Netscape 4.05

      0.0094

      0.0181

      0.0269

      0.0851

      * Optimized and eliminated by compiler or interpreter.

    5. Benchmark Analyze
    6. Base on the nature of the object oriented programming, the function call is a must. The class interface are actually functions associated with objects. From the table above we learn that the most advanced commercial browser's Java interpreter are above 10 times slower than compiled C++ code when a function call is involved in the loop. And when the Java interpreter doesn't equip with JIT, the ratio become unacceptable slow (around 200 times slower). And this is only a very simple benchmark program. When it comes to large application, the JIT will tends to have worse performance because it has limited buffer for compiled code. If the whole application is too large to be compiled before it execute, the JIT interpreter will have to compile section by section on the fly and slow down the execution speed. I estimate the JIT will run about 20 times slower than compiled C++ code when application is relatively large.

    7. Conclusion

    Eighteen months ago, when I start to design the forth generation of NeatTools project, I insist to use C++ instead of Java. The top reason for that is speed. At that time, the JIT technology is not mature yet. Even today the JIT Java interpreter is still not fast enough for mission critical and calculate intensive real-time task like compress/decompress of voice and video data. The only chance that Java's speed will comparable with C++ is Java chip which could execute Java bytecode directly. But it will be a while before the product become popular and inexpensive. There are some other solutions such as link native code into Java program or using tools to convert Java bytecode into native code, etc. But again, these alternatives lost the portability that Java bytecode provide. To avoid all those trouble and overhead, I use C++ and build the Cross Platform API (please reference the Appendix NeatTools Architecture section) which let C++, an already robust and industry standard language, become easy to port on different platform and also equip it with a multi-threaded GUI capable programming interface. I think I made the right decision for this project.

  3. NeatTools Architecture Analyze
  4. In NeatTools, the most important concept are the module abstraction. The module abstraction simplify and model all the interactions between module into active actions and reactive actions. Later in this section, I discuss the implementation concept and present some benchmark information and analyze it.

    1. Module Abstraction
    2. In NeatTools, module abstraction is offered as a set of class methods that provides inter-module communication functionality. Functional components (implemented as class objects) of a concurrent system are written as encapsulated modules that act upon local data structures, or objects inside object classes, some of which may be broadcast for external use. Relationships among modules are specified by logical connections among their broadcast data structures. Whenever a module updates data and wishes to broadcast the change, and make it visible to other connected modules, it should implicitly call an output service function which will broadcast the target data structure according to the configuration of logical connections. Upon receiving the message event, the connected modules execute its action engine according to the remote data structure. Thus, output is essentially a byproduct of computation, and input is handled passively, treated as an instigator of computation.

      This approach simplifies module programming by cleanly separating computation from communication. Software modules written using module abstraction do not establish or effect communication, but instead are concerned only with the details of the local computation. Communication is declared separately as logical relationships among the state components of different modules.

      This programming model has its roots in the formal Input / Output automaton model of Lynch and Tuttle [1]. An I/O automaton is a state machine with a signature consisting of a set of input actions and a set of locally controlled actions. The locally controlled actions could divide into output actions and internal actions. Locally controlled actions are under the control of the automaton, while input actions may occur at any time. Automata may be composed such that when an output action of one automaton occurs, all automata having a same-named action as an input action make a state transition simultaneously. A behavior of an I/O automaton is a sequence of input and output actions that may occur in an execution of that automaton. The module abstraction programming model is designed to benefit from the useful characteristics of the I/O automaton model that are helpful in reasoning formally about distributed systems.

      Module abstraction is based on three fundamental concepts: data, actions, and connections. It is difficult to discuss these concepts in detail without reference to particular mechanisms for supporting them. Therefore, we present them in the context of NeatTools, a software package, run-time system and visual programming environment we have designed to support the development of data flow network applications using module abstraction.

      1. Data
      2. Data (the components of a module's state, could be data structures or objects) may be kept private or they may be broadcast when needed so that other modules may access the data. NeatTools provides a base abstract class object that declares the basic data structure and service procedures (or methods). Every module object should inherit from this class object and override some of the predefined procedures to serve the different computational and presentational needs of each module. NeatTools provides a library of data types for declaring data that may be broadcast. These include integer, real, string, block, byte array, midi event, voice stream, and video stream. The module programmer may define others.

        1. The presentation
        2. Each NeatTools module has a presentation that presents itself to the user as the visual feedback. It could be graphics images, shapes, or text. The presentation may change dynamically according the current state. Associated with each data item are a public name, property, access privileges, and data type. This information helps a user understand its presentation. The data type and access privileges also permit type check and privilege match of logical connections.

        3. Access privilege
        4. Access privileges include input, output, insert, and connect. Output access allows connected modules to observe the value of the data when broadcast event message. Input access allows a module to change the state of the target module. Insert access allows a new connection to be inserted into an aggregate item of a module. Connect access allows a module to relate the data item to a data item of some other module. All those access privileges are controlled by a set of class methods (already defined in the base abstract class). By overriding those methods, modules could change the behavior or dynamically control access behavior according the current state of module.

        5. The desktop

        A NeatTools module interacts with a desktop and a collection of other modules that may be unknown to this module but that read and modify the data item in its presentation when permitted by the access privileges. The desktop also works as a graphical user interface front end that provides a user with a set of layout service functions, including move, resize, copy, delete, group, ungroup, connection management, object persistency management and file input/output.

      3. Actions
      4. The action portion of a module defines how its state changes over time and responds to an environment. Insulated from the structure of its environment, a NeatTools module interacts entirely through the broadcast service procedure and reactive execution engine procedure. A module may autonomously modify its local state, and it may react to the incoming events and change its local state. This suggests a natural division of the actions into two parts: active action and reactive action.

        1. Active (Output) action
        2. The active action carries out the ongoing computation of the module. For example, in a discrete event simulation, the active action would be iterative computation that simulates each event. External updates of simulation parameters could affect the course of future iterations, but would not require any special activity at the time of each change. Modules with only active action can be quite elegant since input simply steers the active computation without requiring a direct response. Active action is analogous to the locally controlled actions of an I/O automaton.

        3. Reactive (Input) action

        The reactive action carries out activities in response to input from the environment. A module with primarily reactive action simply reacts to input from the environment, updating its local state and presentation as dictated by the input change. For example, a data visualization module could be constructed so that each time some data element changes, the visualization is updated to reflect the change. In the above discrete event simulation, one might add reactive action to check the consistency of simulation parameters that are modified by the environment. Reactive action is analogous to the input actions of an I/O automaton.

      5. Connections

      Relationships between data items of different modules are declared with logical connections between those data items. These connections define the communication pattern of the system. Connections are established by a special NeatTools module, called a desktop, that enforces type compatibility across connections and guards against access protection violations by establishing only authorized connections.

      Connections are declared separately from modules so that one can design each module with a local orientation and later connect them together in various ways. Connections are designed to accommodate all kinds of data types varying from integer, real to audio and video. The run-time system could handle the communication requirements automatically according to the module abstraction of the module.

      If we liken the data items of a NeatTools module to the actions in the signature of an I/O automaton, then just as like-named actions in automaton signatures define the sharing of actions, connections define the sharing of state change information. Currently, a simple synchronous data transmission algorithm is used by the broadcast service procedure. The reactive action engine of a connected module will be invoked and executed automatically. However, if asynchronous data transmission is needed, user could construct a data queue inside the module and react to the data queue later. This way, we can keep the general communication structure simple and efficient.

    3. Implementation Concept
    4. NeatTools' design concept is base on a different aspect of application design which provide visual programming capacity. In traditional textual programming design, lines of code are the rough measure of program size. In visual programming design like NeatTools data flow network, number of connections and modules become the major indications. So how NeatTools provide an efficient way to broadcast and process message events between modules become the most important issue. In NeatTools every modules are already class objects. The only object interoperability are simplified into active and reactive actions, or connections. In order to increase the application throughput, the connections in NeatTools are just logical reference. The message broadcast are actually perform by direct function call to ensure the performance of NeatTools' data flow network. For those remote message passing between NeatTools and remote computer running NeatTools, they performed by Socket and ServerSocket modules (just like regular modules, but they perform different task) to handle all the data communication task (usually on top of TCP/IP which is slow compare to direct function call). Connections between Socket and other modules are still the same efficient function call. So, instead of network connection oriented design (like CORBA), NeatTools use direct function call oriented design and eliminate all possible overhead and layers.

    5. Benchmark Information on NeatTools
    6. I wrote a special benchmark module in NeatTools. Which has two inputs and one output. The one on top can enabled and start the benchmark. The one on left can receive message event from other benchmark module but do nothing. When the module is enabled, it will start the benchmark by broadcast events through its output port in a 106 loop and then display the time interval in the debug dialog box. The benchmark here is focus on the overhead of message broadcasting in NeatTools.

      The engine method of the benchmark module was implemented as following:

      void JBenchmarkObj::engine(int n, JLinkObj& link) {

      if (!n) {

      // link.access(JIntegerData(v[0]));

      } else {

      int oldv = v[1];

      link.access(JIntegerData(v[1]));

      v[1] = (v[1] != 0);

      if ((v[1] != oldv) && !v[1]) {

      int time = JSystem::currentTimeMillis();

      for (int i=0; i<1000000; i++)

      broadcast(0);

      time = JSystem::currentTimeMillis()-time;

      JComponent::debug(JInteger::toJString(time)+" ms");

      }

      }

      }

      The NeatTools benchmark data flow network are arranged as following:

      The five test modules are instances of benchmark module. One of them connects its enabled input from button and its output connects to the rest of the test modules.

    7. Benchmark Analyze on NeatTools
    8. The benchmark data for this particular data flow network running on my PC (AMD-233MHZ CPU, Win95) is 2200 ms. Because the output has four connections and the broadcast process are repeated for 106 times. So 2200 ms / 4 / 106 become 0.55 us per connection broadcast which is just 6.25 times slower compare to the direct function call with only one statement. In other word, NeatTools is capable of dispatch around 1,800,000 messages in one second. At this speed, I believe NeatTools could handle most real-time or calculate intensive task on the data flow network level.

    9. Conclusion

    The contribution of this section is focus on how I proposed an abstract module model. Base on this model, I proposed a simplified and high performance way to implement the module connections and how we map the connections into directly function call without much overhead and layers. This model proved to be successfully implement in the NeatTools project. Currently, we have a lot of NeatTools data flow networks on data collection, gesture recognition, control of external devices, virtual world control, remote collaboration, and perceptual modulation. With the scalable design of NeatTools project, I believe NeatTools could be widely adapted to almost any real world problems and provide complete and fast solutions.

  5. NeatTools and Object Management Environments
    1. CORBA
    2. Object Managements Group (OMG)'s Object Management Architecture (OMA): the multi-vendor standard for object-oriented distributed computing. This includes CORBA -- the Common Object Request Broker Architecture -- which most people associated with OMG; the CORBAservices and CORBAfacilities.

      1. Object Definition
      2. Objects are discrete software components -- they contain data, and can manipulate it. Usually, they model real-world objects, although sometimes it's useful to create objects specifically for things we want to compute. Other software components send messages to objects with requests; the objects send other messages back with their responses.

      3. CORBA provide Object Interoperability
      4. In order for objects to plug and play together in a useful way, clients have to know exactly what they can expect from every object they might call upon for a service. In CORBA, the services that an object provides are expressed in a contract that serves as the interface between it and the rest of our system. The interfaces are expressed in OMG Interface Definition Language -- OMG IDL -- making them accessible to objects written in virtually any programming language, and the cross-platform communications architecture is the Common Object Request Broker Architecture -- CORBA.

      5. OMA provide Application-Level Integration

      Base on CORBA architecture, the OMA specifies a set of standard interfaces and functions for each component. Different vendors' implementations of the interfaces and their functionality then plug-and-play on customers' networks, allowing integration of additional functionality from purchased modules or in-house development.

      The OMA is divided into two major components: lower-level CORBAservices and intermediate-level CORBAfacilities. The CORBAservices provide basic functionality that almost any object might need: object lifecycle services such as move and copy, naming and directory services, and other basics. The CORBAfacilities architecture has two major components: one, horizontal, including facilities such as compound document services which can be used by virtually every business; and the other, vertical, standardizing management of information specialized to particular industry groups.

    3. COM/DCOM
    4. COM (Component Object Model) is a software architecture that enables program to be built from smaller binary components. It is a binary standard for component interoperability and is independent of programming language.

      COM supports a client/server model between the user of some object's services and the implementers of that object and its services. COM's role is to establish the connection between the client and the server, which offers the desired object. Once the connection has been made, COM is out of the picture and all communication goes directly from server to client and vice versa.

      1. Objects and Interfaces
      2. In COM an object is an instance of a class which as in standard OO terminology is a set of data and related functionality. Unlike most other OO models, COM provides no direct access to object data. Instead user have to access member functions of an associated interface.

        An interface is a set of functions that can be invoked on a given object. Interfaces do not contain any implementation what so ever, but merely defines the expected behavior of an object. When an object implements an interface, it provides implementations for every function in the interface, and provides pointers to those functions to COM.

      3. Interface Description Language (IDL)
      4. COM's Interface Description Language (IDL) is base on the Open Software Foundation (OSF) Distributed Computing Environment (DCE) specification for describing interfaces, operations, and attributes to define remote procedure calls.

        A designer can define a new custom interface by writing an interface definition file. The interface definition file use the IDL to describe data types and member functions of an interface. The interface definition file contains the information that defines the actual contract between the client application and server object.

      5. Service Control Manager (SCM)

      The SCM is a COM component that is able to locate a given server and launch it. The SCM contains a database of class information. When a client requests the COM library to create an object, the SCM is launched, the server located and run. Here SCM provide the object interoperability.

    5. Compare COBRA and COM/DCOM
    6. From the communication point of view, COM is a little bit different from CORBA. In CORBA, ORB is always the gateway between its object client and server. The client and server in CORBA never communicate each other directly. In COM, SCM locate and lunch the object server for application client and then the client communicate directly with the server. Also COM has different mechanisms for in-process, cross-process, and remote object server. In in-process case, the SCM will locate and load the object server as a DLL. So in this situation, the object server will be executed in the client's process space which is much faster than COBRA's mechanism. In cross-process case, the SCM will locate and load the object server as an executable. The object server will be executed in a separate process space. So it is slower than the DLL but still faster then the COBRA's mechanism. Even in remote object server case, the SCM will contact the remote SCM and later on build a remote proxy server which can forward requests directly to the remote SCM via the RPC connection. So, in general, COM/DCOM have better performance over COBRA. But COBRA have better sense base on system and structure concern. For example, a COBRA's object server will only deal with its local ORB. But a DCOM's object will have to deal with local SCM, in-process client, cross-process client, and remote client.

      From the application point of view, COM is lack of application integration packages. COBRA's CORBAservices and CORBAfacilities components provide the application-level integration which provide lower-level and intermediate-level services for industry and business applications.

    7. Benchmark Information on CORBA
    8. The most important advantage that Object Management Environments like CORBA, and COM/DCOM is the object interoperability. The object interoperability make objects to plug and play together in a useful way become possible. But the advantage comes with the price -- speed. For example, in CORBA, when an object client issue a function call to a remote server object, it has to go through the IDL Stub (created by IDL), Object Request Broker (ORB), remote ORB, IDL Skeleton, and finally reach the remote server object implementation. And in most case it go through the network communication layer like TCP/IP at least twice (forward the request and send back the result message) to complete a function call.

      I visited one of the ORB vender site which has a web page dedicate to the performance information. URL for this page is http://www.orl.co.uk/omniORB/omniORBPerformance.html. On this page, one of the table are following:

      Performance of omniORB2 on various platforms.

      Platform

      Transport

      Protocol

      us/call

      Linux Pentium Pro 200 MHz

      IP/intra-machine

      IIOP

      340

       

      IP/ethernet (ISA)

      IIOP

      1000

       

      IP/ATM

      IIOP

      440

       

      AAL5/ATM

      IIOP

      350

      Windows NT Pentium Pro 200 MHz

      IP/intra-machine

      IIOP

      360

       

      IP/ethernet (ISA)

      IIOP

      1000

      Digital Unix 3.2 Alpha DEC 3000

      IP/intra-machine

      IIOP

      750

       

      IP/ethernet

      IIOP

      1050

      Windows '95 Pentium 166 MHz

      IP/intr-machine

      IIOP

      1000

       

      IP/ethernet (PCI)

      IIOP

      1250

      Solaris 2.51 Ultra 1 167 MHz

      IP/intra-machine

      IIOP

      540

       

      IP/ethernet

      IIOP

      710

    9. Benchmark Analyze on CORBA
    10. From the table above, to make a function call, even the function call is made within the machine (the IP/intr-machine), it make about 360 us on a Pentium Pro 200MHz machine. If we compare the benchmark information with the previous section, make a direct function call in compiled C++ code only take 0.0088 us which is about 41,000 times faster than make a function calls on this particular ORB. For those call that are made remotely by direct network card connection (the IP/ethernet), it take 1,000 us to make a function calls. In that case it is about 114,000 times slower than the compiled C++ code.

    11. Conclusion

    CORBA and COM/DCOM provide the object interoperability which is a great feature for object plug and play and object reusability. But this functionality comes with a big draw back -- decrease the performance in a huge fashion especially in CORBA. In COM/DCOM, the performance problem is lesser. It is possible that NeatTools project build upon CORBA or COM/DCOM architecture. NeatTools module designer will be able to put the modules on line and let user access it remotely. But, NeatTools will have to limit data flow design with modules which does not require a lot of message event passing. For those fine grain modules such as digital logic, number, and real number operation module, decrease the message passing speed will hurt the performance a lot. In this case, we won't be able to build data flow network in NeatTools complex enough to meet the requirements as a general human interface tool.

  6. NeatTools and Modeling Languages
    1. Colored Petri-Net
    2. Colored Petri-Net (CP-nets or CPN) is a graphical oriented language for design, specification, simulation and verification of systems. It is in particular well-suited for systems witch communication, synchronization and resource sharing are important. Typical examples of application areas are communication protocols, distributed systems, imbedded systems, automated production systems, work flow analysis and VLSI chips.

    3. UML (Unified Modeling Language)
    4. The Unified Modeling Language (UML) is a language for specifying, visualizing, constructing, and documenting the artifacts of software systems, as well as for business modeling and other non-software systems. The UML represents a collection of best engineering practices that have proven successful in the modeling of large and complex systems.

       

    5. Conclusion
  7. NeatTools and Other Visual Programming Tools
    1. Visual C++
    2. Visual Basic
    3. Java Bean
    4. J++
    5. LabView
    6. AVS
    7. Conclusion
  8. NeatTools' Visual Programming Features
    1. Multimedia Database
    2. Transfer Focus among Text Fields
    3. Polymorph Data Type
    4. Container Nest Structure (Complex Module)
    5. Data Flow Controls
    6. Multimedia Features
    7. Multi-Thread Features
    8. Keyboard and Mouse Event Simulator/Filter
    9. One of most important issue in fast prototyping with existing program is that if we can build a Keyboard or Mouse event simulator. By transfer the action into simulated keyboard or mouse events, the existing program will think that the keystroke or mouse movement is coming from user interaction.

    10. External Module and Dynamic Link Library
    11. Modules for External Devices
    12. Networking and TCP/IP
    13. State Machine
  9. Examples/Applications
  10. Conclusion
  11. Appendix
    1. NeatTools Reference Manual
      1. NeatTools Module Specification:
      2.  

        Name: NOTObj

        Input: "input" integer port on the left edge with unlimited connections.

        Output: "output" integer port on the right edge with unlimited connections.

        Function: Calculate the bit wise NOT operation on the input values and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color. "N Bits" set the operation width. When it is one, it become the logical (1-bit) NOT operation. When it is 16, it will become the 16 bit wise NOT operation.

        Name: ANDObj

        Input: "input" integer port on the left edge with unlimited connections.

        Output: "output" integer port on the right edge with unlimited connections.

        Function: Calculate the bit wise AND operation on the input values and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color. "N Bits" set the operation width. When it is one, it become the logical (1-bit) AND operation. When it is 16, it will become the 16 bit wise AND operation.

        Name: ORObj

        Input: "input" integer port on the left edge with unlimited connections.

        Output: "output" integer port on the right edge with unlimited connections.

        Function: Calculate the bit wise OR operation on the input values and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color. "N Bits" set the operation width. When it is one, it become the logical (1-bit) OR operation. When it is 16, it will become the 16 bit wise OR operation.

        Name: XORObj

        Input: "input" integer port on the left edge with unlimited connections.

        Output: "output" integer port on the right edge with unlimited connections.

        Function: Calculate the bit wise XOR operation on the input values and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color. "N Bits" set the operation width. When it is one, it become the logical (1-bit) XOR operation. When it is 16, it will become the 16 bit wise XOR operation.

        Name: GreaterThanObj

        Input: "input-1" integer port on the left edge and "input-2" integer port on the top edge with maximum one connection.

        Output: "output" integer port on the right edge with unlimited connections.

        Function: Compare the value of "input-1" and "input-2" and broadcast the result value to "output" port when receiving an input event. Result value is true when "input-1" is larger "input-2", false otherwise.

        Properties: "moduleColor" set the background color. "N Bits" set the operation width. When it is one, it become the logical operation (true=1, false=0). When it is 16, it will become the 16 bit operation (true=0xFFFF, false=0x0000).

        Name: GreaterEqualObj

        Input: "input-1" integer port on the left edge and "input-2" integer port on the top edge with maximum one connection.

        Output: "output" integer port on the right edge with unlimited connections.

        Function: Compare the value of "input-1" and "input-2" and broadcast the result value to "output" port when receiving an input event. Result value is true when "input-1" is greater or equal "input-2", false otherwise.

        Properties: "moduleColor" set the background color. "N Bits" set the operation width. When it is one, it become the logical operation (true=1, false=0). When it is 16, it will become the 16 bit operation (true=0xFFFF, false=0x0000).

        Name: EqualObj

        Input: "input-1" integer port on the left edge and "input-2" integer port on the top edge with maximum one connection.

        Output: "output" integer port on the right edge with unlimited connections.

        Function: Compare the value of "input-1" and "input-2" and broadcast the result value to "output" port when receiving an input event. Result value is true when "input-1" is equal "input-2", false otherwise.

        Properties: "moduleColor" set the background color. "N Bits" set the operation width. When it is one, it become the logical operation (true=1, false=0). When it is 16, it will become the 16 bit operation (true=0xFFFF, false=0x0000).

        Name: NotEqualObj

        Input: "input-1" integer port on the left edge and "input-2" integer port on the top edge with maximum one connection.

        Output: "output" integer port on the right edge with unlimited connections.

        Function: Compare the value of "input-1" and "input-2" and broadcast the result value to "output" port when receiving an input event. Result value is true when "input-1" is not equal "input-2", false otherwise.

        Properties: "moduleColor" set the background color. "N Bits" set the operation width. When it is one, it become the logical operation (true=1, false=0). When it is 16, it will become the 16 bit operation (true=0xFFFF, false=0x0000).

        Name: AddObj

        Input: "input" integer port on the left edge with unlimited connections.

        Output: "output" integer port on the right edge with unlimited connections.

        Function: Calculate the sum of all the input values and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

        Name: MultiplyObj

        Input: "input" integer port on the left edge with unlimited connections.

        Output: "output" integer port on the right edge with unlimited connections.

        Function: Multiply all the input values and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

        Name: SubstractObj

        Input: "input-1" integer port on the left edge and "input-2" integer port on the top edge with maximum one connection.

        Output: "output" integer port on the right edge with unlimited connections.

        Function: Calculate "input-1" - "input-1" and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

        Name: DivideObj

        Input: "input-1" integer port on the left edge and "input-2" integer port on the top edge with maximum one connection.

        Output: "output" integer port on the right edge with unlimited connections.

        Function: Calculate "input-1" / "input-2" and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

        Name: AbsObj

        Input: "input" integer port on the left with maximum one connections.

        Output: "output" integer port on the right edge with unlimited connections.

        Function: Calculate ABS("input") and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

         

        Name: PowObj

        Input: "input-1" integer port on the left edge and "input-2" integer port on the top edge with maximum one connection.

        Output: "output" integer port on the right edge with unlimited connections.

        Function: Calculate "input-1" ^ "input-2" and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

        Name: MaxObj

        Input: "input" integer port on the left edge with unlimited connections.

        Output: "output" integer port on the right edge with unlimited connections.

        Function: Choose the maximum input value and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

        Name: MinObj

        Input: "input" integer port on the left edge with unlimited connections.

        Output: "output" integer port on the right edge with unlimited connections.

        Function: Choose the minimum input value and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

        Name: RemainObj

        Input: "input-1" integer port on the left edge and "input-2" integer port on the top edge with maximum one connection.

        Output: "output" integer port on the right edge with unlimited connections.

        Function: Calculate "input-1" % "input-2" and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

        Name: RandomObj

        Input: "control(logical)" integer port on the top edge with maximum one connection.

        Output: "output" integer port on the right edge with unlimited connections.

        Function: When detect a raise edge signal event (from false to true) on the "control(logical)" port, this module will generate a random integer number and broadcast the result value to "output" port.

        Properties: "moduleColor" set the background color. "N Bits" set the operation width. When it is one, it will generate only logical (1-bit) value (true, or false). When it is 16, it will generate the 16 bit wise value (from 0 to 0xFFFF).

        Name: ControlObj

        Input: "N(1-512)" and "control(logical)" integer port on the top edge and "in-0", "in-1", ..."in-(N-1)" polymorph ports on the left edge with maximum one connection.

        Output: "out-0", "out-1", ..."out-(N-1)" polymorphs port on the right edge with unlimited connections.

        Function: "N(1-512)" will determine the number of input-output pair. When detect a raise edge signal event (from false to true) on the "control(logical)" port, this module will connect the input-output pairs. So when there are input events presented on say "in-k", this module will transmit them into the corresponding "out-k" output port.

        Properties: "moduleColor" set the background color. "N(1-512)" set the number of the input-output pair.

        Name: SampleObj

        Input: "N(1-512)" and "control(logical)" integer port on the top edge and "in-0", "in-1", ..."in-(N-1)" polymorph ports on the left edge with maximum one connection.

        Output: "out-0", "out-1", ..."out-(N-1)" polymorphs port on the right edge with unlimited connections.

        Function: "N(1-512)" will determine the number of input-output pair. When detect a raise edge signal event (from false to true) on the "control(logical)" port, this module will sample the current input value from input port say "in-k" and transmit into the corresponding "out-k" output port.

        Properties: "moduleColor" set the background color. "N(1-512)" set the number of the input-output pair.

        Name: PulseObj

        Input: "input(logical)" integer port on the left edge with maximum one connection.

        Output: "output" integer port on the right edge with unlimited connections.

        Function: When receiving an input event, this module will generate an true-false event pair to the "output" port.

        Properties: "moduleColor" set the background color. "N Bits" set the operation width. When it is one, it become the logical operation (true=1, false=0). When it is 16, it will become the 16 bit operation (true=0xFFFF, false=0x0000).

        Name: DelayObj

        Input: "input(logical)" integer port on the left edge with maximum one connection.

        Output: "output" integer port on the right edge with unlimited connections.

        Function: When receiving an input event, this module will hold the value and broadcast the value when next input event comes in.

        Properties: "moduleColor" set the background color.

        Name: AccumulatorObj

        Input: "enable(logical)" integer port on the top edge and "clock(logical)" integer port on the left edge with maximum one connection.

        Output: "output" integer port on the right edge with unlimited connections.

        Function: When receiving a raise signal (from false to true) event on "clock" port and current value of "enable" port is true, this module will increase the internal integer accumulator and broadcast the value to the "output" port. If receive a drop signal (from true to false) event on "enable" port, the internal integer accumulator will reset to zero and broadcast the value to the "output" port.

        Properties: "moduleColor" set the background color.

        Name: MultiplexerObj

        Input: "N(2-512)" and "select" integer port on the top edge and "in-0", "in-1", ..."in-(N-1)" polymorph ports on the left edge with maximum one connection.

        Output: "output" polymorphs port on the right edge with unlimited connections.

        Function: "N(2-512)" will determine the number of input port. When receiving an input event on "select" port say k, this module will connect the selected "in-k" input port to "output" port. So when there are input events presented on "in-k" port, this module will transmit them into the "output" port.

        Properties: "moduleColor" set the background color. "N(2-512)" set the number of the input port. "select (0-(N-1))" set the current selected input port.

        Name: DeMultiplexerObj

        Input: "N(2-512)" and "select" integer port on the top edge and "input" polymorph ports on the left edge with maximum one connection.

        Output: "out-0", "out-1", ... "out-(N-1)" polymorphs port on the right edge with unlimited connections.

        Function: "N(2-512)" will determine the number of output port. When receiving an input event on "select" port say k, this module will connect the selected "input" input port to "out-k" port. So when there are input events presented on "input" port, this module will transmit them into the "out-k" port.

        Properties: "moduleColor" set the background color. "N(2-512)" set the number of the output port. "select (0-(N-1))" set the current selected output port.

        Name: EncoderObj

        Input: "N(2-32)" integer port on the top edge and "in-0", "in-1", ..."in-(N-1)" integer ports on the left edge with maximum one connection.

        Output: "output" integer port on the right edge with unlimited connections.

        Function: "N(2-32)" will determine the number of input port. When receiving an input event on input port, this module will encode all the output value, encode it into an integer and transmit them into the "output" port. For example, when N = 4 and the input value from "in-0", .."in-3" are 1, 0, 0, 1, this module will encode 1001 binary value into output integer value 9.

        Properties: "moduleColor" set the background color. "N(2-32)" set the number of the input port.

        Name: DecoderObj

        Input: "N(2-32)" integer port on the top edge and "input" integer ports on the left edge with maximum one connection.

        Output: "out-0", "out-1", ..."out-(N-1)" integer port on the right edge with unlimited connections.

        Function: "N(2-32)" will determine the number of input port. When receiving an input event on input port, this module will decode the input value into the decoded bit value and transmit them into the corresponding output port. For example, when N = 4 and the input value is integer 9, this module will decode it into 1001 binary value and send out 1, 0, 0, and 1 into "out-0", "out-1", "out-2", and "out-3" output ports.

        Properties: "moduleColor" set the background color. "N(2-32)" set the number of the output port.

        Name: ClockDividerObj

        Input: "N(2-512)" integer port on the top edge and "clock(logical)" integer ports on the left edge with maximum one connection.

        Output: "out-0", "out-1", ..."out-(N-1)" integer port on the right edge and "value" integer port on the bottom edge with unlimited connections.

        Function: "N(2-512)" will determine the number of output port. When receiving an raise signal (from false to true) on "clock(logical)" port, this module will increase an internal counter say k (k = 0..(N-1)) and transmit a true signal to the corresponding "out-k" output port. So when N=10, the output frequency will be 1/10 of the input frequency.

        Properties: "moduleColor" set the background color. "N(2-32)" set the number of the output port. "N Bits" set the operation width. When it is one, it will generate only logical (1-bit) value (true, or false). When it is 16, it will generate the 16 bit wise value (from 0 to 0xFFFF).

        Name: TimeObj

        Input: None.

        Output: "output" date port on the right edge with unlimited connections.

        Function: will send out date event every one second. Use the DateObj to show the current time and get the seconds, minutes, etc.

        Properties: "moduleColor" set the background color.

        Name: TimerObj

        Input: "enabled(logical)" and "interval" integer port on the top edge with maximum one connection.

        Output: "output" integer port on the right edge and "interval" integer port on the bottom edge with unlimited connections.

        Function: When "enabled" is true (default is true), this module will send out integer pulse to "output" port event every "interval" millisecond. The "interval" input and output ports are for two way communication to external integer objects. So the value will keep consist when user modify the interval by property dialog box.

        Properties: "moduleColor" set the background color. "N Bits" set the operation width. When it is one, it will generate only logical (1-bit) value (true, or false). When it is 16, it will generate the 16 bit wise value (from 0 to 0xFFFF). "delay" set the interval value in millisedond.

        Name: CalibrateObj

        Input: "calibrate(logical)", "lower" and "upper" integer port on the top edge and "input", "feedback" integer port on the left edge with maximum one connection.

        Output: "output" and "decalibrate" integer port on the right edge and "lower", "upper" integer port on the bottom edge with unlimited connections.

        Function: When "calibrate" is true, this module will adjust to the current input range of "input" and re-map the value into N bits value and broadcast it to "output" port. When "calibrate" is false, this module will not adjust to the current input range, but keep re-map the value by using the current lower and upper value. If the N bits value comes in from the "feedback" port, this module will map it back to the input range (the reverse mapping). The "lower", "upper" input and output ports are for two way communication to external integer objects. So the value will keep consist when user modify the "lower" and "upper" value by property dialog box.

        Properties: "moduleColor" set the background color. "N Bits" set the operation width. When it is one, it will generate only logical (1-bit) value (true, or false). When it is 16, it will generate the 16 bit wise value (from 0 to 0xFFFF). "fraction" set the current blank display area (on the top and bottom of display area) in percent. percent. For example, fraction=0 will use all display area, fraction=25 will have 25% blank area on the top and bottom of display area. "upper" and "lower" set the current input range set.

        Name: AvgFilterObj

        Input: "input" on the left edge with maximum one connection.

        Output: "output" integer port on the right edge with unlimited connections.

        Function: When event comes into "input" port, this module will calculate the average value of last N input value (include the current value) and broadcast the value through the "output" port. Basically, it works as a low-pass filter.

        Properties: "moduleColor" set the background color. "N" set the number of contiguous input values to average.

        Name: DelaySustainObj

        Input: "input" on the left edge with maximum one connection. "sampling-clock", "delay", and "sustain" on the top edge with maximum one connection.

        Output: "output" integer port on the right edge with unlimited connections. "delay" and "sustain" on the bottom edge with unlimited connections.

        Function: When there is a raise (false to true) event detected in "input" port, this module will delay the input value for "delay" ticks (Tick marks come from sampling-clock). When there is drop (true to false) event detected in "input" port, this module will sustain last value for "sustain" ticks. The "delay", "sustain" input and output ports are for two way communication to external integer objects. So the value will keep consist when user modify the "delay" and "sustain" value by property dialog box.

        Properties: "moduleColor" set the background color. "delay" set the number of delay ticks. "sustain" set the number of sustain ticks.

        Name: RtoIObj

        Input: "input" real number port on the left edge with maximum one connection.

        Output: "output" integer port on the right edge with unlimited connections.

        Function: Convert the "input" port's real number into integer (with rounding) and broadcast the result to "output" port.

        Properties: "moduleColor" set the background color.

        Name: ItoRObj

        Input: "input" integer port on the left edge with maximum one connection.

        Output: "output" real number port on the right edge with unlimited connections.

        Function: Convert the "input" port's integer into real number and broadcast the result to "output" port.

        Properties: "moduleColor" set the background color.

        Name: RGreaterThanObj

        Input: "input-1" real number port on the left edge and "input-2" real number port on the top edge with maximum one connection.

        Output: "output" integer port on the right edge with unlimited connections.

        Function: Compare the value of "input-1" and "input-2" and broadcast the result value to "output" port when receiving an input event. Result value is true when "input-1" is larger "input-2", false otherwise.

        Properties: "moduleColor" set the background color. "N Bits" set the operation width. When it is one, it become the logical operation (true=1, false=0). When it is 16, it will become the 16 bit operation (true=0xFFFF, false=0x0000).

        Name: RGreaterEqualObj

        Input: "input-1" real number port on the left edge and "input-2" real number port on the top edge with maximum one connection.

        Output: "output" integer port on the right edge with unlimited connections.

        Function: Compare the value of "input-1" and "input-2" and broadcast the result value to "output" port when receiving an input event. Result value is true when "input-1" is greater or equal "input-2", false otherwise.

        Properties: "moduleColor" set the background color. "N Bits" set the operation width. When it is one, it become the logical operation (true=1, false=0). When it is 16, it will become the 16 bit operation (true=0xFFFF, false=0x0000).

        Name: REqualObj

        Input: "input-1" real number port on the left edge and "input-2" real number port on the top edge with maximum one connection.

        Output: "output" integer port on the right edge with unlimited connections.

        Function: Compare the value of "input-1" and "input-2" and broadcast the result value to "output" port when receiving an input event. Result value is true when "input-1" is equal "input-2", false otherwise.

        Properties: "moduleColor" set the background color. "N Bits" set the operation width. When it is one, it become the logical operation (true=1, false=0). When it is 16, it will become the 16 bit operation (true=0xFFFF, false=0x0000).

        Name: RNotEqualObj

        Input: "input-1" real number port on the left edge and "input-2" real number port on the top edge with maximum one connection.

        Output: "output" integer port on the right edge with unlimited connections.

        Function: Compare the value of "input-1" and "input-2" and broadcast the result value to "output" port when receiving an input event. Result value is true when "input-1" is not equal "input-2", false otherwise.

        Properties: "moduleColor" set the background color. "N Bits" set the operation width. When it is one, it become the logical operation (true=1, false=0). When it is 16, it will become the 16 bit operation (true=0xFFFF, false=0x0000).

        Name: RAddObj

        Input: "input" real number port on the real number edge with unlimited connections.

        Output: "output" real number port on the right edge with unlimited connections.

        Function: Calculate the sum of all the input values and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

        Name: RMultiplyObj

        Input: "input" real number port on the left edge with unlimited connections.

        Output: "output" real number port on the right edge with unlimited connections.

        Function: Multiply all the input values and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

        Name: RSubstractObj

        Input: "input-1" real number port on the left edge and "input-2" real number port on the top edge with maximum one connection.

        Output: "output" real number port on the right edge with unlimited connections.

        Function: Calculate "input-1" - "input-1" and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

        Name: RDivideObj

        Input: "input-1" real port on the left edge and "input-2" real port on the top edge with maximum one connection.

        Output: "output" real port on the right edge with unlimited connections.

        Function: Calculate "input-1" / "input-2" and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

        Name: RAbsObj

        Input: "input" real number port on the left with maximum one connections.

        Output: "output" real number port on the right edge with unlimited connections.

        Function: Calculate ABS("input") and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

         

        Name: RPowObj

        Input: "input-1" real number port on the left edge and "input-2" real number port on the top edge with maximum one connection.

        Output: "output" integer port on the right edge with unlimited connections.

        Function: Calculate "input-1" ^ "input-2" and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

        Name: RMaxObj

        Input: "input" real number port on the left edge with unlimited connections.

        Output: "output" real number port on the right edge with unlimited connections.

        Function: Choose the maximum input value and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

        Name: RMinObj

        Input: "input" real number port on the left edge with unlimited connections.

        Output: "output" real number port on the right edge with unlimited connections.

        Function: Choose the minimum input value and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

        Name: RSinObj

        Input: "input" real number port on the left edge with maximum one connection.

        Output: "output" real number port on the right edge with unlimited connections.

        Function: Calculate SIN("input") and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

        Name: RCosObj

        Input: "input" real number port on the left edge with maximum one connection.

        Output: "output" real number port on the right edge with unlimited connections.

        Function: Calculate COS("input") and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

        Name: RASinObj

        Input: "input" real number port on the left edge with maximum one connection.

        Output: "output" real number port on the right edge with unlimited connections.

        Function: Calculate ASIN("input") and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

        Name: RACosObj

        Input: "input" real number port on the left edge with maximum one connection.

        Output: "output" real number port on the right edge with unlimited connections.

        Function: Calculate ACOS("input") and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

        Name: RTanObj

        Input: "input" real number port on the left edge with maximum one connection.

        Output: "output" real number port on the right edge with unlimited connections.

        Function: Calculate TAN("input") and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

        Name: RATanObj

        Input: "input" real number port on the left edge with maximum one connection.

        Output: "output" real number port on the right edge with unlimited connections.

        Function: Calculate ATAN("input") and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

        Name: RExpObj

        Input: "input" real number port on the left edge with maximum one connection.

        Output: "output" real number port on the right edge with unlimited connections.

        Function: Calculate EXP("input") and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

        Name: RLogObj

        Input: "input" real number port on the left edge with maximum one connection.

        Output: "output" real number port on the right edge with unlimited connections.

        Function: Calculate LOG("input") and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

        Name: RSqrtObj

        Input: "input" real number port on the left edge with maximum one connection.

        Output: "output" real number port on the right edge with unlimited connections.

        Function: Calculate SQRT("input") and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

        Name: RRoundObj

        Input: "input" real number port on the left edge with maximum one connection.

        Output: "output" real number port on the right edge with unlimited connections.

        Function: Calculate ROUND("input") and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

        Name: RCeilObj

        Input: "input" real number port on the left edge with maximum one connection.

        Output: "output" real number port on the right edge with unlimited connections.

        Function: Calculate CEIL("input") and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

        Name: RFloorObj

        Input: "input" real number port on the left edge with maximum one connection.

        Output: "output" real number port on the right edge with unlimited connections.

        Function: Calculate FLOOR("input") and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

        Name: RModObj

        Input: "input-1" real number port on the left edge and "input-2" real number port on the top edge with maximum one connection.

        Output: "output" real number port on the right edge with unlimited connections.

        Function: Calculate the reminder of "input-1"/"input-2" and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

        Name: RATan2Obj

        Input: "input-1" real number port on the left edge and "input-2" real number port on the top edge with maximum one connection.

        Output: "output" real number port on the right edge with unlimited connections.

        Function: Calculate ATAN2("input-1", "input-2") and broadcast the result value to "output" port when receiving an input event.

        Properties: "moduleColor" set the background color.

        Name: RPIObj

        Input: None.

        Output: "output" real number port on the right edge with unlimited connections.

        Function: Return PI value when requested.

        Properties: "moduleColor" set the background color.

        Name: REObj

        Input: None.

        Output: "output" real number port on the right edge with unlimited connections.

        Function: Return e value when requested.

        Properties: "moduleColor" set the background color.

        Name: RRandomObj

        Input: "control(logical)" integer port on the left edge with maximum one connection.

        Output: "output" real number port on the right edge with unlimited connections.

        Function: When detect a raise signal (from false to true) on the "control" port, this module will prepare a real random number (0-1.0) and broadcast the value to "output" port.

        Properties: "moduleColor" set the background color.

        Name: RCalibrateObj

        Input: "calibrate(logical)" integer, "lower" and "upper" real number port on the top edge and "input" real number, "feedback" integer port on the left edge with maximum one connection.

        Output: "output" integer and "decalibrate" real number port on the right edge and "lower", "upper" real number port on the bottom edge with unlimited connections.

        Function: When "calibrate" is true, this module will adjust to the current input range of "input" and re-map the value into N bits integer value and broadcast it to "output" port. When "calibrate" is false, this module will not adjust to the current input range, but keep re-map the value by using the current lower and upper value. If the N bits value comes in from the "feedback" port, this module will map it back to the input range (the reverse mapping). The "lower", "upper" input and output ports are for two way communication to external integer objects. So the value will keep consist when user modify the "lower" and "upper" value by property dialog box.

        Properties: "moduleColor" set the background color. "N Bits" set the operation width. When it is one, it will generate only logical (1-bit) value (true, or false). When it is 16, it will generate the 16 bit wise value (from 0 to 0xFFFF). "fraction" set the current blank display area (on the top and bottom of display area) in percent. percent. For example, fraction=0 will use all display area, fraction=25 will have 25% blank area on the top and bottom of display area. "upper" and "lower" set the current input range set.

        Name: SKeyboardObj

        Input: "input" string port on the left edge with maximum one connection.

        Output: "output" string number port on the right edge with unlimited connections.

        Function: This module will generate string event with exact one character when user press a key. It works even NeatTools is minimized or in the background. If user supply a string event into the "input" port, it will simulate the keyboard event (just like someone is typing the keyboard) to the windows system. This function will only work when NeatTools is in background to avoid feedback problems.

        Properties: "moduleColor" set the background color.

          etc.

        Name: KeyboardObj

        Input: "stroke(logical)" integer port on the left edge and "depress(logical)" integer port on the top edge with maximum one connection.

        Output: "output" string number port on the right edge with unlimited connections.

        Function: This module will generate integer event when a key that match this module pressed. It works even NeatTools is minimized or in the background. If user supply a true integer event into the "stroke(logical)" port, it will simulate a stroke keyboard event (just like someone press and then release the key) to the windows system. If user supply a raise integer event (from false to true ) into the "depress(logical)" port, it will simulate a depress keyboard event (just like someone press the key) to the windows system. If user supply a drop integer event (from true to false) into the "depress(logical)" port, it will simulate a release keyboard event (just like someone release the key) to the windows system. These functions will only work when NeatTools is in background to avoid feedback problems.

        Properties: "moduleColor" set the background color. "N Bits" set the operation width. When it is one, it will generate only logical (1-bit) value (true, or false). When it is 16, it will generate the 16 bit wise value (from 0 to 0xFFFF).

         

        Name: MixerObj

        Input: "input-L/Mono" integer port on the left edge and "input-R" integer port on the top edge with maximum one connection.

        Output: "output-L/Mono" integer port on the right edge and "output-R" integer port on the bottom edge with unlimited connections.

        Function: This module is designed to couple the windows' multimedia control components. The "Output Volume" module will accept mono or stereo input value to change the volume level of a sound source. It also will feedback with output value that indicate the volume level of a particular sound source. It will couple the exist mixer applications. So when user change the level value in other mixer application, this module will reflect the change by send out events from output ports. When the module show gray text, it indicate that your system does not support this type of sound source.

        Properties: "moduleColor" set the background color. "N Bits" set the operation width. When it is one, it will generate only logical (1-bit) value (true, or false). When it is 16, it will generate the 16 bit wise value (from 0 to 0xFFFF).

         

        Name: MixerObj

        Input: "input " integer port on the left edge with maximum one connection.

        Output: "output" integer port on the bottom edge with unlimited connections.

        Function: This module is designed to couple the windows' multimedia control components. The "Output Mute" module will accept input value to change the state (Mute or not) of a sound source. It also will feedback with output value that indicate the state of a particular sound source. It will couple the exist mixer applications. So when user change the state of a sound source in other mixer application, this module will reflect the change by send out events from output port. When the module show gray text, it indicate that your system does not support this type of sound source.

        Properties: "moduleColor" set the background color. "N Bits" set the operation width. When it is one, it will generate only logical (1-bit) value (true, or false). When it is 16, it will generate the 16 bit wise value (from 0 to 0xFFFF).

         

        Name: MixerObj

        Input: "input-L/Mono" integer port on the left edge and "input-R" integer port on the top edge with maximum one connection.

        Output: "output-L/Mono" integer port on the right edge and "output-R" integer port on the bottom edge with unlimited connections.

        Function: This module is designed to couple the windows' multimedia control components. The "Input Volume" module will accept mono or stereo input value to change the recording level of a sound source. It also will feedback with output value that indicate the recording level of a particular sound source. It will couple the exist mixer applications. So when user change the level value in other mixer application, this module will reflect the change by send out events from output ports. When the module show gray text, it indicate that your system does not support this type of sound source for recording.

        Properties: "moduleColor" set the background color. "N Bits" set the operation width. When it is one, it will generate only logical (1-bit) value (true, or false). When it is 16, it will generate the 16 bit wise value (from 0 to 0xFFFF).

         

        Name: MixerObj

        Input: "input " integer port on the left edge with maximum one connection.

        Output: "output" integer port on the bottom edge with unlimited connections.

        Function: This module is designed to couple the windows' multimedia control components. The "Input Mute" module will accept input value to change the state (Mute or not) of a sound source's recording. It also will feedback with output value that indicate the state of a particular sound source's recording. It will couple the exist mixer applications. So when user change the state of a sound source in other mixer application, this module will reflect the change by send out events from output port. When the module show gray text, it indicate that your system does not support this type of sound source's mute operation.

        Properties: "moduleColor" set the background color. "N Bits" set the operation width. When it is one, it will generate only logical (1-bit) value (true, or false). When it is 16, it will generate the 16 bit wise value (from 0 to 0xFFFF).

        Name: MIDIOutObj

        Input: "input" MIDI port on the left edge and "enabled(logical)" integer port on the top edge with maximum one connection.

        Output: None.

        Function: When "enabled" is true, this module will open the assigned MIDI device and start to wait for MIDI event coming from the "input" port. When receive a MIDI event, this module will transfer it into the assigned and opened MIDI device.

        Properties: "moduleColor" set the background color. "device" set the destination MIDI device. Depend on windows' setting. It could be internal FM or external MIDI port. If it is internal FM, send in MIDI events will generate sound. If it is external MIDI port, send in MIDI events could control external MIDI instrument which connected to this hardware MIDI port.

        Name: MIDIInObj

        Input: "enabled(logical)" integer port on the top edge with maximum one connection.

        Output: "output" MIDI port on the right edge with unlimited connections.

        Function: When "enabled" is true, this module will open the assigned MIDI device and start to send out MIDI events (which coming from the hardware MIDI port or the internal MIDI device) to the "output" port.

        Properties: "moduleColor" set the background color. "device" set the destination MIDI device. Depend on windows' setting. It could be internal MIDI devise or external MIDI port. If it is external MIDI port, play notes or playback on external MIDI instrument will send in MIDI events and broadcast through "output" port.

        Name: MIDIObj

        Input: "midi-in" MIDI port on the top edge with maximum one connection. 127 notes inputs (from "Octave[0] C" to "Octave[10]G"), "channel(0-15)", "channel_pressure", "program(0-127)", "volume", "pan", "damper" and "pitch" integer port on the left edge with maximum one connection.

        Output: "midi-out" MIDI port on the bottom edge with unlimited connections. 127 notes outputs (from "Octave[0] C" to "Octave[10]G"), "channel(0-15)", "channel_pressure", "program(0-127)", "volume", "pan", "damper" and "pitch" integer port on the right edge with unlimited connections.

        Function: In order to generate MIDI event from integer event, user can use this module to create almost all type of MIDI events. When receive a MIDI event through "midi-in" port, this module will decompose the MIDI event into integer event into the related output ports.

        Properties: "moduleColor" set the background color. "N Bits" set the operation width. When it is one, it will generate only logical (1-bit) value (true, or false). When it is 16, it will generate the 16 bit wise value (from 0 to 0xFFFF).

        Name: MIDIChannelObj

        Input: "midi-in" MIDI port on the top edge with maximum one connection. "ch1-in", "ch2-in", ..., "ch15-in", and "misc-in" MIDI port on the left edge with maximum one connection.

        Output: "midi-out" MIDI port on the bottom edge with unlimited connections. "ch1-out", "ch2-out", ..., "ch15-out", and "misc-out" MIDI port on the right edge with unlimited connections.

        Function: There are 16 channel in the MIDI signal. When receive MIDI event from the "midi-in" port, this module can separate the event into the correspond output channel port. If user want a MIDI event change to anther channel, he can feed the MIDI event to say the "ch1-in" port. Then the even coming out from the "midi-out" port will have MIDI signal with channel 1 assigned.

        Properties: "moduleColor" set the background color.

        Name: MIDIFileObj

        Input: "record(logical)" integer, "play(logical)" integer, "pause(logical)" integer, "filename" string, "sequence" integer, "pos" integer, "N(1-128)" integer, and "ratio" integer port on the top edge with maximum one connection. There are MIDI ports (name and number of the MIDI ports determined by MIDI file user assigned) on the left edge with maximum one connection.

        Output: "count", "total", and "tempo" integer port on the bottom edge with unlimited connections. There are MIDI ports (name and number of the MIDI ports determined by MIDI file user assigned) on the right edge with unlimited connections.

        Function: This module could load in a MIDI file with "MID" extension and play it back or recording(Recording portion is not complete yet). When "record(logical)" receive a raise event (from false to true), it will start to recording MIDI events into assigned file. When "play(logical)" receive a raise event, it will start to play back the content of the current MIDI file. When "pause" is true, it will pause the current recording or playback action. The "filename" and "sequence" combine could use to assign the MIDI filename. When "sequence" is zero, the "filename" is the assigned filename. If "sequence" not equal to zero, say 1, the assigned filename will become "filename_1". Just change the sequence number and user could record on sequences of different files. The "pos" is the current begin event count. So user could playback from any starting position. The "N" set the

        Properties: "moduleColor" set the background color.

      3. NeatTools Class Hierarchy:

      +-JObject

      |

      +-JClipboard

      |

      +-JColor

      |

      +-JDimension

      |

      +-JEvent

      |

      +-JFontMetrics

      |

      +-JInsets

      |

      +-JLayoutManager

      | |

      | +-JBorderLayout

      | |

      | +-JFlowLayout

      | |

      | +-JGridLayout

      |

      +-JPoint

      | |

      | +-JRect

      | |

      | +-JComponent

      | |

      | +-JCanvas

      | | |

      | | +-JLabel

      | | | |

      | | | +-JButton

      | | | | |

      | | | | +-JPushButton

      | | | | | |

      | | | | | +-JThumb

      | | | | | |

      | | | | | +-JTriangleButton

      | | | | |

      | | | | +-JToggleButton

      | | | | |

      | | | | +-JModuleButton

      | | | |

      | | | +-JTextField

      | | |

      | | +-JListBox

      | | |

      | | +-JRuler

      | | |

      | | +-JScroller

      | | |

      | | +-JSeparator

      | | |

      | | +-JAbout

      | | |

      | | +-JModuleCanvas

      | |

      | +-JDialog

      | |

      | +-JModal

      | | |

      | | +-JMessageBox

      | | |

      | | +-JColorBox

      | | |

      | | +-JInputBox

      | | | |

      | | | +-JFileBox

      | | | |

      | | | +-JIntegerBox

      | | |

      | | +-JIntegerListBox

      | | |

      | | +-JPropertyBox

      | |

      | +-JPanel

      | |

      | +-JWindow

      |

      +-JBlockInputStream

      |

      +-JBlockOutputStream

      |

      +-JFile

      |

      +-JFilterInputStream

      | |

      | +-JBufferedInputStream

      |

      +-JFilterOutputStream

      | |

      | +-JBufferedOutputStream

      |

      +-JPipedStream

      |

      +-JBoolean

      |

      +-JCharacter

      |

      +-JDouble

      |

      +-JFloat

      |

      +-JInteger

      |

      +-JLong

      |

      +-JMath

      |

      +-JPObject

      | |

      | +-JObjectPtr

      |

      +-JReference

      | |

      | +-JFont

      | |

      | +-JGraphics

      | |

      | +-JImage

      | |

      | +-JRegion

      | |

      | +-JBlock

      | |

      | +-JCriticalSection

      | |

      | +-JDescriptor

      | | |

      | | +-JColor

      | | |

      | | +-JFileInputStream

      | | | |

      | | | +-JFileIOStream

      | | |

      | | +-JFileOutputStream

      | | |

      | | +-JSocket

      | | | |

      | | | +-JServerSocket

      | | |

      | | +-JSocketInputStream

      | | |

      | | +-JSocketOutputStream

      | |

      | +-JProcess

      | |

      | +-JString

      | |

      | +-JThread

      | |

      | +-JArray

      | |

      | +-JList

      | |

      | +-JDList

      |

      +-JSystem

      |

      +-JThrowable

      | |

      | +-JError

      | |

      | +-JException

      | |

      | +-JIOException

      | | |

      | | +-JEOFException

      | | |

      | | +-JInterruptedIOException

      | | |

      | | +-JClassReferenceException

      | | |

      | | +-JSocketException

      | | |

      | | +-JUnknownHostException

      | |

      | +-JRuntimeException

      | |

      | +-JArithmeticException

      | |

      | +-JIllegalArgumentException

      | |

      | +-JNullPointerException

      | |

      | +-JProcessCreateException

      | |

      | +-JThreadCreateException

      |

      +-JDataType

      | |

      | +-JBlockData

      | | |

      | | +-JBytesData

      | | |

      | | +-JVideoData

      | | |

      | | +-JWaveData

      | |

      | +-JIntegerData

      | | |

      | | +-JColorData

      | | |

      | | +-JDateData

      | | |

      | | +-JMIDIData

      | |

      | +-JRealData

      | |

      | +-JStringData

      |

      +-JFDimension

      |

      +-JFPoint

      | |

      | +-JFRect

      | |

      | +-JViewObj

      | |

      | +-JGuideObj

      | |

      | +-JLineObj

      | |

      | +-JModuleObj

      | | |

      | | +-JColorObj

      | | |

      | | +-JLEDObj

      | | | |

      | | | +-JLabelObj

      | | | | |

      | | | | +-JDateObj

      | | | | |

      | | | | +-JIntegerObj

      | | | | |

      | | | | +-JRealObj

      | | | |

      | | | +-JNBitsObj

      | | | |

      | | | +-J1DMeterObj

      | | | | |

      | | | | +-J1DViewerObj

      | | | |

      | | | +-J2DMeterObj

      | | | |

      | | | +-JBtnObj

      | | | |

      | | | +-J1DSliderObj

      | | | |

      | | | +-J2DSliderObj

      | | | |

      | | | +-JFocusObj

      | | | |

      | | | +-JPushBtnObj

      | | | |

      | | | +-JSwitchObj

      | | |

      | | +-JRAddObj

      | | | |

      | | | +-JRAbsObj

      | | | | |

      | | | | +-JItoRObj

      | | | | |

      | | | | +-JRACosObj

      | | | | |

      | | | | +-JRASinObj

      | | | | |

      | | | | +-JRATanObj

      | | | | |

      | | | | +-JRCeilObj

      | | | | |

      | | | | +-JRCosObj

      | | | | |

      | | | | +-JRDivideObj

      | | | | | |

      | | | | | +-JRAtan2Obj

      | | | | | |

      | | | | | +-JRModObj

      | | | | | |

      | | | | | +-JRPowObj

      | | | | | |

      | | | | | +-JRSubtractObj

      | | | | |

      | | | | +-JRExpObj

      | | | | |

      | | | | +-JRFloorObj

      | | | | |

      | | | | +-JRLogObj

      | | | | |

      | | | | +-JRRandomObj

      | | | | |

      | | | | +-JRRoundObj

      | | | | |

      | | | | +-JRSinObj

      | | | | |

      | | | | +-JRSqrtObj

      | | | | |

      | | | | +-JRTanObj

      | | | | |

      | | | | +-JRtoIObj

      | | | |

      | | | +-JRMaxObj

      | | | |

      | | | +-JRMinObj

      | | | |

      | | | +-JRMultiplyObj

      | | | |

      | | | +-JRPIObj

      | | | |

      | | | +-JREObj

      | | |

      | | +-JTimeObj

      | | |

      | | +-JAddObj

      | | |

      | | +-JAbsObj

      | | | |

      | | | +-JDelayObj

      | | | |

      | | | +-JDivideObj

      | | | | |

      | | | | +-JAccumulatorObj

      | | | | |

      | | | | +-JPowObj

      | | | | |

      | | | | +-JRemainObj

      | | | | |

      | | | | +-JSubtractObj

      | | | |

      | | | +-JNodeObj

      | | |

      | | +-JAvgFilterObj

      | | |

      | | +-JBtoIObj

      | | |

      | | +-JCOMObj

      | | |

      | | +-JComplexObj

      | | |

      | | +-JConvertObj

      | | |

      | | +-JDataBaseObj

      | | |

      | | +-JDaviconObj

      | | |

      | | +-JDeMultiplexerObj

      | | |

      | | +-JDecoderObj

      | | |

      | | +-JDelaySustainObj

      | | |

      | | +-JEncoderObj

      | | |

      | | +-JExclusiveObj

      | | |

      | | +-JItoBObj

      | | |

      | | +-JLPTObj

      | | |

      | | +-JMIDIChannelObj

      | | |

      | | +-JMIDIOutObj

      | | | |

      | | | +-JMIDIInObj

      | | |

      | | +-JMaxObj

      | | |

      | | +-JMinObj

      | | |

      | | +-JMultiplexerObj

      | | |

      | | +-JMultiplyObj

      | | |

      | | +-JRecorderObj

      | | | |

      | | | +-JMIDIFileObj

      | | | | |

      | | | | +-JRMIDFileObj

      | | | |

      | | | +-JWaveFileObj

      | | |

      | | +-JSampleObj

      | | | |

      | | | +-JControlObj

      | | |

      | | +-JSocketObj

      | | | |

      | | | +-JServerSocketObj

      | | |

      | | +-JWaveOutObj

      | | | |

      | | | +-JWaveInObj

      | | |

      | | +-JANDObj

      | | |

      | | +-JCalibrateObj

      | | |

      | | +-JClockDividerObj

      | | |

      | | +-JJoyStickObj

      | | |

      | | +-JMIDIObj

      | | |

      | | +-JMixerObj

      | | |

      | | +-JNOTObj

      | | | |

      | | | +-JCHObj

      | | | |

      | | | +-JDGreaterThanObj

      | | | | |

      | | | | +-JDEqualObj

      | | | | |

      | | | | +-JDGreaterEqualObj

      | | | | |

      | | | | +-JDNotEqualObj

      | | | |

      | | | +-JGreaterThanObj

      | | | | |

      | | | | +-JEqualObj

      | | | | |

      | | | | +-JGreaterEqualObj

      | | | | |

      | | | | +-JNotEqualObj

      | | | |

      | | | +-JKeyboardObj

      | | | |

      | | | +-JMouseBtnObj

      | | | | |

      | | | | +-JMousePosObj

      | | | |

      | | | +-JMouseObj

      | | | |

      | | | +-JPulseObj

      | | | |

      | | | +-JRGreaterThanObj

      | | | | |

      | | | | +-JREqualObj

      | | | | |

      | | | | +-JRGreaterEqualObj

      | | | | |

      | | | | +-JRNotEqualObj

      | | | |

      | | | +-JRandomObj

      | | | |

      | | | +-JSGreaterThanObj

      | | | |

      | | | +-JSEqualObj

      | | | |

      | | | +-JSGreaterEqualObj

      | | | |

      | | | +-JSNotEqualObj

      | | |

      | | +-JORObj

      | | |

      | | +-JOxfordObj

      | | |

      | | +-JRCalibrateObj

      | | |

      | | +-JTNGObj

      | | | |

      | | | +-JTNG3Obj

      | | |

      | | +-JTimerObj

      | | |

      | | +-JXORObj

      | |

      | +-JViewSet

      | |

      | +-JFocusSet

      | |

      | +-JLinkObj

      |

      +-JProperty

      | |

      | +-JColorProperty

      | |

      | +-JIntegerListProperty

      | |

      | +-JIntegerProperty

      | |

      | +-JRealProperty

      | |

      | +-JStringProperty

      | |

      | +-JFileProperty

      |

      +-JInetAddress

      |

      +-JAssociation

      |

      +-JDataBase

      |

      +-JDate

      |

      +-JFileArray

      |

      +-JHashTable

      | |

      | +-JDictionary

      |

      +-JRandom

    2. NeatTools Architecture
    3. The NeatTools architecture defines the complete structure for implementing NeatTools' cross-platform, extensive module unit, usability, and functionality features by using UML (Unified Modeling Language).

      1. Three-Layer Architecture

The NeatTools' implementation model is defined as a three-layer architecture. This architecture is necessary for cross-platform design. There are several advantages associated with this approach:

  1. It separates the application design from platform dependent detail by providing abstract windows and a system resource layer for building the application upon the abstract layer.
  2. Based upon the well defined interfaces in the class, a system programmer can refine the design and algorithms later without needing to change the dependent layer.
  3. The current commercial windows abstract layers, like Microsoft MFC, Borland OWL, and OSF MOTIF tend to be fat in design and fixed on one specific platform.

The conceptual framework for NeatTools is based on an architecture with three layers:

  1. Operating system and programming language layer
  2. Java like cross-platform API layer
  3. NeatTools application layer

Functions of the layers are summarized in the following table:

Layer

Description

Operating system and programming language

the service and resources provided by operation systems and programming language itself.

Java like cross-platform API

a set of abstract classes that provide the windows and basic service for application construction needs.

NeatTools application

provides the actual implementation of usability and functionality which meet the general requirement as a real-time visual programming tool.

Table 1: Summary of layers

The operating system and programming language layer provide all the basic system service and resources. This layer includes Win32 API, X11 API, and C++ run time library. The Win32 API and X11 API provide the generally required functionality of windowing, graphics context, objects and memory management in a platform dependent fashion. The C++ run time usually comes with the actual compiler implementations. There are even some standards proposed for the C++ language itself. However, there are still some significant differences between companies and platforms. Hence, it is desirable to have an abstract layer which provides standardized interfacing between the application layer and the operating system layer.

The Java-like cross platform API layer is the abstract layer that works between the operating system and the application. It releases the application's dependency on the operating system and provides a higher level utility class object support. Usually, the API is a collection of procedures. It is usually very difficult for a programmer to: find out the relevant procedures in an API; know its capability and usage; know how it interacts with other procedures; not to mention putting them together in order to accomplish a required task. In this sense, a cross-platform API layer is necessary and desirable.

Now comes the second question: why Java-like. "Java-like" means it defines the class and interface according to a Java API specification. NeatTools needs to be fast and efficient to handle the real-time and computationally intensive task (s). By implementing a Java-like API in C++, we gain Java’s ability to run on different platforms as well as the high performance of C++. The application layer is where we build the actual NeatTools implementation in cross platform fashion. Different applications will eventually need some special classes which could perform the usability and functionality needed for the particular applications. So the presence of this layer is natural.

      1. Package structure
      2. The NeatTools implementation is moderately complex. It is composed of approximately 100 classes in a Java-like cross platform API layer and approximately 120 classes in a NeatTools application layer. The complexity of the classes is managed by organizing them into logical packages. The NeatTools implementation is decomposed into the top-level packages shown in Figure 1:

        Figure 1: Top-level packages

      3. OS and C++ runtime Package
      4. The Operating system and C++ runtime package is further decomposed as show in Figure 2:

        Figure 2: OS and C++ runtime layer

      5. Java-like API package
      6. The Java-like cross platform package is further decomposed into NET, AWT, UTIL, IO, and LANG packages as show in Figure 3:

        Figure 3: Java like cross-platform API layer

        Figure 4: Exceptions class diagram in Java like API layer

        1. LANG package
        2. The LANG package contains the classes that make up the core of the Java-like API layer. The classes of the LANG package are summarized in the following table:

          Class

          Description

          JBlock

          Memory block class

          JBoolean

          Object wrapper for Boolean values

          JCharacter

          Object wrapper for char values

          JCriticalSection

          Exclusive object for critical section

          JDescriptor

          Generic descriptor manipulate object

          JDouble

          Object wrapper for double values

          JFloat

          Object wrapper for float values

          JInteger

          Object wrapper for integer values

          JLong

          Object wrapper for long values

          JMath

          Object wrapper for math functions

          JObject

          Generic object class, at top of inheritance hierarchy

          JObjectPtr

          Object wrapper for object pointer

          JPObject

          Object wrapper for object reference

          JProcess

          Generic behavior for process

          JReference

          Generic handle manipulate object

          JString

          Character strings

          JThread

          Class for managing threads

          JThrowable

          Generic exception class; all object thrown must be a Throwable

          Table 2: Classes of LANG package

        3. UTIL package
        4. The UTIL package contains various utility classes, including random numbers, system properties, and other useful classes. Classes of the UTIL package are summarized in the following table:

          Class

          Description

          JArray

          A array of objects

          JAssociation

          Association object that associate two objects

          JDList

          A double link list

          JDictionary

          A class that maps between keys and values

          JFileArray

          A massive array that store content in file system

          JHashTable

          A hash table

          JList

          A link list

          JRandom

          A random number generator object

          Table 3: Classes of UTIL package

        5. IO package
        6. The IO package provides input and output classes and classes for streams and files. The classes of IO packages are summarized in the following table:

          Class

          Description

          JBlockInputStream

          An input stream from a memory block

          JBlockOutputStream

          An output stream from a memory block

          JBufferedInputStream

          A buffered input stream

          JBufferedOutputStream

          A buffered output stream

          JFile

          Represents a file on the file system

          JFileIOStream

          A input/output stream from and to a file

          JFileInputStream

          An input stream from a file

          JFileOutputStream

          An output stream to a file

          JFilterInputStream

          A class which provides a filter for input stream

          JFilterOutputStream

          A class which provides a filter for output stream

          JInputStream

          An abstract class representing an input stream

          JOutputStream

          An abstract class representing an output stream

          JPipedStream

          An piped input/output stream

          Table 4: Classes of IO package

        7. NET package
        8. The NET package contains classes for performing network operations, such as sockets and URLs. Classes of the NET package are summarized in the following table:

          Class

          Description

          JInetAddress

          An object representation of an Internet host

          JServerSocket

          A server-side socket

          JSocket

          A socket

          JSocketInputStream

          An input stream from a socket connection

          JSocketOutputStream

          An output stream to a socket connection

          Table 5: Classes of NET package

        9. AWT package

        The AWT package contains the classes that make up the Abstract Windowing Toolkit. This package contains the window abstraction and graphics abstraction related classes. The classes of AWT package are summarized in the following table:

        Class

        Description

        JBorderLayout

        A layout manager for arranging items in border formation

        JButton

        A UI button

        JCanvas

        A canvas for drawing and performing other graphics operation

        JClipboard

        An object wrapper for clipboard buffer

        JColor

        A representation of a color

        JColorBox

        A dialog box that could change color setting

        JComponent

        The generic class for all UI components

        JDialog

        A window for brief interactions with users

        JDimension

        width and height

        JEvent

        An object representing events caused by the system or based on user input

        JFileBox

        A dialog box that could select a file in file system

        JFlowLayout

        A layout manager that lays out objects from left to right in rows

        JFont

        A representation of a font

        JFontMetrics

        A class for holding information about a specific font's character information

        JGraphics

        The generic behavior for representing a graphics context, and for drawing and painting shapes and objects

        JGridLayout

        A layout manager with rows and columns; elements are added to each cell in the grid

        JImage

        A representation of a bitmap image

        JInputBox

        A dialog box for input text

        JInsets

        Distances from the outer border of the window; used to layout components

        JIntegerBox

        A dialog box for input integer values

        JIntegerListBox

        A dialog box for select integer values

        JLabel

        A text label for UI components

        JLayoutManager

        A generic class for all layout manager

        JListBox

        A scrolling list

        JMessageBox

        A dialog box that display a message to users

        JModal

        A specialized dialog box that will interact with users

        JPanel

        A container that is displayed

        JPoint

        x and y coordinates

        JPushButton

        A UI pushbutton

        JRect

        x and y coordinates for the top corner, plus width and height

        JRegion

        A logical region defined in graphics context

        JRuler

        A UI ruler

        JScroller

        A UI scrollbar

        JSeparator

        A UI separator

        JTextField

        A fixed-size editable text field

        JThumb

        A UI thumb in scrollbar

        JToggleButton

        A UI toggle button

        JTriangleButton

        A UI triangle button in scrollbar

        JWindow

        A top-level window

        Table 6: Classes of AWT package

      7. NeatTools application package
      8. The NeatTools application package is further decomposed into NEAT, DESKTOP, Modules, and External Modules packages as show in Figure 5:

        Figure 5: NeatTools application layer

        1. NEAT package
        2. Figure 5: Property in NEAT package

          Figure 7: NEAT package (continue)

          The NeatTools modules could define internal properties which could be modified through a property dialog box. Each property will become an item in a property list box. A user could select and modify them. Taking advantage of the object oriented programming technique, the Property class becomes the generic property representation. And all other properties will be derived from Property class and will benefit the unified process and editing procedures.

          Just as the LANG package is the core of Java-like API layer, the NEAT package is the core of the NeatTools application layer. It defines the basic object structure of how JViewObj aggregates into JVewSet. It also defines the basic module behavior which includes input group and output group (an aggregation of JFocusSet. Here, JFocusSet is the composition of JLinkObj that represents the input and output links of a module object). Because of the polymorph feature of object orient programming, the JViewSet could become the composition of any object which derived from JVewObj. This structure forms a container-component relationship pattern.

          The classes of NEAT package are summarized in the following table:

          Class

          Description

          JANDObj

          A NeatTools module that handle AND operation

          JAbout

          A banner that shows the NeatTools

          JColorProperty

          A property that represent color values

          JFDimension

          width and height in floating point format

          JFPoint

          x and y in floating point format

          JFRect

          A rectangle in floating point format

          JFileProperty

          A property that represent files

          JFocusSet

          A composition of JViewObj reference

          JGuideObj

          A guide line in NeatTools desktop area

          JIntegerListProperty

          A property that represent a list of integer values

          JIntegerProperty

          A property that represent integer values

          JLineObj

          A line representation in NeatTools desktop area

          JLinkObj

          A link between two NeatTools modules

          JModuleButton

          A UI button that display NeatTools modules

          JModuleCanvas

          A UI canvas that display NeatTools modules

          JModuleObj

          A generic class of all NeatTools modules

          JProperty

          A generic class of all properties

          JPropertyBox

          A dialog box that could change the property settings

          JRealProperty

          A property that represent the floating point values

          JStringProperty

          A property that represent the string values

          JViewObj

          A generic class of all display object in NeatTools desktop area

          JViewSet

          A composition of JViewObj objects

          Table 7: Classes of NEAT package

        3. Modules package
        4. All NeatTools modules are derived directly or indirectly from JModuleObj. Currently, there are around 100 different modules in NeatTools. Each modules works like a black box, or Ics, which could handle one or several functions in a particular field. As AND module is the AND gate in digital logic, OR module is the OR gate in digital logic. Please see section 3 for more detailed information on NeatTools module structure.

        5. External modules package
        6. The external modules are just like a normal NeatTools module. The only difference is how it is complied and linked into the system. Follow the special instructions in "NeatTools external module development kit" and it will guide you through the creation of an external module and into a dynamic linkage library (DLL). NeatTools will load the external modules in startup when it can locate them in the NeatTools directory. Or they could be loaded in runtime by pressing "Load Module" button in NeatTools. If an external module is used in a NeatTools network and the module was not loaded in memory yet, NeatTools will popup a dialog box for the user to specify the location of the particular external module.

        7. DESKTOP package

The DESKTOP package contains a very complex class called JView which is a UI canvas as well as the NeatTools desktop area. It contains the aggregation and composition of all the NeatTools modules, links between modules, guide lines, and focus objects selected by users. It also handles all the user and system events, such as mouse events, keyboard events, and system notify events. It represents and implements

  1. module display
  2. module layout
  3. grid snapping
  4. thread operation exclusive
  5. module persistency
  6. module creation
  7. data flow network construction
  8. clipboard buffer operations
  9. event broadcast initialization.
    1. Module Programming Introduction
      1. Module Event Broadcast Model
      2. By using module abstraction, I simplify the module event broadcast model into a process involve only three methods and directly function call between these methods. There three method include engine, broadcast, and access. Usually, programmer will have to override engine and access method to define the module's behavior. The behavior here means how module react to external events and change its internal state to respond to the event. Also, some module could change its state or broadcast message without external trigger by using its own thread.

        How those three method methods work together ? and how NeatTools system involve in the process ? First, I have to mansion the Link Object which NeatTools use to record the logical connection between modules. The object defined as follow (Programmer always could find all the header files under http://www.pulsar.org/ej/work/oop/oop.html :

        class

        JLinkObj : public JViewSet {

        ...

        public:

        ...

        JLinkObj();

        ...

        void access(const JDataType& data);

        void engine();

        ...

        JModuleObj *from, *to;

        int fn, tn;

        };

         

         

        In this object, I defined the public data member include the Module pointer 'from' and 'to', and Interger 'fn' and 'tn'. Pointer 'from' reference the source module and Pointer 'to' reference the destination module. 'fn' stand for the output port number of the source module and 'tn' stand for the input port number of the destination module. In NeatTools module, programmer can define the number of input or output by fixed number or dynamically change the number of input or output port. Each port could accept one or more connections depend on the behavior of module. I will discuss that later on. So what happen when user make connection between two modules ? NeatTools will initiate a link and put it in a link list of links and then each module on the particular port will have separate link list which has the reference to the link itself. (for performance reason, so module could direct access to the link object without search).

        Now, lets get back to the broadcast model again. Module programmer could decide to broadcast event on a particular port at any time. It could happen in its thread loop or just respond to incoming event from other modules. When broadcast(fn) is been called, NeatTools will invoke all the connected module's engine(tn, link). When a module's engine method got invoked, it knows an event occur and it comes from which module, which output port, and it goes into which input port by access the data member of the link parameter. When programmer implement the engine method, he will first use tn to identify which input port got event and then use link.access(data) to access the event content. the link.access(data) will translate into call source module's access(fn, link, data) method. So before call broadcast, programmer should prepare the value in data member so when the destination module call its access method, it could provide the value right on time. Why, we have this trouble to have the engine call the access in order to get the data ? Because, in some situation, like AND gate, its input port could accept any number of connections. And when an event occur through one of the connection, the AND has to go through all the input connection to figure out the result value. In this case, The AND gate call module's access even when that module did not call broadcast. So, programmer should keep it in mind that access should always provide current value.

        In order to see how it works, let see a simple example on a module which calculate X2 as an output when integer event going in. We will just focus on the broadcast related methods at this time.

        // JSquareObj.h

        class JSquareObj : public JModuleObj {

        protected:

        virtual void writeContent(class JOutputStream& os);

        virtual void readContent(class JDictionary& dict);

        public:

        virtual const char* className() const;

        virtual JObject* clone() const;

        JSquareObj();

        virtual void draw(JGraphics g, int x, int y, int w, int h);

        virtual void access(int n, JLinkObj& link, const JDataType& data);

        virtual boolean inputAllowed(int n);

        virtual boolean outputAllowed(int n);

        virtual void engine(int n, JLinkObj& link);

        protected:

        int value;

        };

         

        #include "JSquareObj.h"

        #include "JLinkObj.h"

        #include "JIntegerData.h"

         

        char* theJSquareObj = JSquareObj().Register();

        void JSqureObj::writeContent(JOutputStream& os) {

        JModuleObj::writeContent(os);

        putInteger(os, "value", value);

        }

         

        void JSquareObj::readContent(JDictionary& dict) {

        JModuleObj::readContent(dict);

        value = getInteger(dict, "value");

        }

         

        const char* JSquareObj::className() const { return "JSquareObj";}

        JObject* JSquareObj::clone() const { return new JSquareObj(*this);}

        JSquareObj::JSquareObj() { igm = 1; value = 0;}

         

        void JSquareObj::draw(JGraphics g, int x, int y, int w, int h) {

        JRect rect(x, y, w, h);

        drawText(g, JString("Sqr"), rect);

        }

         

        void JSquareObj::access(int n, JLinkObj& link, const JDataType& data) { INT(data) = value;}

        boolean JSquareObj::inputAllowed(int n)

        { return !inputSet(n).last();}

        boolean JSquareObj::outputAllowed(int n) { return true;}

         

        void JSquareObj::engine(int n, JLinkObj& link) {

        int nv;

        link.access(JIntegerData(nv));

        nv *= nv;

        if (value != nv) {

        value = nv;

        broadcast(0);

        }

        }

         

        Here, we start our focus on engine method. In this method, we declare a temporary integer variable nv. the link.access(JIntegerData(nv)) will first create JIntegerData (a derived class of JDataType) instance and use it as a media to transfer integer value into nv. Every data type are derived class of JDataType. I will discuss the data type polymorphism later. Because of polymorphism, we can use the same access method to transfer all kind of different data type. After this statement, the input value will assign on variable nv. So we calculate the square of nv. If nv and value are different, we update the value and call broadcast(0). Here we only have one output port, so the only valid broadcast number would be zero. When process broadcast method, the destination module's engine method will get invoked and eventually it will call source module's access method. Here, in access method, we have only one statement: INT(data) = value. INT is a macro defined in JIntegerData.h to type cast JIntegerData into int&. So we can use it and assign new value. Programmer also could use data.assign(JInteger(value)). JInteger is a wrapper class for int data (Like the Integer class in Java). But the first implementation is faster.

      3. Basic Methods in Module
      4. Almost every object class in NeatTools are subclass of JObject directly or indirectly. There are some method which always need to be take care of or override to ensure the basic object behavior works correctly.

        In the previous example module, after invoke some header files, you will see a strange line :

        char* theJSquareObj = JSquareObj().Register();

        What this line does is: it will call the Register method and register the module into NeatTools system. So later on, NeatTools could duplicate or recreate object instance by using this registered copy. If you fail to define this line, your module will become invisible to NeatTools system.

        Programmer also need to override the className() and clone() methods. In NeatTools, I use the character string return by className() method to identify different objects. Please make sure not to define different class with the same name return by className(). The clone method will new and return a object instance. If you fail to define these methods, NeatTools could not generate the module you designed.

        The constructor is an option. But usually you will initialize your data member or set the default input or output port number. 'igm' and 'ogm' are the variable represent the current input and output port number. In this example, I set 'igm' to 1 and the default value of 'ogm' (defined in JModuleObj) is 1 also. So here, this module has only one input and one output port. If you try to change the number of input or output port respond to property or input event, there are some complex issues on layout refresh problem. Please reference the source code in NeatTools Module develop kit and find out how to implement this feature.

      5. Information Methods in Module
      6. NeatTools need more information on each input and output port. For example the data type, the attached edge, the tag, etc. The following methods will need to be override: (If you have some module which has common behavior, you can use one of the class as base class and use it to derive other class. This way, we could save time and space.)

        1. JString inputTag(int n), JString outputTag(int n)
        2. NeatTools will these methods to display the tag or description for a particular input or output port. The default behavior in Module is following:

          JString JModuleObj::inputTag(int n) {

          char* tag[] = { "input", "enable(logical)"};

          return tag[n];

          }

           

          JString JModuleObj::outputTag(int n)

          { return "output";}

           

          So when user move to the port area, NeatTools system will display the tag by using the return value of this method.

        3. int inputType(int n), int outputType(int n)
        4. Each input or output port could associate with different data type. Here we can return different data type identify for each different port. Or just return one data type identify for every port. The default behavior is following:

          int JModuleObj::inputType(int n) { return JIntegerData::id;}

          int JModuleObj::outputType(int n) { return JIntegerData::id;}

           

          Here, it define every input and output port are all integer type. If you want to use other data type, please see the header files in NEAT directory. If you want to set different data type for each different port, you can write something like this:

          int JTestObj::inputType(int n) {

          switch (n) {

          case 0: return JIntegerData::id;

          case 1: return JStringData::id;

          case 2: return JWaveData::id;

          }

          return JIntegerData::id;

          }

           

        5. boolean inputAllowed(int n), boolean outputAllowed(int n)
        6. This two methods define the accessibility of a input or output port. When it return true, NeatTools could add new connection to it. When it return false, NeatTools will indicate this port already been occupied. The default behavior is following:

          boolean JModuleObj::inputAllowed(int n) { return false;}

          boolean JModuleObj::outputAllowed(int n) { return false;}

           

          So if you derive your module directly from JModuleObj, you will have to override these methods to ensure your input or output port could accept new connections. If you want input port accept only one connection, you can do something like this:

          boolean JSquareObj::inputAllowed(int n)

          { return !inputSet(n).last();}

           

          The inputSet(n) will return the link list of the input port number n. So if link is empty, its last() method will return null. So inputAllowed() will return true and NeatTools could accept new connection for this port. Otherwise, NeatTools will not accept new connection. Programmer could apply the outputSet(n) to the outputAllowed() method.

        7. int inputFace(int n), int outputFace(int n)
        8. These two method decide the attach face that a connection would connect to. For inputFace(n), you could return either LEFT or TOP. For outputFace(n), you could return either RIGHT or BOTTOM. The default behavior is following:

          int JModuleObj::inputFace(int n) { return (!n) ? LEFT : TOP;}

          int JModuleObj::outputFace(int n) { return RIGHT;}

           

          It means inputFace(0) will return LEFT and inputFace(1) will return TOP. and outputFace() always return RIGHT. So connection to the first input port will attach on left edge, but the second input port will attach on top edge.

        9. JFRect inputArea(int n), JFRect outputArea(int n)
        10. These two methods decide the area that a port will accept connections. When user's mouse move within the area defined by JFRect (A floating point rectangle with x, y, with, height data member), NeatTools will show the inverse rectangle to indicate the port area. Module itself is derived from JFRect also. So itself has the x, y, with, and height data member which define the current position and dimension of the module. By using module's with and height value you can define inputArea or outputArea like this:

          JFRect JModuleObj::inputArea(int n) {

          if (!n) return JFRect(0, height/4, width/6, height/2);

          return JFRect(width/4, 0, width/2, height/6);

          }

           

          JFRect JModuleObj::outputArea(int n)

          { return JFRect(width*5/6, height/4, width/6, height/2);}

           

          But, I found out, it is too much trouble for most module with several input port and some of the module need to change the number of input or output port dynamically. So I wrote some utility method which will calculate the rectangle automatically. The default behavior is following:

          JFRect JModuleObj::inputArea(int n) {

          if (!n) return leftArea(n, 0, 1);

          return topArea(n, 1, 1);

          }

           

          JFRect JModuleObj::outputArea(int n)

          { return rightArea(n, 0, 1);}

           

          The leftArea, topArea, rightArea, and bottomArea method are defined in JMoudleObj.

          JFRect topArea(int n, int start, int N,

          double from = 0.25, double delta = 0.5, int factor = 6);

          JFRect bottomArea(int n, int start, int N,

          double from = 0.25, double delta = 0.5, int factor = 6);

          JFRect leftArea(int n, int start, int N,

          double from = 0.25, double delta = 0.5, int factor = 6);

          JFRect rightArea(int n, int start, int N,

          double from = 0.25, double delta = 0.5, int factor = 6);

           

          The 'n' stand for the port number. 'start' means start from which port number. 'N' means for how many port. 'from' stand for the relative position that area start. 'delta' stand for the relative distance that 'N' port will occupy. 'factor' stand for the divide factor of area. If 'factor' is 6, it means area will have height/6 or width/6 dimension. So leftArea(n, 0, 3) means start from port 0 to port 2 (total 3 ports) will occupy area JFRect(0, height/4, width/6, height/2) and divide it into 3 portions from top to down are port0, port1, and port2.

        11. JFPoint inputPoint(int n, class JLinkObj& link), JFPoint outputPoint(int n, class JLinkObj& link)

         

        These two method is pretty much like the inputArea and outputArea. But the only different is it will return the final attachment point of the connection to a particular port. You will see the link become one of the parameter. It is because, for those port could accept more than one connection, each connection will going to have different attachment point event they are belong to the same port. But using this parameter, we could decide its order and calculate the attachment point when necessary. Again, I wrote the following utility methods. The usage is exactly the same to area utility methods. Only you have to put in the extra link parameter.

        JFPoint topPoint(int n, class JLinkObj& link, int start, int N,

        double from = 0.25, double delta = 0.5);

        JFPoint bottomPoint(int n, class JLinkObj& link, int start, int N, double from = 0.25, double delta = 0.5);

        JFPoint leftPoint(int n, class JLinkObj& link, int start, int N, double from = 0.25, double delta = 0.5);

        JFPoint rightPoint(int n, class JLinkObj& link, int start, int N, double from = 0.25, double delta = 0.5);

         

      7. Display Related Methods in Module
      8. Display is a very important issue in NeatTools. I have been change the display mechanism several time to increase to through put especially for high frequency events that involve repaint modules. But there are only a few method that related to display. That's talk about paint, update, and repaint method:

        void paint(JGraphics g, double dx, double dy, JRegion& rgn, double scale);

        void update(JGraphics g, double dx, double dy, JRegion& rgn, double scale);

        void repaint();

         

        NeatTools will call paint method where there is a need to refresh the graphics contents of module. For example, when user do resize, scroll, scale, etc. operations on the NeatTools windows could cause a module's paint method get invoked. If module itself decide refresh itself to respond to its internal state's change (like LED receive a true event and decide to turn itself on), it could call the repaint() method. Eventually, NeatTools could invoke module's update method. (Depend on the situation, cause module could covered by other module or out of desktop's scope.) Usually, when receive paint, module will draw everything include frame and contents. But when received update, module could only draw the contents. To save space, usually, in paint method we will only draw frame and call the update to draw the contents. But basically, programmer could whatever he want depend on the situations. The following is an example on LED object:

        void JLEDObj::paint(JGraphics g, double dx, double dy, JRegion& rgn, double scale) {

        JRect rect = getIExtent(dx, dy, scale);

        g.setJColor(moduleColor);

        if ((rect.width > depth2) && (rect.height > depth2))

        g.draw3DJRect(rect, depth);

        update(g, dx, dy, rgn, scale);

        }

         

        void JLEDObj::update(JGraphics g, double dx, double dy, JRegion& rgn, double scale) {

        JRect rect = getIExtent(dx, dy, scale);

        if (value == 0) g.setJColor(bkgnd);

        else g.setJColor(color);

        if ((rect.width > depth2) && (rect.height > depth2)) {

        g.fillJRect(rect.shrink(depth, depth));

        } else g.fillJRect(rect);

        }

         

        The JGraphics object is the graphics context that module could make their graphics operations or setup parameters. It works like a media between program and actual devices. In this case, the JGraphics is always an area on screen, if user make some operation by calling JGraphics' methods, it will reflect the change to screen.

        Here, in paint, first we use getIExtent to get the current module extent in integer screen unit. Cause NeatTools could display module in any scale. So, module will not know its current size on screen until its paint or update method get invoked. After this statement, the rect will store the current module size in pixel unit. Then, depend on the value itself, if value is false, we set the current color to background color, otherwise we set it to foreground color. If current size is large enough to draw the frame, we call g.draw3DJRect to draw the 3d frame. Then we call update to draw the contents.

        In update, we follow the same process and later on fill the LED module with the proper color by using g.fillJRect methods.

        void JLEDObj::engine(int n, JLinkObj& link) {

        if (!n) {

        int iv;

        link.access(JIntegerData(iv));

        setValue(iv);

        } else processColor(n, link);

        }

         

        boolean JLEDObj::setValue(int _value) {

        if (_value != value) {

        value = _value;

        broadcast(0);

        repaint();

        return true;

        }

        return false;

        }

         

        So, when will LED decide to update itself and make visual feedback to user ? Let's look at the engine method. If n is equal to zero (the input port on the left edge, in this case), it will use link.access to assign the integer value into iv variable. And call setValue(iv). In setValue method, we will check if the value need change, if it does, we update the value first and call broadcast(0) and repaint() to refresh its display. Later on, NeatTools will invoke it's update method to fill the color when necessary.

      9. Module persistency related Methods
      10. One important thing that NeatTools system does is provide user the capacity to layout modules and make connections between modules. But the other task that NeatTools does is equally important - module persistency. That means, NeatTools provide a way to let module store its current state and connections into secondary storage space like hard disk. And later on, retrieve the information and reconstruct every module, restore their state and rebuild their connections. So, how NeatTools do that ? NeatTools rely on two methods in module to accomplish this requirement.

        protected:

        virtual void writeContent(class JOutputStream& os);

        virtual void readContent(class JDictionary& dict);

         

        The implementation in LED looks like this:

        void JLEDObj::writeContent(JOutputStream& os) {

        JModuleObj::writeContent(os);

        putObject(os, "color", color);

        putObject(os, "bkgnd", bkgnd);

        putInteger(os, "value", value);

        }

         

        void JLEDObj::readContent(JDictionary& dict) {

        JModuleObj::readContent(dict);

        JObject *obj = getObject(dict, "color");

        if (obj) color = *(JColor*)obj;

        obj = getObject(dict, "bkgnd");

        if (obj) bkgnd = *(JColor*)obj;

        value = getInteger(dict, "value");

        }

         

        'writeContent' method will be invoked when NeatTools want a module to write its current states into output stream. Programmer has to call base class's writeConnect method first. Cause every module will only handle the data member that declare in its object scope. Some times a data member is just for temporary usage, we could decide not to write their current state. readContent is the opposite to writeContent. When we try to 'put' a variable, we assign a string name to identify the variable. Later on, the readContent provide user a dictionary object which contain all the available variables. Programmer could use string name as a key to retrive the variables. All the putX and getX method are defined in JObject class. The only tricky thing is that, getObject could return null. In that case, we could check for that situation and assign object only when the return object is not null.

      11. Property Related Methods in Module
      12. About Data Type
      13. About Polymorph Data Type
      14. Use Thread in Module
      15. Concurrency Issues when Design Module
    2. Visual Programming Examples

 

 

 

  1. Bibliography
  1. Nancy A. Lynch and Mark R. Tuttle. An introduction to Input / Output Automata. CWI-Quarterly, 2(3), 1989.
  2. Myers, Brad A. "User Interface Software Tools", ACM Transactions on Computer-Human Interaction, 2(1): 64-103, March 1995.
  3. Myers, Brad A. and Mary Beth Rosson. Survey on User Interface Programming. In Proceedings of SIGCHI'92 Human Factors in Computing Systems, May 1992.
  4. Myers, Brad A. "Challenges of HCI Design and Implementation", ACM Interactions 1, 1(1994), to appear.
  5. X Business Group, Inc. Interface Develop Technology. 3155 Kearney Street, Suite 160, Fremont, CA 94538. (510) 266-1075, 1944.
  6. Wilson, David. "Programming with MacApp pages", Addison-Wesley Publishing Company Reading, MA, 1990.
  7. Linton, Mark A., John M. Vlissides and Paul R. Calder. "Composing User Interfaces with InterViews". IEEE Computer 22(2): 8-22, February 1989.
  8. Microsoft Corporation. Visual C++, Visual Basic. PO Box 72368, Roselle IL 60172-9900. (800) 426-9400, 1997.
  9. Szekely, Pedro. Separating the User Interface from the Functionality of Application Programs. Ph.D. Thesis. Carnegie Mellon University School of Computer Science technical reports CMU-CS-88-101, January 1988.
  10. Laura Lemay and Charles L. Perkins. "Teach Yourself Java in 21 Days", Sams Net, 201 West 103rd Street, Indianapolis, Indiana 46290.
  11. Richard C. Lee and William M. Tepfenhart. "UML and C++, A Practical Guide To Object-Oriented Development", AT&T Lucent Technologies, Prentice Hall, Upper Saddle River, NJ 07458.
  12. Richard J. Simon, Tony Davis, John Eaton, and R. Murray Goertz. "Windows 95 Multimedia & ODBC API Bible", Waite Group Press, 200 Tamal Plaza, Corte Madera, CA 94925.
  13. Charles Petzold. "Programming Windows 3.1" Third Edition, Microsoft Press, A Division of Microsoft Corporation, One Microsoft Way, Redmond, Washington 98052-6399.
  14. Jon Siegel. "CORBA, Fundamentals and Programming", Wiley Computer Publishing, John Wiley & Sons, Inc. Professional, Reference and Trade Group, 605 Third Avenue, New York, NY 10158-0012
  15. Oracle Corporation. "Oracle7 Server Concepts Manual", Oracle7 Server Documentation Manager, Oracle Corporation, 500 Oracle Parkway, Redwood Shores, CA 94065.
  16. Matt Pietrek. "Windows Internals, The Implementation of the Windows Operating Environment", Addison-Wesley Publishing Company (800)358-4566.
  17. Bradford Nichols, Dick Buttlar & Jacqueline Proulx Farrell. "Pthreads programming", O'Reilly & Associates, Inc. 101 Morris Street, Sebastopol, CA 95472-9902.
  18. Nabajyoti Barkakati. "X Window System Programming, Your Complete Guide to Developing X and Motif Applications!", Sames Publishing, 201 W. 103rd Street, Indianapolis, Indiana 46290.

 

VITA

NAME OF AUTHOR: Yuh-Jye Chang

PLACE OF BIRTH: Wen-Lin, Taiwan

DATE OF BIRTH: Feb 22, 1966

GRADUATE AND UNDERGRADUATE SCHOOLS ATTENDED:

Stevens Institute of Technology, Hoboken, New Jersey

National Taiwan University, Taipei, Taiwan

DEGREES AWARDED:

Master of Computer Science, 1991, Stevens Institute of Technology

Bachelor of Mechanical Engineering, 1988, National Taiwan University

AWARDS AND HONORS:

Creative Entertainment Choice, 1997

Java Cup International Winner, 1996

National Taiwan University Symphony Vice-leader, 1987

PROFESSIONAL EXPERIENCE:

Research Assistant, Northeast Parallel Architectures Center, Syracuse University, 1997

Teaching Assistant, Department of Computer Information Science, Syracuse University, 1996

Project Leader, NewTek Corp, 1992

Robot Lab Assistant, Department of Mechanical Engineering, National Taiwan University, 1987

 

I.