User Guide

Introduction

The aim of this document is to describe in detail the Artificial Life framework, which is a mutli-agent system designed to run within the same Operating System process. The agents run in the same OS process mainly for speed and also to avoid implementing a complex system to share information between agents.

Artificial Life uses threads to run the concurrent agents. Developing and debuging applications using lots of threads is known to be difficult. The framework addresses those difficulties by implementing mechanisms using messaging systems (Messenger, MethodInvocation and Event).

The framework defines two types of agents: The services and the processes. The processes are agents that perform tasks and the services are agents that provide services to the processes.

The agents are organized in a tree structure called Instance. Within an Instance, the services and the processes are grouped together and an unlimited number of groups can be defined. Each node of the Instance tree can have a collection of views used to monitor the activity of the node or interact with the node.

Each Instance has an Instance Model; Instance Models are basically lists of Class Definitions organized in a tree structure where Class Definitions record paths to classes (Java classes). Instance Models are used in Instance Manager to define the list of classes (Java classes) that can be added to Instances (Service, Process or Views). Instance Models can be seen as libraries.

Please note that a good understanding of Java programming is a prerequisite.


Content


I. Architecture

1. Tools

a. Instance Server

b. Model Composer

c. Instance Manager

2. API


II. How To:


I. Architecture

Artificial Life can be decomposed in two parts: The tools used to manage and run the Instances and the API.

1. Tools

a. Instance Server

Instance Server runs Instances and can be remotely managed by using Telnet (Port 4000).

b. Model Composer

Model Composer is used to manipulate the Instance Models: Add, update or delete Class Definitions.

c. Instance Manager

Instance Manager is used to create, modify, delete, run, import or export Instances. You will use this tool to add or delete classes (Service, Process or Views) in Instances.

Instance Manager uses Instance Server to run Instances.

Artificial Life provides two ways to run your agent code:
- By coping your compiled agent code in the ext sub folder (for extensions) of Artificial Life and then by running directly Instance Manager
- By launching Instance Manager from your project (This technique will give you the possibility to debug your code with your favorite Java IDE). Here is an example of a class that you can add to your project:


import org.artificialLife.tools.common.*;

public class InstanceManager extends ALTool
{
    public InstanceManager() 
    {
        super(new org.artificialLife.tools.instanceManager.InstanceManagerFrame());
    }
    
    public static void main(String args[]) 
    {
        new InstanceManager().run();
    }
}



2. API

The API defines the interfaces that the agents and the views implement and provide all the necessary services that you will need to run Instances.


II. How To:

  • Create a service
    
    package myproject;
    
    import org.artificialLife.kernel.*;
    
    public class MyService extends Service
    {
        public MyService()
        {
            super("My Service");        
        }
    
        protected void run()
        {
            while (!this.stopRequested())
            {
                // Do something...
            }
        }
    }
    
    
    
  • Create a process

    
    
    package myproject;
    
    import org.artificialLife.kernel.*;
    
    public class MyAgent extends ALProcess
    {
        public MyAgent()
        {
             super("My Agent");
        }
    
        protected void run()
        {
            while (!this.stopRequested())
            {
                // Do something...
            }
        }
    }
    
    
    
  • Create a view

    
    
    package myproject;
    
    import org.artificialLife.system.*;
    
    public class MyServiceView extends View
    {
        public MyServiceView()
        {
            super("My Service");
        }
    
        public void setContext(ALComponent context)
        {
            Service s;
            
            if (context != null)
            {
                if (context instanceof MyService)
                {
                    service = (MyService) context;
    
                    // Initialize the view...
                }
            }
        }
    }
    
    
    
  • Store a property

    
    
    package myproject;
    
    import org.artificialLife.kernel.*;
    
    public class MyService extends Service
    {
        private String myProperty;
    
        public MyService()
        {
            super("My Service");        
        }
    
        protected void run()
        {
            while (!this.stopRequested())
            {
                // Do something...
            }
        }
    
        @ALProperty (displayName = "My Property")
        public String getMyProperty()
        {
            return myProperty;
        }
    
        public void setMyProperty(String myProperty)
        {
            this.myProperty = myProperty;
        }
    }
    
    
    
  • Settings

    
    
    import org.artificialLife.system.*;
    
    public MyClass
    {
        public MyClass()
        {
        }
    
        public void MyMethod() 
        {
            Setting setting;
            String value;
            
            setting = ALSystem.settings.get("MY_SETTING");
    
            if (setting == null)
            {
                value = "Setting value";
    
                ALSystem.settings.setDefault("MY_SETTING", value);
            }
            else
            {
                value = (String)setting.getValue();
            }
    
            ALSystem.settings.delete("MY_SETTING");
        }
    }
    
    
    
  • Logging

    
    
    import org.artificialLife.system.*;
    
    public MyClass
    {
        public MyClass()
        {
        }
    
        public void MyMethod() 
        {
            ALSystem.logs.log(new InformationLog("My Project", "Information"));
    
            ALSystem.logs.log(new DebugLog("My Project", "Debug information"));
    
            ALSystem.logs.log(new ErrorLog("My Project", "Error"));
        }
    }
    
    
    
  • Method Invocation

    
    
    // A service
    
    package myproject;
    
    import org.artificialLife.kernel.*;
    
    public class MyService extends Service
    {
        public MyService()
        {
            super("My Service");        
        }
    
        protected void run()
        {
            while (!this.stopRequested())
            {
                // Do something...
            }
        }
    
        public void myMethod()
        {
        }
    }
    
    // Invocation from an agent
    
    package myproject;
    
    import org.artificialLife.kernel.*;
    import org.artificialLife.mi.*;
    
    public class MyAgent extends ALProcess
    {
        public MyAgent()
        {
            super("My Agent");
        }
    
        protected void run()
        {
            MyService service;
    
            ...
    
            while (!this.stopRequested())
            {
                ...
    
                // Method invocation using the method invocation handler of the service
                new MethodInvocator(service.getMethodInvocationHandler()).invoke(service, 
                  "myMethod", new Class[] {}, new Object[] {});
    
                ...
    
            }
        }
    }
    
    
    
  • Event

    
    
    // An event
    
    package myproject;
    
    import org.artificialLife.events.*;
    
    public class MyEvent extends Event
    {
        public MyEvent()
        {
        }
    }
    
    
    // A service dispatching and receiving events
    
    package myproject;
    
    import org.artificialLife.kernel.*;
    import org.artificialLife.events.*;
    import org.artificialLife.system.*;
    
    public class MyService extends Service
    {
        private EventDispatcher eventDispatcher;
        private QueuedEventListener eventListener;
    
        public MyService()
        {
            super("My Service");
    
            eventDispatcher = new EventDispatcher();
    
            eventListener = new QueuedEventListener()
            {
                public void takeEvent(Event event)
                {
                    try
                    {
                        if (event instanceof MyEvent)
                        {
                            // Do something...
                        }
                    }
                    catch (Exception e)
                    {
                        ALSystem.logs.log(new ErrorLog("My Project", e));
                    }
                }
            };
        }
    
        protected void run()
        {
            while (!this.stopRequested())
            {
                // Do something...
            }
        }
    
        @Override
        public void start()
        {
            if (!this.isRunning())
            {
                eventDispatcher.start();
    
                eventListener.start();
    
                eventDispatcher.addListener(eventListener);
    
                super.start();
            }
        }
    
        @Override
        public void stop()
        {
            if (this.isRunning())
            {
                eventDispatcher.stop();
    
                eventDispatcher.removeListener(eventListener);
    
                eventListener.stop();
    
                super.stop();
            }
        }
    
        public EventDispatcher getEventDispatcher()
        {
            return eventDispatcher;
        }
    }
    
    // Send events from an agent
    
    package myproject;
    
    import org.artificialLife.kernel.*;
    import org.artificialLife.events.*;
    
    public class MyAgent extends ALProcess
    {
        public MyAgent()
        {
            super("My Agent");
        }
    
        protected void run()
        {
            MyService service;
            MyEvent event;
    
            ...
    
            while (!this.stopRequested())
            {
                ...
    
            
                event = new MyEvent();
    
                service.getEventDispatcher.fireEvent(event);
    
                ...
    
            }
        }
    }
    
    
    
  • Find a service

    
    
    package myproject;
    
    import org.artificialLife.system.*;
    import org.artificialLife.kernel.*;
    
    public class MyAgent extends ALProcess
    {
        public MyAgent()
        {
            super("My Agent");
        }
    
        @Override
        public void start()
        {
            Service service;
    
            if (!this.isRunning())
            {
                // Find a service ascending in the Instance tree
                service = new AscServiceLocator(this).findFirst(MyService.class);
    
                if (service == null)
                {
                    throw new SystemException("Service not found.");
                }
    
                // Find a service descending in the Instance tree
                service = new DescServiceLocator(this).findFirst(MyService.class);
    
                if (service == null)
                {
                    throw new SystemException("Service not found.");
                }
    
                super.start();
            }
        }
    
        protected void run()
        {
             while (!this.stopRequested())
            {
                // Do something...
            }
        }
    }
    
    
    
  • Reference and de-reference a service

    
    
    package myproject;
    
    import org.artificialLife.system.*;
    import org.artificialLife.kernel.*;
    
    public class MyAgent extends ALProcess
    {
        public MyAgent()
        {
            super("My Agent");
        }
    
        @Override
        public void start()
        {
            Service service;
    
            if (!this.isRunning())
            {
                service = new AscServiceLocator(this).findFirst(MyService.class);
    
                if (service == null)
                {
                    throw new SystemException("Service not found.");
                }
    
                // Reference the service
                this.getReferencedServices().referenceService("MyService", service);
    
                super.start();
            }
        }
    
        @Override
        public void stop()
        {
            if (this.isRunning())
            {
                super.stop();
    
                // De-reference the service
                this.getReferencedServices().dereferenceService("MyService");
            }
        }
    
        protected void run()
        {
             while (!this.stopRequested())
            {
                // Do something...
            }
        }
    }
    
    
    
  • Use referenced service

    
    
    package myproject;
    
    import org.artificialLife.system.*;
    import org.artificialLife.kernel.*;
    
    public class MyAgent extends ALProcess
    {
        public MyAgent()
        {
            super("My Agent");
        }
    
        @Override
        public void start()
        {
            Service service;
    
            if (!this.isRunning())
            {
                service = new AscServiceLocator(this).findFirst(MyService.class);
    
                if (service == null)
                {
                    throw new SystemException("Service not found.");
                }
    
                this.getReferencedServices().referenceService("MyService", service);
    
                super.start();
            }
        }
    
        @Override
        public void stop()
        {
            if (this.isRunning())
            {
                super.stop();
    
                this.getReferencedServices().dereferenceService("MyService");
            }
        }
    
        protected void run()
        {
            MyService service;
    
            // Use the referenced service
            service = (MyService)this.getReferencedServices().getService("MyService");
    
            while (!this.stopRequested())
            {
                // Do something...
            }
        }
    }