- Add support for abtract python classes

- Create first modules: the Policy Python class


git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@335 3ecf2c5c-341e-0410-92b4-d18e462d057c
This commit is contained in:
tchernobog 2006-02-16 22:50:32 +00:00
parent 5554ec2256
commit b6c49d98d6
6 changed files with 145 additions and 38 deletions

View File

@ -55,7 +55,7 @@ sgpemv2_SOURCES = \
observer.cc \ observer.cc \
parse_opts.cc \ parse_opts.cc \
simulation.cc \ simulation.cc \
standard_io.cc \ standard_io.cc \
start_gui.cc start_gui.cc
noinst_HEADERS = \ noinst_HEADERS = \

View File

@ -30,36 +30,35 @@
namespace sgpem namespace sgpem
{ {
class Policy;
class Policy;
/** \brief /** \brief
e' una Strategy che rappresenta un algoritmo di scheduling che implementa una politica e' una Strategy che rappresenta un algoritmo di scheduling che implementa una politica
di scheduling. di scheduling.
*/ */
class SG_DLLEXPORT Policy class SG_DLLEXPORT Policy
{ {
public: public:
virtual ~Policy(); virtual ~Policy();
virtual void configure() = 0; virtual void configure() = 0;
virtual void sort_queue(sgpem::Scheduler::event) const = 0; virtual void sort_queue(sgpem::Scheduler::event) const = 0;
int get_id() const; int get_id() const;
virtual Glib::ustring get_description() const = 0; virtual Glib::ustring get_description() const = 0;
virtual bool is_pre_emptive() const = 0; virtual bool is_pre_emptive() const = 0;
virtual int get_time_slice() const = 0; virtual int get_time_slice() const = 0;
virtual void set_time_slice(const int&) = 0; virtual void set_time_slice(const int&) = 0;
const PolicyParameters& get_parameters() const; const PolicyParameters& get_parameters() const;
private: private:
PolicyParameters _parameters; PolicyParameters _parameters;
int _id; int _id;
}; };
}//~ namespace sgpem }//~ namespace sgpem
#endif #endif

View File

@ -27,19 +27,17 @@
namespace sgpem namespace sgpem
{ {
class PolicyManager;
class SG_DLLEXPORT PolicyManager
{
public:
virtual ~PolicyManager() = 0;
class PolicyManager; virtual Policy& get_policy() = 0;
virtual void init() = 0;
class SG_DLLEXPORT PolicyManager };
{
public: } //~ namespace sgpem
virtual ~PolicyManager() = 0;
virtual Policy* get_policy() = 0;
virtual void init() = 0;
};
}
#endif #endif

94
src/pyloader/Abstract.py Normal file
View File

@ -0,0 +1,94 @@
class AbstractMethod (object):
"""Defines a class to create abstract methods
@example:
class Foo:
foo = AbstractMethod('foo')
"""
def __init__(self, func):
"""Constructor
@params func: name of the function (used when raising an
exception).
@type func: str
"""
self._function = func
def __get__(self, obj, type):
"""Get callable object
@returns An instance of AbstractMethodHelper.
This trickery is needed to get the name of the class for which
an abstract method was requested, otherwise it would be
sufficient to include a __call__ method in the AbstractMethod
class itself.
"""
return self.AbstractMethodHelper(self._function, type)
class AbstractMethodHelper (object):
"""Abstract method helper class
An AbstractMethodHelper instance is a callable object that
represents an abstract method.
"""
def __init__(self, func, cls):
self._function = func
self._class = cls
def __call__(self, *args, **kwargs):
"""Call abstract method
Raises a TypeError, because abstract methods can not be
called.
"""
raise TypeError('Abstract method `' + self._class.__name__ \
+ '.' + self._function + '\' called')
class Metaclass (type):
def __init__(cls, name, bases, *args, **kwargs):
"""Configure a new class
@param cls: Class object
@param name: Name of the class
@param bases: All base classes for cls
"""
super(Metaclass, cls).__init__(cls, name, bases, *args, **kwargs)
# Detach cls.new() from class Metaclass, and make it a method
# of cls.
cls.__new__ = staticmethod(cls.new)
# Find all abstract methods, and assign the resulting list to
# cls.__abstractmethods__, so we can read that variable when a
# request for allocation (__new__) is done.
abstractmethods = []
ancestors = list(cls.__mro__)
ancestors.reverse() # Start with __builtin__.object
for ancestor in ancestors:
for clsname, clst in ancestor.__dict__.items():
if isinstance(clst, AbstractMethod):
abstractmethods.append(clsname)
else:
if clsname in abstractmethods:
abstractmethods.remove(clsname)
abstractmethods.sort()
setattr(cls, '__abstractmethods__', abstractmethods)
def new(self, cls):
"""Allocator for class cls
@param self: Class object for which an instance should be
created.
@param cls: Same as self.
"""
if len(cls.__abstractmethods__):
raise NotImplementedError('Can\'t instantiate class `' + \
cls.__name__ + '\';\n' + \
'Abstract methods: ' + \
", ".join(cls.__abstractmethods__))
return object.__new__(self)

View File

@ -54,4 +54,5 @@ libpyloader_la_SOURCES = \
noinst_HEADERS = python_policy.hh \ noinst_HEADERS = python_policy.hh \
python_policy_manager.hh python_policy_manager.hh
mod_PYTHON = Abstract.py \
Policy.py

15
src/pyloader/Policy.py Normal file
View File

@ -0,0 +1,15 @@
''' from sgpem import SchedulableQueue, PolicyParameters '''
from Abstract import *
class Policy:
'''
Avoid instantiation of an abstract class.
'''
__metaclass__ = Metaclass
configure = AbstractMethod('configure')
sort_queue = AbstractMethod('sort_queue')
is_preemptive = AbstractMethod('is_preemptive')
is_time_sliced = AbstractMethod('is_time_sliced')
get_parameters = AbstractMethod('get_parameters')