Writting GNU/EDMA applications
------------------------------
Abstract
--------
In this paper we will show how to build basic GNU/EDMA applications and use GNU/EDMA classes/components in a way we can exploit the dynamic features GNU/EDMA provides in order to improve code reuse and application extensibility.

1. Hello World!
---------------
We will begin with the basic "Hello World" application which will show us how to compile a GNU/EDMA application and how to begin using GNU/EDMA components. Here is the code:

#include <edma.h>

main () {
	OBJID   id;

	EDMAInit();
	if ((id=NewObj("HELLO_WORLD"))==-1) {
	 fprintf (stderr,"Can't create HELLO_WORLD object\n");
	 EDMAEnd();
	}
	Met3(id,"hello");
	FreeObj(id);
	EDMAEnd();
}

As you can imagine, this simple program show a impresive "Hello World!!" message in the console. Let's go in deep with the different parts of the program.

1.1 Startup and shutdown
------------------------
Like most systems, GNU/EDMA needs to be started up before it can be used. As you can infere from the above code, this is done calling the EDMAInit() function. 

Any GNU/EDMA application must first call this function what registers it in the GNU/EDMA system initiating its internal structs.

The same way, when an application finishes using GNU/EDMA it must call EDMAEnd(), to instruct GNU/EDMA to clean up all the application related structs created while the program was running. 

1.2 Creating/Destroying GNU/EDMA components
-------------------------------------------
Once the system was started up, the application can begin using the services GNU/EDMA provides. The more simple operation we can do is to create an object. This is done calling the NewObj primitive.

This primitive accepts as first parameter the component/class name we want to instantiate, and returns an instance reference that  will be used to interact with the just created object.

If the instance can't be created, for example because the class passed as parameter doesn't exist, NewObj return a -1 value, and a error message is showed in the console.

When calling NewObj, GNU/EDMA does a lot of things. First it checks if the class definition has already been loaded. Thinking about CORBA, the class definition is equivalent to the IDL file. The main difference here is that GNU/EDMA doesn't requires to precompile IDL files, it does itself when required.

Then, it checks if the implementation for the requested class is loaded and mapped in the application space address, in order to allow the application to use it. If not, GNU/EDMA locates the asociated implementation file and makes it available to the current application.

At this point, the interface and implementation for the requested class or component is ready to be used. All this process is done transparently to the programmer. In this simple introduction we will just deal with in-process components, that is, components that are implemented as shared libraries. More complex mechanisms can be build on GNU/EDMA but that is another history.

When we are done with our object, we can destroy it calling FreeObj primitive with the object referencei we got from previous NewObj call. This primitive frees all the internal structs asociated with the object.

Really, FreeObj undoes all the operation NewObj did previously, but consistently. So, FreeObj will unload implementation if the object been destroyed was the last object using it, and even it frees the interface information related to the class if it's no longer required by the application. Actually the current implementation never frees interface related information until the EDMAEnd function is called.

1.3 Using the objects
---------------------
Now, we have a HELLO_WORLD instance and we can make it do things. This class just defines only one method which is named hello, and simply shows the well-known message in the console.

There are tree basic operation an application can do with an object. The first one is the one showed in our example; invoke a method. This is done using the Met3 primitive, the syntax can be easyly infered from our hello world example.

The other two operations allows us to work with properties. Properties are the status of the object, what C++ programmers call member variables. To deal with properties, GNU/EDMA provides two accessor primitives: WProp3 which allows to write a value in  a property, and RProp3 which allows to retrieve a properties's value. 

We will see how to use them in our next example. For now is enough to know they exist.

2. Generating the exe
------------------
Let's write a makefile to get our application compiled. Here it is:

CC=gcc
CFLAGS=`edma-config --cflags-exe`
LIBS=`edma-config --libs-exe`

hello_test: hello.c
	$(CC) $(CFLAGS) -o $@ $< $(LIBS)

As you can see it is a classical makefile, just run make and run the resulting application. A impressive Hello World! message will be dropped in the console.

Let's continue.

3. Dealing with properties
--------------------------
Now we will make a little modification to our application in order to ilustrate how to work with properties. Here is the new code.

#include <edma.h>

main () {
	OBJID   id;
	EChar   the_name[80];

	EDMAInit();
	if ((id=NewObj("HELLO_WORLD"))==-1) {
	 fprintf (stderr,"Can't create HELLO_WORLD object\n");
	 EDMAEnd();
	}
	Met3(id,"hello");
	/* New code follows*/
	WProp3 (id,"Name","John");
	Met3 (id,"sayHello");
	RProp3 (id,"Name",the_name);
	/* New code ends*/
	FreeObj(id);
	EDMAEnd();
}

The use of WProp3 and RProp3 is straightforward as you can see in the above code. The sayHello method now says "Hello John", this method uses internally the property Name we are manipulating in this example.

One special property type provided by GNU/EDMA is the so called EDMAT_BUFFER. This data type is just a memory chunck which stores size information. EDMAT_BUFFER is the preferer way to deal with dynamic memory in GNU/EDMA. Let's see how to use this type with a new example.

3.1 Using EDMAT_BUFFER types
----------------------------
Next example is a simple program that reads a file and shows its first 200 bytes in screen. We suppose we are reading a text file so we don't care about non-printable characters.

#include <stdio.h>
#include <edma.h>

main () {
	OBJID         id;
	EDMAT_BUFFER	buf;
	ESint32       size;

	EDMAInit();
	if ((id=NewObj("NFILE"))==-1) {
		fprintf (stderr,"Can't create NFILE object\n");
		EDMAEnd();
		exit(1);
	}
	EBufferAlloc(&buf,1024);
	
	Met3(id,"Load","the_sample_file.txt",&buf);
	printf ("%d bytes read\n",buf.Size);
	(EPChar)buf.dat[200]=0;
	printf ("%s",(EPChar)buf.dat);
	
	EBufferFree(&buf);
	FreeObj(id);
	EDMAEnd();
}

The above example shows how to use EDMAT_BUFFER vars. First, we can see how to use EBufferAlloc and EBufferFree to alloc and free memory chunks. Second we see how to access information stored in the type: the Size field tell us the memory chunk size in bytes and the dat field allow us to access the stored information.

There is also a EBufferRealloc function we didn't need to use in our previous example and that is used the same way as EBufferAlloc working like the realloc standard C library function.

4. Static or Class Methods
--------------------------
GNU/EDMA allows to define and use static methods the same way Java does. The difference between a ordinary method and a static one is that the second doesn't know what object it is related to. It is just related to a class not to an object.

We can extend our previous file example adding an extra method call to the FileExist static method in class FILESYSTEM. This class provides a set of static method to get information about filesystem objects. For checking if the file exists before reading it we can use this code.

if ((SMet3("FILESYSTEM","FileExist","the_sample_file.txt"))==-1) {
	fprintf (stderr,"File the_sample_file.txt doesn't exist\n");
	EDMAEnd();
	exit(1);
}

In this case, instead of use Met3 primitive we use SMet3 primitive. Instead of provide the primitive with an object reference we provide a class/component name. No further complication required.

5. A simple extensible application
----------------------------------
Taking a brief look to all the examples we have showed until now, you can advice that GNU/EDMA primitives works on character strings. This simple fact provides a powerful extensibility mechanism. Let's see a simple example:

#include <edma.h>

int main (int argc, char *argv[]) {
  EChar  viewer[1024];
	EChar  file[1024];
	OBJID  id;

	EDMAInit();
	
	strcpy (viewer,argv[1]);
	strcpy (file,argv[2]);
	
	id=NewObj(viewer);
	Met3(id,"view",file);
	FreeObj(id);
	
	EDMAEnd();
}

In previous example we have intentionally removed the error checking code for space reasons. As we can see this simple application tries to be a minimum file viewer, when invoked it receives two parameter. The first one is the class the application will use to show us the file, which is the second parameter.

This is a quite silly example but it show how to build applications that can use classes that doesn't exist at the compile time. You can distribute this simple application and add specific viewers in future. This viewer classes just must provide a view method, that is the only requirement for this application.

Of course this simple efect can be easyly achieved with dlopen function family, but let's do a little extension to show some simple advantage of working this way.

5.1 Adding interactibility
--------------------------
Now we are going to modify the above example to allow the user to do some basic manipulations on the file been viewed.


#include <edma.h>

int main (int argc, char *argv[]) {
  EChar  viewer[1024];
	EChar  file[1024];
	EChar  cmd[1024];
	OBJID  id;

	EDMAInit();
	
	strcpy (viewer,argv[1]);
	strcpy (file,argv[2]);
	
	id=NewObj(viewer);
	while (strcmp(cmd,"quit")!=0) {
		printf ("# ");
		scanf ("%s",cmd);
		Met3(id,cmd,file);
	}
	FreeObj(id);
	
	EDMAEnd();
}

Quite easy, isn't?. Now you can use any defined method in the viewer class. For example suposse your class has a print method, then you can print your file just writting print at the prompt, or suppose your IMAGE_VIEWER class has a showPseudoColor method, you can use it directly.

As said, this is a very simple example that can be solved in a variety of ways without using GNU/EDMA, or even building a simple library to deal with shared libraries. But, GNU/EDMA is there now and it offers a lot more facilities we will coment in future papers.

6. Conclusion
-------------
In this short paper we have introduced the basic primitives required to write GNU/EDMA applications. Using this simple primitives you can write applications with deals with GNU/EDMA components as ordinary shared libraries, but in a more easy and flexible way.

Once your application is written you can make changes in any GNU/EDMA component and see the result without any recompilation (if the interface application uses doesn't change), and you can easyly write application that works with GNU/EDMA components not availables when you write your applications.

There is a lot more interesting facilities GNU/EDMA offers that will be introducced in future chapters.

