//------------------------------------------------------------------------------
// emPriSchedAgent.h
//
// Copyright (C) 2006-2008,2010 Oliver Hamann.
//
// Homepage: http://eaglemode.sourceforge.net/
//
// This program is free software: you can redistribute it and/or modify it under
// the terms of the GNU General Public License version 3 as published by the
// Free Software Foundation.
//
// This program is distributed in the hope that it will be useful, but WITHOUT
// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License version 3 for
// more details.
//
// You should have received a copy of the GNU General Public License version 3
// along with this program. If not, see <http://www.gnu.org/licenses/>.
//------------------------------------------------------------------------------
#ifndef emPriSchedAgent_h
#define emPriSchedAgent_h
#ifndef emModel_h
#include <emCore/emModel.h>
#endif
//==============================================================================
//============================== emPriSchedAgent ===============================
//==============================================================================
class emPriSchedAgent : public emUncopyable {
public:
// Abstract base class for an agent in exclusively accessing an abstract
// thing via a simple priority scheduling algorithm. This has been
// invented for the use in emFileModel to make sure that only one file
// is loading at a time and that the files are loaded in a nice order.
// Other objects could take part of that scheduling.
emPriSchedAgent(emContext & context, const emString & resourceName,
double priority=0.0);
// Constructor.
// Arguments:
// context - Should be the root context.
// resourceName - Should be "cpu". A future agreement could be
// "network". ???: Maybe emFileModel should
// say "disk" instead of "cpu", or both...
// priority - The access priority (see SetAccessPriority).
virtual ~emPriSchedAgent();
// Destructor.
void SetAccessPriority(double priority);
// Set the access priority. Usually, this should be set from
// emPanel::GetUpdatePriority.
void RequestAccess();
// Start waiting for access.
bool IsWaitingForAccess() const;
// Whether this agent is waiting for access.
bool HasAccess() const;
// Whether this agent got access.
void ReleaseAccess();
// Release an obtained access or stop waiting for access.
protected:
virtual void GotAccess() = 0;
// Called when this agent got access.
private:
class PriSchedModel : public emModel {
public:
static emRef<PriSchedModel> Acquire(
emContext & context, const emString & name
);
protected:
PriSchedModel(emContext & context, const emString & name);
virtual bool Cycle();
private:
friend class emPriSchedAgent;
emPriSchedAgent * List;
emPriSchedAgent * Active;
};
friend class PriSchedModel;
emRef<PriSchedModel> PriSched;
double Priority;
emPriSchedAgent * * ThisPtrInList;
emPriSchedAgent * NextInList;
};
inline bool emPriSchedAgent::IsWaitingForAccess() const
{
return ThisPtrInList!=NULL;
}
inline bool emPriSchedAgent::HasAccess() const
{
return PriSched->Active==this;
}
#endif