Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Splits the behaviour inherit structure into simple and compound behaviours #46

Open
wants to merge 1 commit into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
144 changes: 51 additions & 93 deletions pade/behaviours/base.py
Original file line number Diff line number Diff line change
@@ -1,124 +1,82 @@
'''
This file implements the needed Behaviour class extensions, in
order to PADE Scheduler be able to manage the agent behaviours.
'''
"""Framework for Intelligent Agents Development - PADE

from pade.behaviours.protocols import Behaviour
from pade.acl.messages import ACLMessage
from time import sleep
import queue
The MIT License (MIT)

class BaseBehaviour(Behaviour):
Copyright (c) 2019 Lucas S Melo

''' BaseBehaviour class ihnerits from Behaviour class and
implements the basic methods for scheduled behaviours.
'''

def __init__(self, agent):
''' This method initializes a new instance of BaseBehaviour
class and explicitly calls the Behaviour.__init__() method.
'''
super().__init__(agent)
# Queue of received messages by the agent and unread by this behaviour
self.messages = queue.Queue()
# Lock object (to ensure the mutual exclusion, when needed)
self.__lock = None
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.

def read(self, block = True):
''' It gets the first message in the local message queue.
'''
if block:
return self.messages.get()
else:
try:
return self.messages.get_nowait()
except queue.Empty:
return None


def send(self, message):
''' This method gets a message and passes it to self.agent.send() method.
It was coded just to complement the pair read/send in the BaseBehaviour class.
The method self.agent.send() can still be used directly in the code.
'''
self.agent.send(message)
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

Behaviours module
-----------------

def read_timeout(self, timeout):
''' It tries to read a message twice until the end of timeout.
In cases of no messages, this method returns None
'''
message = self.read(block = False)
if message != None:
return message
else:
sleep(timeout)
return self.read(block = False)
This module implements the base of the Behaviours classes, in order to enable
the PADE Scheduler to manage the agent behaviours.

@author: Italo Campos
"""

def receive(self, message):
''' It sets a new message on local messages queue.
'''
if isinstance(message, ACLMessage):
self.messages.put(message)
else:
raise ValueError('message object type must be ACLMessage!')
from pade.behaviours.protocols import Behaviour
from pade.acl.messages import ACLMessage
import queue, time

class BaseBehaviour(Behaviour):
''' The basic behaviour class.

This class inherits from Behaviour class and implements the basic methods
for scheduled behaviours.
'''

def action(self):
''' This is an abstract method that must be overridden in the
child classes, writing the main actions of this behaviour.
''' An abstract method that performs the actions of the behaviour.

This method must be overridden in the subclasses.
'''

pass


def done(self):
''' This is an abstract method that must be overridden in the
child classes, dealing with the finish of this behaviour.
''' Defines when the behaviour ends.

This method must be overridden in the subclasses.
'''

pass


def wait(self, timeout):
''' This method sleeps a behaviour until occurs a timeout. The
behaviour will execute normally afterwards.
'''
sleep(timeout)

''' Sleeps a behaviour until occurs a timeout.

def on_end(self):
''' The scheduler will calls this method after the self.done()
method returns True and before the end of this behaviour. It is
the last action of a behaviour.
Parameters
----------
timeout : float
The time to be waited.
'''
pass


def has_messages(self):
''' A method to returns if this behaviour has messages in its
received messages queue.
'''
return self.messages.qsize() != 0
time.sleep(timeout)


def add_lock(self, lock):
''' Adds a threading.Lock object to this behaviour, allowing
it to execute the mutual exclusion correctly.
'''
self.__lock = lock

def on_end(self):
''' Executes the final actions of the behaviou.

def lock(self):
''' Tries to acquire the lock of the threading.Lock object.
The behaviour will block if fails.
The scheduler will call this method after the behaviour ends. May be
overriden in subclasses.
'''
self.__lock.acquire()


def unlock(self):
''' Releases the lock of the threading.Lock object, allowing
the other behaviours to acquire it.
'''
self.__lock.release()
pass
Loading