/*
 * Coordinate starting and stopping of subsystems
 *
 * Copyright (C) 2007  Enrico Zini <enrico@debian.org>
 *
 * Interface configuration routines are adapted from
 * Laptop-net, Copyright 2002 Massachusetts Institute of Technology
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library 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
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307	USA
 */

#include "util/starter.h"
#include "util/output.h"

using namespace std;

namespace util {

static Starter* instance = 0;

Starter& Starter::get()
{
	if (!instance)
		instance = new Starter;
	return *instance;
}


Starter::Starter()
	: started(false)
{
}

void Starter::add(Startable* s, unsigned prio)
{
	debug("Added startable with priority %u\n", prio);
	members[prio].push_back(s);
	
	if (started)
	{
		debug("Starting right away regardless of priority\n");
		s->startableStart();
	}
}

void Starter::start()
{
	debug("Starting all %d startables\n", members.size());
	for (map< unsigned, list<Startable*> >::const_iterator i = members.begin();
			i != members.end(); ++i)
	{
		debug("Starting elements with priority %u\n", i->first);
		for (list<Startable*>::const_iterator j = i->second.begin();
				j != i->second.end(); ++j)
			(*j)->startableStart();
	}
	started = true;
}

void Starter::stop()
{
	for (map< unsigned, list<Startable*> >::const_reverse_iterator i = members.rbegin();
			i != members.rend(); ++i)
		for (list<Startable*>::const_reverse_iterator j = i->second.rbegin();
				j != i->second.rend(); ++j)
			(*j)->startableStop();
	started = false;
}

void Starter::reset()
{
	if (started)
		stop();
	members.clear();
}

}

// vim:set ts=4 sw=4:
