- documentation and warning removal: holt_widget.??,

simulation_widget.hh holt_container_window.cc



git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@1180 3ecf2c5c-341e-0410-92b4-d18e462d057c
This commit is contained in:
paolo 2006-09-15 22:14:23 +00:00
parent 715e51dc9d
commit 0cbe635c1e
4 changed files with 533 additions and 91 deletions

View File

@ -77,7 +77,9 @@ HoltContainerWindow::on_button_press_event(GdkEventButton* event)
" <popup name='PopupMenu'>"; " <popup name='PopupMenu'>";
HoltWidget::arrange_mode arrange = _holt_widget.get_arrange_mode(); HoltWidget::arrange_mode arrange = _holt_widget.get_arrange_mode();
CairoWidget::scaling_mode scaling = _holt_widget.get_scaling_mode();
// actually unused
//CairoWidget::scaling_mode scaling = _holt_widget.get_scaling_mode();
RefPtr<ActionGroup> action_group = Gtk::ActionGroup::create(); RefPtr<ActionGroup> action_group = Gtk::ActionGroup::create();

View File

@ -58,7 +58,6 @@ using namespace std;
HoltNode::HoltNode(Vec2 pt) HoltNode::HoltNode(Vec2 pt)
: _radius(20) : _radius(20)
{ {
//_x = pt.real(); _y = pt.imag();
_pos = pt; _pos = pt;
} }
@ -92,9 +91,6 @@ double HoltNode::get_radius()
return _radius; return _radius;
} }
// double HoltNode::_radius = 20;
HoltResource::HoltResource(const Resource& resource, resource_key_t resource_key, Vec2 pt) HoltResource::HoltResource(const Resource& resource, resource_key_t resource_key, Vec2 pt)
: HoltNode(pt) : HoltNode(pt)
@ -195,7 +191,7 @@ void HoltSchedulable::draw(cairo_t *cr)
cairo_save(cr); // save context state cairo_save(cr); // save context state
const Point center(_pos.real(), _pos.imag()); const Point center(_pos.real(), _pos.imag());
const Color* color; const Color* color = &red;
// draw circle // draw circle
CairoElements cel(cr); CairoElements cel(cr);
@ -240,9 +236,15 @@ void HoltSchedulable::draw(cairo_t *cr)
Vec2 HoltSchedulable::get_intersection_to(Vec2 pt) Vec2 HoltSchedulable::get_intersection_to(Vec2 pt)
{ {
// schedulables ar circles
// intersection is a radius from center then...
Vec2 final = _pos; Vec2 final = _pos;
// take segment
Vec2 segment = pt - _pos; Vec2 segment = pt - _pos;
double len = std::abs(segment); double len = std::abs(segment);
// and normalize to radius
if(len>0) if(len>0)
{ {
segment *= _radius/len; segment *= _radius/len;
@ -270,7 +272,7 @@ void HoltRequest::draw(cairo_t *cr)
Vec2 schedulable = _hr->get_intersection_to(_hp->get_position()); Vec2 schedulable = _hr->get_intersection_to(_hp->get_position());
cairo_save(cr); cairo_save(cr);
// cairo_set_line_width(cr, 0.5*cairo_get_line_width(cr));
switch(_state) switch(_state)
{ {
case Request::state_unallocable: case Request::state_unallocable:
@ -278,15 +280,19 @@ void HoltRequest::draw(cairo_t *cr)
cairo_set_source_rgb(cr, 1, 0, 0); cairo_set_source_rgb(cr, 1, 0, 0);
arrow(cr, schedulable, resource); arrow(cr, schedulable, resource);
break; break;
case Request::state_allocated: case Request::state_allocated:
// green // green
cairo_set_source_rgb(cr, 0, 1, 0); cairo_set_source_rgb(cr, 0, 1, 0);
arrow(cr, resource, schedulable); arrow(cr, resource, schedulable);
break; break;
case Request::state_future: case Request::state_future:
break; break;
case Request::state_exhausted: case Request::state_exhausted:
break; break;
case Request::state_allocable: case Request::state_allocable:
// yellow // yellow
cairo_set_source_rgb(cr, 1, 0.7, 0); cairo_set_source_rgb(cr, 1, 0.7, 0);
@ -294,22 +300,51 @@ void HoltRequest::draw(cairo_t *cr)
break; break;
} }
// stroke all // stroke all and restore status
cairo_stroke (cr); cairo_stroke (cr);
cairo_restore(cr); cairo_restore(cr);
} }
void HoltRequest::arrow(cairo_t *cr, Vec2 first, Vec2 second) void HoltRequest::arrow(cairo_t *cr, Vec2 first, Vec2 second)
{ {
// option to draw the line a little translated
// this allow to draw two counterflow arrows
// without overlap
bool traslate = true;
double line_width = cairo_get_line_width(cr);
if(traslate)
{
// if needed calc parallel versor of arrow
Vec2 direction = second-first;
direction /= std::abs(direction); // set unary modulus
// and rotate it 90 degrees
Vec2 dir_rotation(0.0, 1.0);
direction *= dir_rotation;
// translation modulus equals line width
direction *= line_width;
first += direction;
second += direction;
}
// draw main line
cairo_move_to(cr, second.real(), second.imag()); cairo_move_to(cr, second.real(), second.imag());
cairo_line_to(cr, first.real(), first.imag()); cairo_line_to(cr, first.real(), first.imag());
// some calculation to draw arrowpoint...
// take a short line parallel to main line
Vec2 arrowside = second-first; Vec2 arrowside = second-first;
arrowside *= 10.0/std::abs(arrowside); arrowside *= 15.0*line_width/std::abs(arrowside);
Vec2 deviation(5.0, 1.0); deviation /= std::abs(deviation);// = std::polar(1,M_PI/6.0); // make a rotation component
Vec2 deviation(5.0, 1.0); deviation /= std::abs(deviation);
// make left and right sides rotating that first short line
Vec2 side1 = arrowside * deviation; Vec2 side1 = arrowside * deviation;
Vec2 side2 = arrowside * conj(deviation); Vec2 side2 = arrowside * conj(deviation);
// draw one side
cairo_move_to(cr, first.real(), first.imag()); cairo_move_to(cr, first.real(), first.imag());
cairo_line_to(cr, first.real()+side1.real(), first.imag()+side1.imag()); cairo_line_to(cr, first.real()+side1.real(), first.imag()+side1.imag());
// draw the other side
cairo_move_to(cr, first.real(), first.imag()); cairo_move_to(cr, first.real(), first.imag());
cairo_line_to(cr, first.real()+side2.real(), first.imag()+side2.imag()); cairo_line_to(cr, first.real()+side2.real(), first.imag()+side2.imag());
} }
@ -323,15 +358,15 @@ void HoltRequest::arrow(cairo_t *cr, Vec2 first, Vec2 second)
HoltWidget::HoltWidget(Simulation& simulation) HoltWidget::HoltWidget(Simulation& simulation)
: Glib::ObjectBase("sgpem_HoltWidget"), : Glib::ObjectBase("sgpem_HoltWidget"),
CairoWidget(),
SimulationObserver(), SimulationObserver(),
HistoryObserver(), HistoryObserver(),
CairoWidget(),
_simulation(&simulation), _simulation(&simulation),
_radius(20),
_n_proc(0), _n_proc(0),
_n_res(0), _n_res(0),
_radius(20), _arrange_mode(arrange_horizontal),
_show_threads(false), _show_threads(false)
_arrange_mode(arrange_horizontal)
{ {
// Register this SimulationObserver: // Register this SimulationObserver:
@ -374,7 +409,6 @@ HoltWidget::set_radius(double radius)
double old_radius = _radius; double old_radius = _radius;
if(radius>0) if(radius>0)
_radius = radius; _radius = radius;
// resize_redraw();
return old_radius; return old_radius;
} }
@ -390,27 +424,53 @@ HoltWidget::set_arrange_mode(arrange_mode mode)
arrange_mode old_mode = _arrange_mode; arrange_mode old_mode = _arrange_mode;
_arrange_mode = mode; _arrange_mode = mode;
arrange(); arrange();
// resize_redraw();
return old_mode; return old_mode;
} }
void void
HoltWidget::arrange() HoltWidget::arrange()
{ {
#ifndef NDEBUG
std::cout << "HoltWidget::arrange" << endl; std::cout << "HoltWidget::arrange" << endl;
// cout << "START:" << endl; #endif
// _x_req = 0;
// _y_req = 0;
Vec2 pos, inc, mul, cen; // Differents graph's dispositions are made easy by
// usual complex number algebra:
//
// v1 += v2 - translation
// v1 *= d - scaling
// v1 *= v2 - rotating if abs(v2)==1.0
// v1 *= v2 - rotating and scaling by modulus if abs(v2)!=1.0
//
// where v1, v2 are Vec2 (complex<double>), d is double
//
// to draw a linear disposition the algorithm starts with
// first desired position and sums an inc vetor each step
//
// to draw a circular disposition the center and radius are taken
// then every position is calculated summing to center a radius (inc)
// vector. The inc vector is rotated each step
//
Vec2 pos; // position of current HoltNode derived object (all)
Vec2 inc; // increment (vertical and horizontal) or radius (circular)
Vec2 cen; // center of rotation (circular only)
Vec2 mul; // rotation multiplier (circular only)
// vectors building
if(_arrange_mode==arrange_horizontal) if(_arrange_mode==arrange_horizontal)
{ {
// first position
pos = Vec2(2*_radius, 2*_radius); pos = Vec2(2*_radius, 2*_radius);
// increment
inc = Vec2(3*_radius, 0); inc = Vec2(3*_radius, 0);
} }
else if(_arrange_mode==arrange_vertical) else if(_arrange_mode==arrange_vertical)
{ {
// first position
pos = Vec2(2*_radius, 2*_radius); pos = Vec2(2*_radius, 2*_radius);
// increment
inc = Vec2(0, 3*_radius); inc = Vec2(0, 3*_radius);
} }
else // _arrange_mode==arrange_circular else // _arrange_mode==arrange_circular
@ -418,33 +478,39 @@ HoltWidget::arrange()
int sx = _draw_w; // get_width(); int sx = _draw_w; // get_width();
int sy = _draw_h; // get_height(); int sy = _draw_h; // get_height();
int nelem = _holt_resources.size()+_holt_schedulables.size(); int nelem = _holt_resources.size()+_holt_schedulables.size();
if(sx<=sy) if(nelem>1)
inc = Vec2(sx/2-2*_radius, 0); {
// take minimum between x and y
if(sx<=sy)
inc = Vec2(-(sx/2-2*_radius), 0);
else
inc = Vec2(-(sy/2-2*_radius), 0);
}
else else
inc = Vec2(sy/2-2*_radius, 0); {
// zero or one object always at center
inc = Vec2(0, 0);
}
// calc rotation angle
if(nelem>0) if(nelem>0)
mul = Vec2(cos(2*M_PI/(double)nelem), sin(2*M_PI/(double)nelem)); mul = Vec2(cos(2*M_PI/(double)nelem), sin(2*M_PI/(double)nelem));
else else
mul = Vec2(0,0); mul = Vec2(0,0);
// cen = Vec2(sx/2, sy/2);
cen = Vec2(2*_radius+inc.real(), 2*_radius+inc.real()); cen = Vec2(2*_radius+inc.real(), 2*_radius+inc.real());
pos = inc + cen; pos = inc + cen;
// cout << "A) pos=" << pos << " cen=" << cen << " inc=" << inc << " mul=" << mul << endl;
} }
// positions all resources
HoltResources::const_iterator riter = _holt_resources.begin(); HoltResources::const_iterator riter = _holt_resources.begin();
while(riter!=_holt_resources.end()) while(riter!=_holt_resources.end())
{ {
HoltResource* hr = (*riter).second; HoltResource* hr = (*riter).second;
// cout << "r-A) pos=" << pos << " cen=" << cen << " inc=" << inc << " mul=" << mul << endl;
hr->set_position(pos); hr->set_position(pos);
hr->set_radius(_radius); hr->set_radius(_radius);
/*
if(pos.real()+_radius>_x_req) // calc next position
_x_req = pos.real()+_radius;
if(pos.imag()+_radius>_y_req)
_y_req = pos.imag()+_radius;
*/
if(_arrange_mode!=arrange_circular) if(_arrange_mode!=arrange_circular)
{ {
pos += inc; pos += inc;
@ -455,9 +521,11 @@ HoltWidget::arrange()
pos = cen + inc; pos = cen + inc;
} }
riter++; riter++;
// cout << "r-B) pos=" << pos << " cen=" << cen << " inc=" << inc << " mul=" << mul << endl;
} }
// positions all schedulables
// if linear disposition then must reevaluate start and increment
// when circular continue with previous values to end circle
if(_arrange_mode==arrange_horizontal) if(_arrange_mode==arrange_horizontal)
{ {
pos = Vec2(2*_radius, 8*_radius); pos = Vec2(2*_radius, 8*_radius);
@ -473,15 +541,9 @@ HoltWidget::arrange()
while(piter!=_holt_schedulables.end()) while(piter!=_holt_schedulables.end())
{ {
HoltSchedulable* hp = (*piter); HoltSchedulable* hp = (*piter);
// cout << "p-A) pos=" << pos << " cen=" << cen << " inc=" << inc << " mul=" << mul << endl;
hp->set_position(pos); hp->set_position(pos);
hp->set_radius(_radius); hp->set_radius(_radius);
/*
if(pos.real()+_radius>_x_req)
_x_req = pos.real()+_radius;
if(pos.imag()+_radius>_y_req)
_y_req = pos.imag()+_radius;
*/
if(_arrange_mode!=arrange_circular) if(_arrange_mode!=arrange_circular)
{ {
pos += inc; pos += inc;
@ -491,7 +553,6 @@ HoltWidget::arrange()
inc *= mul; inc *= mul;
pos = cen + inc; pos = cen + inc;
} }
// cout << "p-B) pos=" << pos << " cen=" << cen << " inc=" << inc << " mul=" << mul << endl;
piter++; piter++;
} }
@ -518,23 +579,21 @@ HoltWidget::set_show_threads(bool show)
void void
HoltWidget::update(const Simulation& changed_simulation) HoltWidget::update(const Simulation& /*changed_simulation*/)
{ {
std::cout << "HoltWidget::update - Simulation" << endl;
// Force redraw
//redraw();
// acquire();
// resize_redraw();
} }
void void
HoltWidget::update(const History& changed_history) HoltWidget::update(const History& /*changed_history*/)
{ {
#ifndef NDEBUG
std::cout << "HoltWidget::update - History" << endl; std::cout << "HoltWidget::update - History" << endl;
// Force redraw #endif
//redraw(); // take new data
acquire(); acquire();
// Force redraw
resize_redraw(); resize_redraw();
} }
@ -544,7 +603,9 @@ HoltWidget::update(const History& changed_history)
void void
HoltWidget::acquire() HoltWidget::acquire()
{ {
#ifndef NDEBUG
std::cout << "HoltWidget::acquire" << endl; std::cout << "HoltWidget::acquire" << endl;
#endif
const HoltResources& const_holt_resources = _holt_resources; const HoltResources& const_holt_resources = _holt_resources;
for(Iseq<HoltResources::const_iterator> it = iseq(const_holt_resources); it; ++it) for(Iseq<HoltResources::const_iterator> it = iseq(const_holt_resources); it; ++it)
@ -603,9 +664,6 @@ HoltWidget::acquire()
} }
// iter trough threads, requests, subrequests // iter trough threads, requests, subrequests
// FIXME
// typedef std::vector<Thread*> Threads;
// typedef std::vector<Thread*>::const_iterator thr_iterator;
const std::vector<Thread*>& tvect = p->get_threads(); const std::vector<Thread*>& tvect = p->get_threads();
std::vector<Thread*>::const_iterator thr_iter = tvect.begin(); std::vector<Thread*>::const_iterator thr_iter = tvect.begin();
while(thr_iter!=tvect.end()) while(thr_iter!=tvect.end())
@ -661,8 +719,6 @@ HoltWidget::acquire()
// associates process (or thread) with resource) // associates process (or thread) with resource)
HoltRequest *hreq = new HoltRequest(*hp, *(hpos->second), sr->get_state()); HoltRequest *hreq = new HoltRequest(*hp, *(hpos->second), sr->get_state());
_holt_requests.push_back(hreq); _holt_requests.push_back(hreq);
// cout << "added HoltRequest\n"
// os << " name: " << pos->second->get_name();
} }
} // ~ if(subr_state==Request::state_unallocable ... etc } // ~ if(subr_state==Request::state_unallocable ... etc
/* /*
@ -686,7 +742,9 @@ HoltWidget::acquire()
void void
HoltWidget::draw_widget(cairo_t* ctx) HoltWidget::draw_widget(cairo_t* ctx)
{ {
#ifndef NDEBUG
std::cout << "HoltWidget::draw_widget" << endl; std::cout << "HoltWidget::draw_widget" << endl;
#endif
// dispose objects // dispose objects
arrange(); arrange();
@ -754,7 +812,6 @@ HoltWidget::calc_drawing_size(cairo_t* ctx, size_t& width, size_t& height)
max = _n_res; max = _n_res;
cairo_text_extents_t extents; cairo_text_extents_t extents;
// std::cout << " x_unit: " << std::endl;
static const Glib::ustring val("Process 999 Resource 999"); static const Glib::ustring val("Process 999 Resource 999");
cairo_text_extents(ctx, val.c_str(), &extents); cairo_text_extents(ctx, val.c_str(), &extents);
_radius = extents.width/4.0; _radius = extents.width/4.0;
@ -762,13 +819,15 @@ HoltWidget::calc_drawing_size(cairo_t* ctx, size_t& width, size_t& height)
switch(_arrange_mode) switch(_arrange_mode)
{ {
case arrange_horizontal: case arrange_horizontal:
width = max * 4 * _radius; width = (size_t) (max * 4 * _radius);
height = 10 * _radius; height = (size_t) (10 * _radius);
break; break;
case arrange_vertical: case arrange_vertical:
width = 10 * _radius; width = (size_t) (10 * _radius);
height = max * 4 * _radius; height = (size_t) (max * 4 * _radius);
break; break;
case arrange_circular: case arrange_circular:
int tot = (_n_proc + _n_res); int tot = (_n_proc + _n_res);
double alpha = 0; double alpha = 0;
@ -782,15 +841,16 @@ HoltWidget::calc_drawing_size(cairo_t* ctx, size_t& width, size_t& height)
} }
if(diam<4 * _radius) if(diam<4 * _radius)
diam = 4 * _radius; diam = 4 * _radius;
width = height = diam + 4 * _radius; width = height = (size_t) (diam + 4 * _radius);
break; break;
} }
cout << "Holt widget AFTER calc_drawing_size width=" << width << " height=" << height << endl;
} }
/*
void void
HoltWidget::calc_widget_size(size_t& width, size_t& height) HoltWidget::calc_widget_size(size_t& width, size_t& height)
{ {
cout << "Holt widget BEFORE calc_widget_size width=" << width << " height=" << height << endl; cout << "Holt widget BEFORE calc_widget_size width=" << width << " height=" << height << endl;
width = height = 20; // default minimum size width = height = 20; // default minimum size
} }
*/

View File

@ -44,88 +44,329 @@ namespace sgpem
/** /**
* \brief Every point or vector is a Vec2. * \brief Every point or vector is a Vec2.
*
* This phisical vector class, Vec2 is realized trough * This phisical vector class, Vec2 is realized trough
* complex<double> because it's a full operative class with operators. * complex<double> because it's a full functional
* class with operators and easy vector operation as
* sum, multiply by scalar, rotation.
*/ */
typedef std::complex<double> Vec2; typedef std::complex<double> Vec2;
/**
* \brief Base class to draw holt graph nodes (schedulables and resources).
*
* This class is an "element" used by HoltWidget to draw holt graphs.
* An holt graph is built of circular nodes representing schedulables
* and square nodes representing resources connected as needed by
* arrows.
*
* This is a base abstract class for schedulables and resources.
* It has basic methods for positioning and sizing.
* The abstract method get_intersection() must be defined
* in derived classes to calculate the intersection of a request
* arrow with the node edge.
*
* Method draw() (abstract too) must provide effective object drawing.
*/
class HoltNode class HoltNode
{ {
public: public:
// HoltNode(double x=0.0, double y=0.0); /**
* \brief Unique constructor taking a Vec2 point as position.
*
* \param pt the predefined node position; default position at (0,0).
*/
HoltNode(Vec2 pt = Vec2(0.0, 0.0)); HoltNode(Vec2 pt = Vec2(0.0, 0.0));
/**
* \brief Class virtual destructor.
*/
virtual ~HoltNode(); virtual ~HoltNode();
/**
* \brief Effective output cairo drawing method.
*
* \param cr The cairo context to draw to.
*/
virtual void draw(cairo_t *cr) = 0; virtual void draw(cairo_t *cr) = 0;
// void set_position(double x, double y);
/**
* \brief Setter and getter method for position parameter.
*
* Position is in the center of object.
*
* \param pt The point to position the object.
* \return The previous position.
*/
Vec2 set_position(Vec2 pt); Vec2 set_position(Vec2 pt);
/**
* \brief Getter method for position parameter.
*
* Position is in the center of object.
*
* \return The object actual position.
*/
Vec2 get_position(); Vec2 get_position();
/**
* \brief Sets dimension of object.
*
* Radius represent the node dimension.
* By default these object are symmetrical and radius stay
* for "radius" in circular shaped nodes (schedulables),
* an half of the side for square objects (resources).
*
* \param radius The new desired value.
* \return The radius previous value.
*/
double set_radius(double radius); double set_radius(double radius);
/**
* \brief Gets dimension of object.
*
* Radius represent the node dimension.
* By default these object are symmetrical and radius stay
* for "radius" in circular shaped nodes (schedulables),
* an half of the side for square objects (resources).
*
* \return The actual radius value.
*/
double get_radius(); double get_radius();
/**
* \brief Computes point of intersection with edge.
*
* Giving a point outside the object edge this funcion returns
* the intersection of the segment connecting the shape center
* with the given point.
* Because is "shape dependent" it must be redefined in derived
* classes.
*
* \param pt The point to (ideally) connect to.
* \return The intersection of edge with segment from center to pt.
*/
virtual Vec2 get_intersection_to(Vec2 pt) = 0; virtual Vec2 get_intersection_to(Vec2 pt) = 0;
protected: protected:
/**
* \brief Object dimension.
*/
double _radius; double _radius;
// double _x, _y;
/**
* \brief Object position.
*/
Vec2 _pos; Vec2 _pos;
private:
}; };
/**
* \brief An holt node representing resources.
*
* A resource is drawn in form of square.
* This class derives from HoltNode and implements
* the abstract methods draw() and get_intersection().
*
* This class is used internally by HoltWidget, an HistoryObserver
* and is strictly related to backend class Resource (and derived).
* Inside there is a pointer to the rapresented resource and its key.
*
*/
class HoltResource : public HoltNode class HoltResource : public HoltNode
{ {
public: public:
// HoltResource(const Resource& resource, resource_key_t resource_key, double x=0.0, double y=0.0); /**
* \brief Unique constructor referring to resource and position in graph.
*
* \param resource The referred resource rapresented by this object.
* \param resource_key Unique numeric key associated with this resource.
* \param pt Position of object in graph.
*/
HoltResource(const Resource& resource, resource_key_t resource_key, Vec2 pt = Vec2(0.0, 0.0)); HoltResource(const Resource& resource, resource_key_t resource_key, Vec2 pt = Vec2(0.0, 0.0));
/**
* \brief Object's virtual destructor.
*/
virtual ~HoltResource(); virtual ~HoltResource();
/**
* \brief Object's drawing method.
*
* \param cr Cairo context to draw to.
*/
virtual void draw(cairo_t *cr); virtual void draw(cairo_t *cr);
/**
* \brief Computes point of intersection with edge.
*
* Giving a point outside the object (square) edge this funcion returns
* the intersection of the segment connecting the shape center
* with the given point.
*
* \param pt The point to (ideally) connect to.
* \return The intersection of edge with segment from center to pt.
*/
virtual Vec2 get_intersection_to(Vec2 pt); virtual Vec2 get_intersection_to(Vec2 pt);
protected:
private: private:
/**
* \brief Pointer to the related resource.
*/
const Resource* _resource; const Resource* _resource;
/**
* \brief Numeric key associated with this resource.
*/
resource_key_t _resource_key; resource_key_t _resource_key;
}; };
/**
* \brief An holt node representing schedulables (processes and threads).
*
* A schedulable is drawn in form of circle.
* This class derives from HoltNode and implements
* the abstract methods draw() and get_intersection().
*
* This class is used internally by HoltWidget, an HistoryObserver
* and is strictly related to backend class Schedulable (and derived).
* Inside there is a pointer to the rapresented schedulable.
*
*/
class HoltSchedulable : public HoltNode class HoltSchedulable : public HoltNode
{ {
public: public:
//HoltSchedulable(const Schedulable& schedulable, double x=0.0, double y=0.0); /**
* \brief Unique constructor referring to schedulable and position in graph.
*
* \param schedulable The referred schedulable rapresented by this object.
* \param pt Position of object in graph.
*/
HoltSchedulable(const Schedulable& schedulable, Vec2 pt = Vec2(0.0, 0.0)); HoltSchedulable(const Schedulable& schedulable, Vec2 pt = Vec2(0.0, 0.0));
/**
* \brief Object's virtual destructor.
*/
virtual ~HoltSchedulable(); virtual ~HoltSchedulable();
/**
* \brief Object's drawing method.
*
* \param cr Cairo context to draw to.
*/
virtual void draw(cairo_t *cr); virtual void draw(cairo_t *cr);
/**
* \brief Computes point of intersection with edge.
*
* Giving a point outside the object (circle) edge this funcion returns
* the intersection of the segment connecting the shape center
* with the given point.
*
* \param pt The point to (ideally) connect to.
* \return The intersection of edge with segment from center to pt.
*/
virtual Vec2 get_intersection_to(Vec2 pt); virtual Vec2 get_intersection_to(Vec2 pt);
protected:
private: private:
/**
* \brief Pointer to the related schedulable.
*/
const Schedulable* _schedulable; const Schedulable* _schedulable;
}; };
/**
* \brief Base class to draw holt graph arrows (requests/allocation).
*
* An arrow from a schedulable to a resource is called
* a request, counter is called an assignment.
*
* This is the class for both.
* It "connects" two objects: a schedulable and a resource and
* has a state to tell the direction of arrow.
* The state definition come from the class Request.
* Not all the values are drawn but only allocated (green),
* allocable (yellow), unallocable (red).
*/
class HoltRequest class HoltRequest
{ {
public: public:
/**
* \brief Object construcor.
*
* \param hp Reference to the HoltSchedulable.
* \param hr Reference to HoltResource.
* \param state Type of request.
*/
HoltRequest(HoltSchedulable& hp, HoltResource& hr, Request::state state); HoltRequest(HoltSchedulable& hp, HoltResource& hr, Request::state state);
/**
* \brief Object's virtual destructor.
*/
virtual ~HoltRequest(); virtual ~HoltRequest();
/**
* \brief Object's drawing method.
*
* \param cr Cairo context to draw to.
*/
virtual void draw(cairo_t *cr); virtual void draw(cairo_t *cr);
virtual void arrow(cairo_t *cr, Vec2 first, Vec2 second);
protected:
private: private:
/**
* \brief Methot for draw an arrow giving starting and ending points.
*
* \param cr Cairo context.
* \param first Starting point.
* \param first Ending point.
*/
virtual void arrow(cairo_t *cr, Vec2 first, Vec2 second);
/**
* \brief Pointer to the referring schedulable.
*/
HoltSchedulable* _hp; HoltSchedulable* _hp;
/**
* \brief Pointer to the referring resource.
*/
HoltResource* _hr; HoltResource* _hr;
/**
* \brief State of request.
*/
Request::state _state; Request::state _state;
}; };
/**
* \brief Widget representing an Holt graph.
*
* This class is based on Simulation and History observers
* to get updates during the simulation progress; it's
* derived from CairoWidget to get the buffering and scaling
* features of that class.
*
* The objects disposition can be done in three ways:
* - horizontal: resources top, schedulables bottom, from left to right
* - vertical: resources left, schedulables right, from top to bottom
* - circular: resources and processes along a cricle
* This disposition is called "arrange mode"
*
* \deprecated The class should implement only HistoryObserver
*
*/
class HoltWidget class HoltWidget
: public SimulationObserver, : public SimulationObserver,
public HistoryObserver, public HistoryObserver,
public CairoWidget public CairoWidget
{ {
public: public:
/**
* \brief Modes to dispose graph nodes.
*/
enum arrange_mode enum arrange_mode
{ {
arrange_horizontal = 1 << 0, arrange_horizontal = 1 << 0,
@ -133,46 +374,185 @@ namespace sgpem
arrange_circular = 1 << 2 arrange_circular = 1 << 2
}; };
typedef std::map<resource_key_t, HoltResource*> HoltResources; /**
typedef std::vector<HoltSchedulable*> HoltProcesses; * \brief Unique constructor.
typedef std::vector<HoltRequest*> HoltRequests; *
* Saves the passed argument in data member _simulation.
*
* \param simulation The observed Simulation
*/
HoltWidget(Simulation& simulation); HoltWidget(Simulation& simulation);
/**
* \brief Object's virtual destructor.
*/
virtual ~HoltWidget(); virtual ~HoltWidget();
/**
* \brief SimulationObserver's update method redefinition.
*
* Actually is a dummy method.
*
* \param changed_simulation the observed Simulation
*/
void update(const Simulation& changed_simulation); void update(const Simulation& changed_simulation);
void update(const History& changed_history);
void acquire();
double get_radius(); /**
* \brief HistoryObserver's update method redefinition.
*
* Updates the widget to reflects history current state.
*
* \param changed_history the observed History
*/
void update(const History& changed_history);
/**
* \brief Sets dimension of contained objects.
*
* \param radius The new desired value.
* \return The radius previous value.
*/
double set_radius(double radius); double set_radius(double radius);
/**
* \brief Gets dimension of contained objects.
*
* \return The actual radius value.
*/
double get_radius();
/**
* \brief Gets the current arrange mode.
*
* \return The actual arrange mode value.
*/
arrange_mode get_arrange_mode(); arrange_mode get_arrange_mode();
/**
* \brief Sets and gets arrange mode.
*
* \param mode The desired arrange mode.
* \return The previous mode value.
*/
arrange_mode set_arrange_mode(arrange_mode mode); arrange_mode set_arrange_mode(arrange_mode mode);
void arrange();
/**
* \brief Gets the _show_threads flag current status.
*
* \return true if threads visualization is enabled
*/
bool get_show_threads(); bool get_show_threads();
/**
* \brief Sets and gets the _show_threads flag status.
*
* If _show_threads is disabled processes will be drawn on widget.
* If _show_threads is enabled then threads will be shown.
*
* \param show the new desired status of threads visualization
* \return the previous status
*/
bool set_show_threads(bool show); bool set_show_threads(bool show);
protected: protected:
/**
* \brief Execute the widget painting when needed.
*
* \param ctx the cairo context to draw to
* \see CairoWidget for more.
*/
void draw_widget(cairo_t* ctx); void draw_widget(cairo_t* ctx);
virtual void calc_drawing_size(cairo_t* ctx, size_t& width, size_t& height);
virtual void calc_widget_size(size_t& width, size_t& height);
/**
* \brief calculated the needed drawing surface dimensions.
*
* \param ctx the cairo context to calc draw related dimensions
* \param width the return parameter for desired width
* \param height the return parameter for desired height
*/
virtual void calc_drawing_size(cairo_t* ctx, size_t& width, size_t& height);
// virtual void calc_widget_size(size_t& width, size_t& height);
/**
* \brief Gets the actual history status and make graph objects.
*/
void acquire();
/**
* \brief Reposition objects respecting actual arrange mode.
*/
void arrange();
private: private:
// int _x_unit; /**
//int _y_unit; * \brief Associative container to keep HoltResource elements.
*
* This is a map because each schedulables request must find
* the related object throug its key.
*/
typedef std::map<resource_key_t, HoltResource*> HoltResources;
/**
* \brief Container to keep HoltSchedulable elements.
*/
typedef std::vector<HoltSchedulable*> HoltProcesses;
/**
* \brief Container to keep HoltRequest elements.
*/
typedef std::vector<HoltRequest*> HoltRequests;
/**
* \brief Pointer to the observed simulation.
*/
Simulation* _simulation; Simulation* _simulation;
/**
* \brief Radius used to dimension all controlled objects.
*/
double _radius; double _radius;
/**
* \brief The HoltResource container.
*/
HoltResources _holt_resources; HoltResources _holt_resources;
/**
* \brief The HoltProcess container.
*/
HoltProcesses _holt_schedulables; HoltProcesses _holt_schedulables;
/**
* \brief The HoltRequest container.
*/
HoltRequests _holt_requests; HoltRequests _holt_requests;
/**
* \brief Number of schedulables (processes or threads) to draw.
*/
int _n_proc; int _n_proc;
/**
* \brief Number of resources to draw.
*/
int _n_res; int _n_res;
/**
* \brief The current "arrange mode".
*
* \see arrange_mode
*/
arrange_mode _arrange_mode; arrange_mode _arrange_mode;
/**
* \brief Flag to select processes or threads visualization.
*/
bool _show_threads; bool _show_threads;
}; };

View File

@ -61,11 +61,11 @@ namespace sgpem
{ {
public: public:
/** /**
* \brief default and unique constructor. * \brief Unique constructor.
* *
* Saves the passed argument in data member _simulation. * Saves the passed argument in data member _simulation.
* *
* \param simulation the observed Simulation * \param simulation The observed Simulation
*/ */
SimulationWidget(Simulation& simulation); SimulationWidget(Simulation& simulation);