From Optflux
Jump to: navigation, search
(Final Remarks Regarding datatypes)
(Final Remarks Regarding datatypes)
Line 284: Line 284:
 
=== Final Remarks Regarding datatypes ===
 
=== Final Remarks Regarding datatypes ===
  
* The ''@Datatype'' annotation contains several properties that can be specified. Please refer [Developers#AIBench_Datatypes | here] for that.
+
* The ''@Datatype'' annotation contains several properties that can be specified. Please refer [[Developers#AIBench_Datatypes | here]] for that.
 
* You don't need to declare the Datatypes in the '''plugin.xml''' file. This will be capture automatically by AIBench/OptFlux when used in Operations or placed in the Clipboard.
 
* You don't need to declare the Datatypes in the '''plugin.xml''' file. This will be capture automatically by AIBench/OptFlux when used in Operations or placed in the Clipboard.
  
 
== Creating your first View ==
 
== Creating your first View ==

Revision as of 10:11, 6 December 2010

Pre-requisites

  • Working version of Eclipse IDE
  • Working installation of Subversion
  • If you wish to work directly with the latest version from the SVN server (OPTIONAL)

If you are behind a proxy, please note that some extra-configuration of subversion may be required:

  • You will need to edit the servers file and modify it accordingly
    • In Unix/BSD based systems (Linux, Mac OS X) you can usually find it under your home directory ~/.subversion/servers
    • In Windows systems it is usually in your user specific folder %APPDATA%\Subversion\servers
[global]
# http-proxy-exceptions = *.exception.com, www.internal-site.org
# http-proxy-host = defaultproxy.whatever.com
# http-proxy-port = 7000
# http-proxy-username = defaultusername
# http-proxy-password = defaultpassword
# http-compression = no
# No http-timeout, so just use the builtin default.
# No neon-debug-mask, so neon debugging is disabled.
# ssl-authority-files = /path/to/CAcert.pem;/path/to/CAcert2.pem
http-proxy-exceptions = *.example.com
http-proxy-host = proxy.example.com
http-proxy-port = 8080
http-proxy-username = myuserid
http-proxy-password = mypassword

Creating a new project for your plug-in (From release packages)

  1. Begin by Running Eclipse
  2. Having downloaded the release from the website, let's begin by creating a New Java Project
    Release1.png
  3. Give a name to your project and:
    1. select the Create project from existing source;
    2. select the path to the directory where you extracted the OptFlux release.
    3. press next;
    Release2.png
  4. Press the Create new source folder link
    1. Add a name to your plug-in, preferably under the plugins_src folder
    Release3.png
  5. Switch to the Libraries tab
    1. Press the Add JARs... button
    2. Add any jar library under the lib[your_architecture] folder. In the example we are adding some extra libraries for MacOS X (darwin64)
    Release4.png
  6. Your Eclipse workspace should look something like:
    Release4 1.png

Creating a Run Configuration to run OptFlux from within Eclipse

After creating a Project for your plug-in, you will need to create a Run Configuration in order to execute OptFlux from within Eclipse.

  1. Right-click your project;
  2. Access the Run As -> Run Configurations menu;
    Run config1.png
  3. Add a New Launch Configuration (top left icon);
  4. Fill in the fields as in the example
    Run config2.png
  5. Switch to the Arguments tab
    1. Add plugins_bin in the program arguments
    2. Add -Xmx1024m in the VM arguments (This is optional. It will increase your maximum Java heap space to 1GB. You can select any other value in the allowed range for your VM)
      Run config3.png
  6. Swich to the Environment tab
    1. You will need to create entries according to your system
      • Windows:
        • Variable: "LD_LIBRARY_PATH", value: libwin32
        • Variable: PATH, value: libwin32
      • Unix:
        • Variable: LD_LIBRARY_PATH, value: libunix32 or libunix64 depending on whether you are on 32 or 64 bit operating system
        • Variable: PATH, value: libunix32 or libunix64 depending on whether you are on 32 or 64 bit operating system
      • MacOS X:
        • Variable: DYLD_LIBRARY_PATH, value: libdarwin64
        • Variable: PATH, value: libdarwin64
      Run config4.png
  7. Click Apply and Run to see if OptFlux boots up normally

Configuring the structure of your plug-in directory

  1. Right-click the plug-in source folder (plugins_src/myplugin4optflux) and:
    1. Press Add -> New -> Package
      Release5.png
    2. Name it whatever you like. We like to use the same name for the first folder in the directory structure. In this case myplugin4optflux
      Release6.png
  2. Create the mandatory plugin.xml file:
  3. Right-click the plug-in source folder (plugins_src/myplugin4optflux) and:
    1. Press Add -> New -> File
      Release7.png
    2. Name it plugin.xml
      Release8.png
  4. To understand the structure and contents of the plugin.xml file, please refer to the The_Plugin.xml_File section.
    1. We Provide an almost empty sample here just for reference File:Plugin.xml
      Release9.png
  5. Filling the sub-directory structure with rational packages is the next step. Since AIBench/OptFlux development is based on 3 main artifacts we usually sub-divide our java classes by those 3 artifacts.
    1. This means that we should create 3 sub-packages, one for the OPERATIONS, one for the VIEWS and one for our DATATYPES.
    2. Please note that this is optional. AIBench/OptFlux are agnostic to this, we just find it easier and more structured this way.
    3. You should get something like this
    Release10.png
  6. Finally, lets specify the compile directory for our plug-in source code. This is mandatory, since OptFlux will look for the compiled plug-in in a specified directory (plugins_bin by default)
    1. Access the properties window for your project
      Release11.png
    2. Access the build path entry on the list on the left;
    3. Switch to the source tab;
    4. Select the Allow output folders for source folders checkbox on the bottom and;
    5. Select the Output folder for your plug-in and click the Edit... button
      Release12.png
    6. Specify plugins_bin/myplugin4optflux as your compilation destination, click OK and we are done.
      Release13.png

What does it take to create a plug-in?

  1. Minimum: implement a class declared as an @Operation
  2. Create your own @Datatype (s)
  3. Create your own Views for the desired Datatypes
  4. Create your own GUIs for your Operations (Advanced)

Create your first operation

Our first OptFlux operation is going to be something really simple. Say, we want our first basic operation to simply add two integers.

  • Create the MyOperation.java class inside the operations package
package myplugin4optflux.operations;

import es.uvigo.ei.aibench.core.operation.annotation.Direction;
import es.uvigo.ei.aibench.core.operation.annotation.Operation;
import es.uvigo.ei.aibench.core.operation.annotation.Port;

@Operation(description="My first OptFlux operation") //use the operation annotation so that OptFlux recognizes this class as an operation
public class MyOperation {
	
	int x, y;     // instance variables to keep my two integers
	
	@Port(name="x",direction=Direction.INPUT,order=1)   // use the port annotation with Direction = INPUT to note that this is an input of the operation
	public void setX(int x){
		this.x = x;
	}

	@Port(name="y",direction=Direction.INPUT,order=2)   // use the port annotation with Direction = INPUT to note that this is an input of the operation
	public void setY(int y){
		this.y = y;
	}
	
	@Port(direction=Direction.OUTPUT,order=3)                 "// use the port annotation with Direction = OUTPUT to note that this is an output of the operation"
	public int result(){
		return this.x + this.y;
	}
}
  • Now let's declare our new operation in the plug-in manifest, the plugin.xml file
    • We are extending the AIBench core with a new Operation, that means that we must connect to the operation-definition extension point and declare the new operation:
      Release14.png
    • Let's analyze the contents of this new entry:
      • <extension - declaration of the beginning of the new extension
        • uid="aibench.core" - This is the uid of the plug-in that contains the extension point
        • name="aibench.core.operation-definition" - The extension point to which we will connect
        • class="myplugin4optflux.operations.MyOperation"> - The path to the class that contains our operation
        • <operation-description - beginning the operation description
          • name="My Operation" - The name of the operation (this will be used in the OptFlux menus)
          • uid= "myplugin_myoperation" - The UID of our operation (this must be unique and will be useful in the future)
          • path="20@Plugins/1@MyOperations" - The path for our operation to be placed in the OptFlux menus (position@menu/position@submenu)
        • /> - close the operation description
      • </extension> - close the declaration of the new extension

Testing your first operation

  1. If everything went well you can execute OptFlux with the Run Configuration that we created before and you are ready to go
  2. You will be able to see your new operation on the menu:
    Release15.png
  3. By clicking it, you will lauch the operation. You can see that AIBench rendered a dialog GUI automatically for you. We will see how to create complex GUIs in the future.
    Release16.png
  4. Finally, executing the operation will place the result in the Clipboard. This is not the behavior that we expect in the future for OptFlux plug-ins, but we will get there.
    If you click the result object, the default view will be launched with the result
    Release17.png

CONGRATULATIONS :D - you just created your first OptFlux operation / plug-in (this one is simple though)

Creating your first Datatypes

If you are not already aware, AIBench/OptFlux is Datatype agnostic, that is, you can use whatever Datatypes you want to. However, if you want to improve the interaction of the user with the Datatypes, you can explicitly declare some properties of those same Datatypes.

For a more clear understanding of AIBench explicit Datatypes, please refer here


Creating a Simple Datatype

Let's begin by creating a simple datatype to contain an integer (see this a simple wrapper)

public class MySimpleDatatype {
	
	private int number;
	
	public MySimpleDatatype(int num){
		this.number = num;
	}

	public int getNumber() {
		return number;
	}

	public void setNumber(int number) {
		this.number = number;
	}

}
  • You can see that the datatype do not declare a STRUCTURE, this happens because, by default all types are interpreted as SIMPLE.
  • This would be the same as adding the annotation:
@Datatype(structure=Structure.SIMPLE)
public class MySimpleDatatype {
...
}

Creating a List Datatype

In this step we will create a List Datatype. This will be a wrapper to a List of SimpleDatatype:

@Datatype(structure=Structure.LIST)
public class MyListDatatype {

	private List<MySimpleDatatype> myList;
	
	public MyListDatatype(List<MySimpleDatatype> list){
		this.myList = list;
	}

	@ListElements
	public List<MySimpleDatatype> getMyList() {
		return myList;
	}

	public void setMyList(List<MySimpleDatatype> myList) {
		this.myList = myList;
	}
	
}
  • Notice that:
    • We have the @Datatype(structure=Structure.LIST) annotation, declaring this as a List Datatype;
    • The method getMyList is annotated with @ListElements. This is mandatory for List datatypes, and tells AIBench where to access our list;

Creating a Complex Datatype

Now we will imagine a Complex Datatype that will contain a List of SimpleDatatype, an Operator (either SUM, SUBTRACTION, MULTIPLICATION or DIVISION) and another SimpleDatatype that will contain the result of applying the operator to the list of elements sequentially (this example is ignoring possible division by zero exceptions):

@Datatype(structure=Structure.COMPLEX)
public class MyComplexDatatype{
	
	private MyListDatatype list;
	private OperationEnumeration operation;
	private MySimpleDatatype result;
	
	public MyComplexDatatype(MyListDatatype list, OperationEnumeration operation,MySimpleDatatype result){
		this.list = list;
		this.operation = operation;
		this.result = result;
	}

	@Clipboard(name="Operation",order=1)
	public OperationEnumeration getOperation() {
		return operation;
	}
	
	@Clipboard(name="List of Elements",order=2)
	public MyListDatatype getList() {
		return list;
	}
	
	@Clipboard(name="Result",order=3)
	public MySimpleDatatype getResult() {
		return result;
	}
}
  • Notice that:
    • The class is annotated with @Datatype(structure=Structure.COMPLEX) annotation, declaring this as a Complex Datatype
    • The methods that give access to each of our class variables are annotated with @Clipboard(). This is mandatory.
      • The name property will be used as a name to display in the Clipboard.
      • The order property is the relative order by which each element will be displayed.

Final Remarks Regarding datatypes

  • The @Datatype annotation contains several properties that can be specified. Please refer here for that.
  • You don't need to declare the Datatypes in the plugin.xml file. This will be capture automatically by AIBench/OptFlux when used in Operations or placed in the Clipboard.

Creating your first View