- Added the LOAD command to TextSimulation, and the classic question made to user on replacing an unsaved simulation

- Changed the way syntactically incorrect python policies are handled, we no more exit abruptly

git-svn-id: svn://svn.gna.org/svn/sgpemv2/trunk@829 3ecf2c5c-341e-0410-92b4-d18e462d057c
This commit is contained in:
elvez 2006-08-08 00:20:56 +00:00
parent d72ce96508
commit 0138387a7f
8 changed files with 189 additions and 14 deletions

View File

@ -167,6 +167,7 @@ src_backend_libbackend_la_SOURCES = \
src/backend/holt_graph.cc \ src/backend/holt_graph.cc \
src/backend/invalid_plugin_exception.cc \ src/backend/invalid_plugin_exception.cc \
src/backend/key_file.cc \ src/backend/key_file.cc \
src/backend/malformed_policy_exception.cc \
src/backend/module.cc \ src/backend/module.cc \
src/backend/null_policy_exception.cc \ src/backend/null_policy_exception.cc \
src/backend/plugin_manager.cc \ src/backend/plugin_manager.cc \
@ -210,6 +211,7 @@ pkginclude_HEADERS += \
src/backend/holt_graph.hh \ src/backend/holt_graph.hh \
src/backend/invalid_plugin_exception.hh \ src/backend/invalid_plugin_exception.hh \
src/backend/key_file.hh \ src/backend/key_file.hh \
src/backend/malformed_policy_exception.hh \
src/backend/module.hh \ src/backend/module.hh \
src/backend/null_policy_exception.hh \ src/backend/null_policy_exception.hh \
src/backend/policy_parameters.hh \ src/backend/policy_parameters.hh \

View File

@ -32,7 +32,7 @@ using namespace std;
// WARNING : this class needs extensive and above all // WARNING : this class needs extensive and above all
// *strong* exception checking / handling! // *strong* exception checking / handling!
PythonCPUPolicy::PythonCPUPolicy(const char* name) PythonCPUPolicy::PythonCPUPolicy(const char* name) throw(MalformedPolicyException)
: _upolicy_dict(NULL), _adapter(NULL), _name(name) : _upolicy_dict(NULL), _adapter(NULL), _name(name)
{ {
PyObject* pLoadmeStr = PyString_FromString(name); PyObject* pLoadmeStr = PyString_FromString(name);
@ -42,8 +42,7 @@ PythonCPUPolicy::PythonCPUPolicy(const char* name)
if( !pUserCPUPolicyModule ) if( !pUserCPUPolicyModule )
{ {
PyErr_Print(); // Error in import PyErr_Print(); // Error in import
// FIXME : don't exit abruptly, but fall back gracefully throw MalformedPolicyException("this message should be the stuff printed by PyErr_Print");
exit(-1);
} }
// Dictionary with defined ``symbols'' for .pyc file // Dictionary with defined ``symbols'' for .pyc file

View File

@ -30,12 +30,12 @@
#include "cpu_policy.hh" #include "cpu_policy.hh"
#include "user_interrupt_exception.hh" #include "user_interrupt_exception.hh"
#include "malformed_policy_exception.hh"
namespace sgpem namespace sgpem
{ {
class PythonCPUPolicy; class PythonCPUPolicy;
class PythonCPUPolicyManager; class PythonCPUPolicyManager;
class UserInterruptException;
/** \brief A specialization of abstract class Policy /** \brief A specialization of abstract class Policy
@ -45,7 +45,7 @@ namespace sgpem
class SG_DLLEXPORT PythonCPUPolicy : public CPUPolicy class SG_DLLEXPORT PythonCPUPolicy : public CPUPolicy
{ {
public: public:
PythonCPUPolicy(const char* name); PythonCPUPolicy(const char* name) throw(MalformedPolicyException);
virtual ~PythonCPUPolicy(); virtual ~PythonCPUPolicy();
/** /**

View File

@ -122,23 +122,30 @@ PythonCPUPolicyManager::collect_policies()
for(Glib::DirIterator file_it = dir.begin(); file_it != dir.end(); ++file_it) for(Glib::DirIterator file_it = dir.begin(); file_it != dir.end(); ++file_it)
{ {
cout << "\tChecking if " << *file_it << " is a Python script... "; cout << "\tChecking if " << *file_it << " is a valid Python script... ";
Glib::PatternSpec dot_py("*.py"); Glib::PatternSpec dot_py("*.py");
if(dot_py.match(*file_it)) if(dot_py.match(*file_it))
{ {
cout << "yes\n"; cout << "yes" << endl;
//strip extension //strip extension
std::string policy_name = (*file_it).substr(0, (*file_it).size() - 3); std::string policy_name = (*file_it).substr(0, (*file_it).size() - 3);
PythonCPUPolicy *pypolicy = new PythonCPUPolicy(policy_name.c_str()); try
{
PythonCPUPolicy *pypolicy = new PythonCPUPolicy(policy_name.c_str());
_policies.push_back(pypolicy); _policies.push_back(pypolicy);
}
catch(MalformedPolicyException e)
{
// TODO do something here someday
}
} }
else else
cout << "no\n"; cout << "no" << endl;
} }
} }
} }

View File

@ -0,0 +1,32 @@
// src/backend/malformed_policy_exception.cc - Copyright 2005, 2006, University
// of Padova, dept. of Pure and Applied
// Mathematics
//
// This file is part of SGPEMv2.
//
// This is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// SGPEMv2 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 for more details.
//
// You should have received a copy of the GNU General Public License
// along with SGPEMv2; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// Warning! This exception will be thrown across different libraries.
// It could be necessary to do dynamic type-checking when
// catching it (with typeinfo).
#include "malformed_policy_exception.hh"
using namespace sgpem;
MalformedPolicyException::MalformedPolicyException(const char* msg)
: std::runtime_error(msg)
{}
MalformedPolicyException::~MalformedPolicyException() throw() {}

View File

@ -0,0 +1,46 @@
// src/backend/malformed_policy_exception.hh - Copyright 2005, 2006, University
// of Padova, dept. of Pure and Applied
// Mathematics
//
// This file is part of SGPEMv2.
//
// This is free software; you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation; either version 2 of the License, or
// (at your option) any later version.
//
// SGPEMv2 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 for more details.
//
// You should have received a copy of the GNU General Public License
// along with SGPEMv2; if not, write to the Free Software
// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
// Warning! This exception will be thrown across different libraries.
// It could be necessary to do dynamic type-checking when
// catching it (with typeinfo).
#ifndef MALFORMED_POLICY_EXCEPTION
#define MALFORMED_POLICY_EXCEPTION 1
#include "config.h"
#include <stdexcept>
namespace sgpem
{
class MalformedPolicyException;
class SG_DLLEXPORT MalformedPolicyException : public std::runtime_error
{
public:
MalformedPolicyException(const char* msg = "");
virtual ~MalformedPolicyException() throw ();
private:
};
} //~ namespace sgpem
#endif

View File

@ -91,7 +91,8 @@ namespace sgpem
} }
TextSimulation::TextSimulation() TextSimulation::TextSimulation() :
_saved(true)
{ {
} }
@ -116,6 +117,35 @@ TextSimulation::check_arguments_num(const Tokens& arguments, unsigned int num)
return true; return true;
} }
bool
TextSimulation::unsaved_ask_confirm() const
{
if(!_saved)
{
p_stderr(_("WARNING: Simulation was not recently saved. "
"If you continue some changes to the simulation might be lost.\n"));
for(bool bad_arg = true; bad_arg;)
{
p_stdout(_("Continue? [y/n] "));
ustring buf = readline();
Tokens tokens = tokenize(buf);
if(tokens.size() == 1 && tokens[0].size() == 1)
{
if(tokens[0].lowercase() == _("n"))
return false;
else if(tokens[0].lowercase() == _("y"))
bad_arg = false;
}
}
}
return true;
}
template <typename Container> template <typename Container>
void void
TextSimulation::show(const Container& entities) TextSimulation::show(const Container& entities)
@ -459,7 +489,7 @@ TextSimulation::on_help(const Tokens& arguments)
if(command.size() == 0) if(command.size() == 0)
p_stdout(_("Avaiable commands:\nRUN\nSTOP\nPAUSE\n" p_stdout(_("Avaiable commands:\nRUN\nSTOP\nPAUSE\n"
"CONFIGURE-CPU-POLICY\nHELP\nGET\nSET\nSHOW\nADD\n" "CONFIGURE-CPU-POLICY\nHELP\nGET\nSET\nSHOW\nADD\n"
"REMOVE\nQUIT\n\n" "REMOVE\nSAVE\nLOAD\nQUIT\n\n"
"HELP followed by a command name shows help about it.\n" "HELP followed by a command name shows help about it.\n"
"ex. `HELP RUN` shows help about the command RUN\n")); "ex. `HELP RUN` shows help about the command RUN\n"));
else if(command == "RUN") else if(command == "RUN")
@ -520,6 +550,12 @@ TextSimulation::on_help(const Tokens& arguments)
"numeric ids follow the same logic of the previous commands\n" "numeric ids follow the same logic of the previous commands\n"
"`REMOVE subrequest <process_id> <thread_id> <request_id> <subrequest_id>` where the " "`REMOVE subrequest <process_id> <thread_id> <request_id> <subrequest_id>` where the "
"numeric ids follow the same logic of the previous commands\n")); "numeric ids follow the same logic of the previous commands\n"));
else if(command == "SAVE")
p_stderr(_("-- SAVE COMMAND --\nSaves the simulation.\n\n"
"Syntax: SAVE <filename>\n"));
else if(command == "LOAD")
p_stderr(_("-- LOAD COMMAND --\nLoads the simulation.\n\n"
"Syntax: LOAD <filename>\n"));
else if(command == "QUIT") else if(command == "QUIT")
p_stderr(_("-- QUIT COMMAND --\nGently closes the program.\n")); p_stderr(_("-- QUIT COMMAND --\nGently closes the program.\n"));
else else
@ -531,6 +567,9 @@ TextSimulation::on_quit(const Tokens& arguments)
{ {
check_arguments_num(arguments, 0); check_arguments_num(arguments, 0);
if(!unsaved_ask_confirm())
return;
p_stdout(_("\n\n*** Thank you for using SGPEM by Sirius Cybernetics Corporation ***\n\n")); p_stdout(_("\n\n*** Thank you for using SGPEM by Sirius Cybernetics Corporation ***\n\n"));
// Is this ok? Really? Oh, sure, if it we always did it in this way, it is surely a Good Thing! // Is this ok? Really? Oh, sure, if it we always did it in this way, it is surely a Good Thing!
@ -1303,11 +1342,53 @@ TextSimulation::on_save(const Tokens& arguments)
vector<Serializer*> serializers = vector<Serializer*> serializers =
SerializersGatekeeper::get_instance().get_registered(); SerializersGatekeeper::get_instance().get_registered();
// FIXME using the first serializer available, this
// will need to be changed when multiple serializers will
// be made available
Serializer& serializer = *serializers.at(0); Serializer& serializer = *serializers.at(0);
const History& history = Simulation::get_instance().get_history(); const History& history = Simulation::get_instance().get_history();
serializer.save_snapshot(filename, history); serializer.save_snapshot(filename, history);
_saved = true;
}
catch(out_of_range e)
{
p_stderr(_("ERROR: No registered serializer available\n"));
}
catch(SerializerError e)
{
string msg = _("ERROR: ");
p_stderr(msg + e.what() + "\n");
}
}
void
TextSimulation::on_load(const Tokens& arguments)
{
if(!check_arguments_num(arguments, 1))
return;
ustring filename = arguments[0];
if(!unsaved_ask_confirm())
return;
try
{
vector<Serializer*> serializers =
SerializersGatekeeper::get_instance().get_registered();
// FIXME using the first serializer available, this
// will need to be changed when multiple serializers will
// be made available
Serializer& serializer = *serializers.at(0);
History& history = Simulation::get_instance().get_history();
serializer.restore_snapshot(filename, history);
} }
catch(out_of_range e) catch(out_of_range e)
{ {
@ -1361,6 +1442,7 @@ TextSimulation::parse_command(TextSimulation& sim, const ustring& str)
command_handlers["ADD"] = &TextSimulation::on_add; command_handlers["ADD"] = &TextSimulation::on_add;
command_handlers["REMOVE"] = &TextSimulation::on_remove; command_handlers["REMOVE"] = &TextSimulation::on_remove;
command_handlers["SAVE"] = &TextSimulation::on_save; command_handlers["SAVE"] = &TextSimulation::on_save;
command_handlers["LOAD"] = &TextSimulation::on_load;
command_handlers["QUIT"] = &TextSimulation::on_quit; command_handlers["QUIT"] = &TextSimulation::on_quit;
Tokens arguments = tokenize(str); Tokens arguments = tokenize(str);
@ -1379,6 +1461,9 @@ TextSimulation::parse_command(TextSimulation& sim, const ustring& str)
arguments.erase(arguments.begin()); arguments.erase(arguments.begin());
(sim.*(command_handlers[key]))(arguments); (sim.*(command_handlers[key]))(arguments);
if(key == "ADD" || key == "REMOVE")
sim._saved = false;
} }
static ostream& static ostream&

View File

@ -74,6 +74,7 @@ namespace sgpem
virtual void update(const History& changed_history); virtual void update(const History& changed_history);
bool check_arguments_num(const Tokens& arguments, unsigned int num); bool check_arguments_num(const Tokens& arguments, unsigned int num);
bool unsaved_ask_confirm() const;
template <typename Container> template <typename Container>
void show(const Container& entities); void show(const Container& entities);
template <typename T> template <typename T>
@ -107,12 +108,15 @@ namespace sgpem
void on_remove_request(const Tokens& arguments); void on_remove_request(const Tokens& arguments);
void on_remove_subrequest(const Tokens& arguments); void on_remove_subrequest(const Tokens& arguments);
void on_save(const Tokens& arguments); void on_save(const Tokens& arguments);
void on_load(const Tokens& arguments);
// FIXME This is a temporary replacement for the // FIXME This is a temporary replacement for the
// to-be written I/O layer // to-be written I/O layer
static void p_stdout(const Glib::ustring& str); static void p_stdout(const Glib::ustring& str);
static void p_stderr(const Glib::ustring& str); static void p_stderr(const Glib::ustring& str);
static Glib::ustring readline(); static Glib::ustring readline();
bool _saved;
}; };
} }