// generated 2005/4/21 19:44:30 EDT by scott@Corwin.(none)
// using glademm V2.6.0
//
// newer (non customized) versions of this file go to main_window.cc_new
// This file is for your program, I won't touch it again!
#include <sys/types.h>
#include <sys/stat.h>
#include <glibmm/thread.h>
#include <gtkmm.h>
#include <gtkmm/main.h>
#include <iomanip>
#include "config.h"
#include "main_window.hh"
//------------------------------------------------------------------------------
// THREADING
thread_acovea::thread_acovea(main_window * window)
: world(NULL),
thread(NULL),
settings(window->get_settings()),
ui(window),
gen_no(0),
pop_no(0),
test_no(0),
drop_dead(false),
text("Nothing to see here."),
gen_no_ptr(&gen_no),
pop_no_ptr(&pop_no),
test_no_ptr(&test_no),
text_ptr(&text)
{
signal_run_complete.connect(sigc::mem_fun(*window, &main_window::catch_run_complete));
signal_progress.connect(sigc::bind<size_t *,size_t *,size_t *>(sigc::mem_fun(*window, &main_window::catch_fitness_test_end),gen_no_ptr,pop_no_ptr,test_no_ptr));
signal_report.connect(sigc::bind<string *>(sigc::mem_fun(*window, &main_window::catch_report),text_ptr));
}
thread_acovea::~thread_acovea()
{
delete world;
}
void thread_acovea::launch()
{
thread = Glib::Thread::create(sigc::mem_fun(*this, &thread_acovea::thread_function),true);
}
void thread_acovea::join()
{
thread->join();
}
void thread_acovea::thread_function()
{
// define a application from config file
application target(settings.config);
// initialize random number generator if required
if (settings.use_seed)
libevocosm::globals::set_random_seed(settings.seed);
// create a world
world = new acovea_world(*this,
settings.benchmark,
settings.mode,
target,
settings.num_pops,
settings.pop_size,
settings.srate,
settings.irate,
settings.mrate,
settings.crate,
settings.scaling,
settings.num_runs);
// start running
world->run();
}
void thread_acovea::terminate()
{
world->terminate();
drop_dead = true;
}
// these functions listen for acovea events
void thread_acovea::ping_generation_begin(size_t a_generation_number)
{
pop_no = 0;
signal_progress();
}
void thread_acovea::ping_generation_end(size_t a_generation_number)
{
gen_no = a_generation_number;
signal_progress();
}
void thread_acovea::ping_population_begin(size_t a_population_number)
{
test_no = 0;
signal_progress();
}
void thread_acovea::ping_population_end(size_t a_population_number)
{
pop_no = a_population_number;
signal_progress();
}
void thread_acovea::ping_fitness_test_begin(size_t a_organism_number)
{
// nada
}
void thread_acovea::ping_fitness_test_end(size_t a_organism_number)
{
test_no = a_organism_number;
signal_progress();
}
void thread_acovea::report(const string & a_text)
{
// text = a_text;
// signal_report();
}
void thread_acovea::report_error(const string & a_text)
{
// In a future version, I'll have an option error display
// text = a_text;
// signal_report();
}
void thread_acovea::run_complete()
{
signal_run_complete();
}
void thread_acovea::yield()
{
if (drop_dead)
{
signal_run_complete();
throw Glib::Thread::Exit();
}
else
Glib::usleep(50000);
}
void thread_acovea::report_config(const string & a_text)
{
text = a_text;
g_print(text.c_str());
signal_report();
}
void thread_acovea::report_generation(size_t a_gen_no, double a_avg_fitness)
{
ostringstream output;
output << "generation " << a_gen_no
<< " complete, average fitness: " << a_avg_fitness
<< endl;
text = output.str();
signal_report();
}
void thread_acovea::report_final(vector<test_result> & a_results, vector<option_zscore> & a_zscores)
{
ostringstream output;
static const double THRESHOLD = 1.5;
// format time
char time_text[256];
time_t now = time(NULL);
strftime(time_text,256,"%Y %b %d %X",localtime(&now));
output << "\nAcovea completed its analysis at " << time_text << endl;
// report optimistic options
bool flag = false;
output << "\nOptimistic options:\n\n";
for (int n = 0; n < a_zscores.size(); ++n)
{
if (a_zscores[n].m_zscore >= THRESHOLD)
{
flag = true;
output << right << setw(40) << a_zscores[n].m_name
<< " (" << a_zscores[n].m_zscore << ")\n";
}
}
if (!flag)
output << " none" << endl;
flag = false;
output << "\nPessimistic options:\n\n";
for (int n = 0; n < a_zscores.size(); ++n)
{
if (a_zscores[n].m_zscore <= -THRESHOLD)
{
flag = true;
output << right << setw(40) << a_zscores[n].m_name
<< " (" << a_zscores[n].m_zscore << ")\n";
}
}
if (!flag)
output << " none" << endl;
// graph test results
double big_fit = numeric_limits<double>::min();
for (int n = 0; n < a_results.size(); ++n)
{
output << "\n" << a_results[n].m_description << ":\n"
<< a_results[n].m_detail
<< endl;
if (a_results[n].m_fitness > big_fit)
big_fit = a_results[n].m_fitness;
}
output << "\n\nA relative graph of fitnesses:\n";
for (int n = 0; n < a_results.size(); ++n)
{
output << "\n" << right << setw(30) << a_results[n].m_description << ": ";
int count = int(a_results[n].m_fitness / big_fit * 50.1);
for (int i = 0; i < count; ++i)
output << "*";
output << right << setw(55 - count) << " ("
<< a_results[n].m_fitness
<< ")";
}
output << "\n\nAcovea is done.\n" << endl;
text = output.str();
signal_report();
}
//------------------------------------------------------------------------------
// MAIN WINDOW CLASS
static bool save_settings(const string & name, const settings_t & settings)
{
bool result = false;
FILE * settings_file = fopen(name.c_str(),"w+b");
if (settings_file != NULL)
{
if (1 == fwrite(&settings,sizeof(settings_t),1,settings_file))
result = true;
fclose(settings_file);
}
return result;
}
static bool load_settings(const string & name, settings_t & settings)
{
bool result = false;
FILE * settings_file = fopen(name.c_str(),"rb");
if (settings_file != NULL)
{
if (1 == fread(&settings,sizeof(settings_t),1,settings_file))
result = true;
fclose(settings_file);
}
return result;
}
static string get_default_settings_name()
{
static char setting_name[1024] = { 0 };
if (setting_name[0] == 0)
{
// find home directory
char * home_dir = getenv("HOME");
// create a directory
snprintf(setting_name,1024,"%s/.acovea-gtk",home_dir);
mkdir(setting_name,0777);
// now generate the file name
snprintf(setting_name,1024,"%s/.acovea-gtk/settings",home_dir);
}
return string(setting_name);
}
static bool create_default_settings(settings_t & settings)
{
settings.num_pops = 5;
settings.pop_size = 40;
settings.num_runs = 20;
settings.srate = 0.10;
settings.irate = 0.05;
settings.mrate = 0.01;
settings.crate = 1.00;
strcpy(settings.benchmark,"You need to pick one");
strcpy(settings.config,"You need to pick one");
settings.scaling = true;
settings.use_seed = false;
settings.seed = 1701;
settings.mode = OPTIMIZE_SPEED;
return save_settings(get_default_settings_name(),settings);
}
const char * main_window::MSG_RUNNING("<span foreground=\"darkgreen\" weight = \"bold\">Running</span>");
const char * main_window::MSG_FINISHED("<span foreground=\"blue\" weight = \"bold\">Finished</span>");
const char * main_window::MSG_TERMINATED("<span foreground=\"red\" weight = \"bold\">Run Terminated</span>");
main_window::main_window()
: main_window_glade()
{
// set our icon
set_icon_from_file(PIXMAPS_DIR "acovea_icon_032.png");
// set scrollbar colors
/*
Gdk::Color blue1, blue2, blue3, gray;
blue1.set_rgb_p(0.0,0.0,0.8);
blue2.set_rgb_p(0.2,0.0,0.6);
blue3.set_rgb_p(0.4,0.0,0.4);
gray.set_rgb_p(0.95,0.95,0.95);
Glib::RefPtr<Gdk::Colormap> colormap = get_default_colormap();
colormap->alloc_color(blue1);
colormap->alloc_color(blue2);
colormap->alloc_color(blue3);
colormap->alloc_color(gray);
main_generation_progressbar->modify_bg(Gtk::STATE_NORMAL,gray);
main_population_progressbar->modify_bg(Gtk::STATE_NORMAL,gray);
main_testing_progressbar->modify_bg(Gtk::STATE_NORMAL,gray);
main_generation_progressbar->modify_fg(Gtk::STATE_NORMAL,blue1);
main_population_progressbar->modify_fg(Gtk::STATE_NORMAL,blue2);
main_testing_progressbar->modify_fg(Gtk::STATE_NORMAL,blue3);
*/
// set label for markup
main_whatsup->set_use_markup(true);
// set a better font
Pango::FontDescription fd;
fd.set_size(10000);
fd.set_stretch(Pango::STRETCH_NORMAL);
fd.set_style(Pango::STYLE_NORMAL);
fd.set_variant(Pango::VARIANT_NORMAL);
fd.set_weight(Pango::WEIGHT_NORMAL);
fd.set_family("monospace"); // Vera Sans Mono, Monospace, Courier");
main_window_output->modify_font(fd);
// we haven't created these windows yet
settings_dialog = NULL;
about_dialog = NULL;
if (!load_settings(get_default_settings_name(),settings))
{
if (!create_default_settings(settings))
{
Gtk::MessageDialog dialog(*this, "Unable to open or create default settings file.");
dialog.run();
}
}
// set inital ui state
set_ui_running(false);
}
main_window::~main_window()
{
if (settings_dialog != NULL)
delete settings_dialog;
if (about_dialog != NULL)
delete about_dialog;
}
void main_window::on_menu_quit_activate()
{
Gtk::Main::quit();
}
void main_window::on_menu_set_run_options_activate()
{
if (settings_dialog != NULL)
delete settings_dialog;
settings_window * dialog = new settings_window(settings);
}
void main_window::on_menu_save_options_default_activate()
{
if (!save_settings(get_default_settings_name(),settings))
{
if (!create_default_settings(settings))
{
Gtk::MessageDialog dialog(*this, "Unable to open or create default settings file.");
dialog.run();
}
}
}
void main_window::on_menu_load_default_options_activate()
{
if (!load_settings(get_default_settings_name(),settings))
{
if (!create_default_settings(settings))
{
Gtk::MessageDialog dialog(*this, "Unable to open or create default settings file.");
dialog.run();
}
}
}
void main_window::on_menu_save_options_activate()
{
Gtk::FileChooserDialog dialog("Save Settings To...", Gtk::FILE_CHOOSER_ACTION_SAVE);
dialog.set_transient_for(*this);
dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
dialog.add_button("Save", Gtk::RESPONSE_OK);
if (Gtk::RESPONSE_OK == dialog.run())
save_settings(dialog.get_filename(),settings);
}
void main_window::on_load_options_activate()
{
Gtk::FileChooserDialog dialog("Load Settings From...", Gtk::FILE_CHOOSER_ACTION_OPEN);
dialog.set_transient_for(*this);
dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
dialog.add_button("Load", Gtk::RESPONSE_OK);
if (Gtk::RESPONSE_OK == dialog.run())
load_settings(dialog.get_filename(),settings);
}
//------------------------------------------------------------------------------
// MAIN WINDOW THREADING
void main_window::catch_fitness_test_end(size_t * gen_no, size_t * pop_no, size_t * test_no)
{
double percent = double(*gen_no) / double(settings.num_runs);
main_generation_progressbar->set_fraction(percent);
percent = double(*pop_no) / double(settings.num_pops);
main_population_progressbar->set_fraction(percent);
percent = double(*test_no) / double(settings.pop_size);
main_testing_progressbar->set_fraction(percent);
/*
Glib::RefPtr<Gtk::TextBuffer> buffer = main_window_output->get_buffer();
Gtk::TextIter end = buffer->end();
main_window_output->scroll_to(end);
*/
}
void main_window::catch_run_complete()
{
set_ui_running(false);
main_whatsup->set_label(end_message);
main_generation_progressbar->set_fraction(1.0);
main_population_progressbar->set_fraction(1.0);
main_testing_progressbar->set_fraction(1.0);
}
void main_window::catch_report(string * text)
{
Glib::RefPtr<Gtk::TextBuffer> buffer = main_window_output->get_buffer();
Gtk::TextIter end = buffer->end();
buffer->insert(buffer->end(),text->c_str());
}
void main_window::set_ui_running(bool running)
{
// when running, these should be off
menu_set_run_options->set_sensitive(!running);
menu_save_options_default->set_sensitive(!running);
menu_load_default_options->set_sensitive(!running);
menu_save_options->set_sensitive(!running);
save_load_options->set_sensitive(!running);
menu_quit->set_sensitive(!running);
menu_run->set_sensitive(!running);
menu_save_output->set_sensitive(!running);
menu_about->set_sensitive(!running);
toolbar_settings_button->set_sensitive(!running);
toolbar_run_button->set_sensitive(!running);
// when running, these should be on
toolbar_stop_button->set_sensitive(running);
menu_stop->set_sensitive(running);
}
void main_window::start()
{
// clear the display
Glib::RefPtr<Gtk::TextBuffer> buffer = main_window_output->get_buffer();
buffer->erase(buffer->begin(),buffer->end());
// set the termination message
end_message = MSG_FINISHED;
main_whatsup->set_label(MSG_RUNNING);
// set ui state
set_ui_running(true);
// reset progress bars
main_generation_progressbar->set_fraction(0.0);
main_population_progressbar->set_fraction(0.0);
main_testing_progressbar->set_fraction(0.0);
// create thread
thread = new thread_acovea(this);
// launch the thread
thread->launch();
}
void main_window::stop()
{
thread->terminate();
end_message = MSG_TERMINATED;
}
void main_window::on_menu_run_activate()
{
start();
}
void main_window::on_menu_stop_activate()
{
stop();
}
void main_window::on_menu_save_output_activate()
{
Gtk::FileChooserDialog dialog("Save Output To...", Gtk::FILE_CHOOSER_ACTION_SAVE);
dialog.set_transient_for(*this);
dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL);
dialog.add_button("Save", Gtk::RESPONSE_OK);
if (Gtk::RESPONSE_OK == dialog.run())
{
FILE * f = fopen(dialog.get_filename().c_str(),"w+");
Glib::RefPtr<Gtk::TextBuffer> buffer = main_window_output->get_buffer();
fputs(buffer->get_text().c_str(),f);
fclose(f);
}
}
void main_window::on_about1_activate()
{
if (about_dialog != NULL)
delete about_dialog;
about_box * dialog = new class about_box();
}
void main_window::on_toolbar_settings_button_clicked()
{
if (settings_dialog != NULL)
delete settings_dialog;
settings_window * dialog = new settings_window(settings);
}
void main_window::on_toolbar_run_button_clicked()
{
start();
}
void main_window::on_toolbar_stop_button_clicked()
{
stop();
}
syntax highlighted by Code2HTML, v. 0.9.1