// Copyright (C) 1999 Jean-Marc Valin
#include "Probe.h"
#include "net_types.h"
#include "Object.h"
#include <gnome.h>
#include "UserException.h"
using namespace std;
namespace FD {
DECLARE_NODE(Probe)
/*Node
*
* @name Probe
* @category Probe
* @description Helps debugging by allowing to "trace" programs
*
* @input_name INPUT
* @input_type any
* @input_description Any data
*
* @output_name OUTPUT
* @output_type any
* @output_description Pass through
*
* @parameter_name BREAK_AT
* @parameter_type int
* @parameter_description If set, the probe runs until (count = BREAK_AT)
*
* @parameter_name SHOW
* @parameter_type bool
* @parameter_value true
* @parameter_description Whether or not to show the the data by default
*
* @parameter_name SKIP
* @parameter_type int
* @parameter_description Count increment for each "Next"
*
* @parameter_name PROBE_NAME
* @parameter_type string
* @parameter_description Name (title) of the probe
*
END*/
static gboolean ignore_delete(GtkWidget *widget,
GdkEvent *event,
gpointer user_data)
{
return TRUE;
}
static void rename_button(GtkWidget *button, char *str)
{
gtk_label_set_text(GTK_LABEL(g_list_last(gtk_container_children(GTK_CONTAINER(GTK_BIN(button)->child)))->data), str);
}
static void next_click (GtkButton *button, Probe *pr)
{
gdk_threads_leave();
pr->next();
gdk_threads_enter();
}
static void cont_click (GtkButton *button, Probe *pr)
{
gdk_threads_leave();
pr->cont();
gdk_threads_enter();
}
static void break_click (GtkButton *button, Probe *pr)
{
pr->setBreak();
}
static void show_hide_click (GtkButton *button, Probe *pr)
{
pr->show_hide();
}
Probe::Probe(string nodeName, ParameterSet params)
: Node(nodeName, params)
, window1(NULL)
, exit_status(false)
{
outputID = addOutput("OUTPUT");
inputID = addInput("INPUT");
//sem_init(&sem, 0, 0);
pthread_cond_init(&cond, NULL);
pthread_mutex_init(&mutex, NULL);
nbClick = 0;
//pthread_mutex_lock(&mutex);
traceEnable=true;
displayEnable=true;
skip = 1;
breakAt=0;
if (parameters.exist("BREAK_AT"))
{
breakAt = dereference_cast<int> (parameters.get("BREAK_AT"));
if (breakAt == -1)
traceEnable=false;
}
if (parameters.exist("SHOW"))
{
displayEnable = dereference_cast<bool> (parameters.get("SHOW"));
}
if (parameters.exist("SKIP"))
{
skip = dereference_cast<int> (parameters.get("SKIP"));
}
if (parameters.exist("PROBE_NAME"))
probeName = object_cast<String> (parameters.get("PROBE_NAME"));
else
probeName = name;
//cerr<<"End Probe constructor"<<endl;
}
Probe::~Probe()
{
//cerr << "Probe destructor\n";
gdk_threads_enter();
if (window1)
gtk_widget_destroy (window1);
gdk_threads_leave();
//sem_destroy(&sem);
pthread_cond_destroy(&cond);
pthread_mutex_destroy(&mutex);
}
void Probe::initialize()
{
this->Node::initialize();
gdk_threads_enter();
try {
//GtkWidget *window1;
//GtkWidget *vbox2;
GtkWidget *handlebox2;
//GtkWidget *toolbar2;
GtkWidget *tmp_toolbar_icon;
//GtkWidget *button16;
//GtkWidget *button17;
GtkWidget *scrolledwindow2;
GtkWidget *canvas2;
window1 = gtk_window_new (GTK_WINDOW_TOPLEVEL);
gtk_object_set_data (GTK_OBJECT (window1), "window1", window1);
//string probeTitle = name + " (" + typeid(*this).name() + ")";
gtk_window_set_title (GTK_WINDOW (window1), probeName.c_str());
gtk_signal_connect (GTK_OBJECT (window1), "delete-event",
GTK_SIGNAL_FUNC (ignore_delete),
NULL);
vbox2 = gtk_vbox_new (FALSE, 0);
gtk_widget_ref (vbox2);
gtk_object_set_data_full (GTK_OBJECT (window1), "vbox2", vbox2,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (vbox2);
gtk_container_add (GTK_CONTAINER (window1), vbox2);
handlebox2 = gtk_handle_box_new ();
gtk_widget_ref (handlebox2);
gtk_object_set_data_full (GTK_OBJECT (window1), "handlebox2", handlebox2,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (handlebox2);
gtk_box_pack_start (GTK_BOX (vbox2), handlebox2, FALSE, FALSE, 0);
gtk_handle_box_set_snap_edge (GTK_HANDLE_BOX (handlebox2), GTK_POS_LEFT);
toolbar2 = gtk_toolbar_new();
gtk_widget_ref (toolbar2);
gtk_object_set_data_full (GTK_OBJECT (window1), "toolbar2", toolbar2,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (toolbar2);
gtk_container_add (GTK_CONTAINER (handlebox2), toolbar2);
/*tmp_toolbar_icon = gnome_stock_pixmap_widget (window1, GNOME_STOCK_PIXMAP_REDO);
button16 = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar2),
GTK_TOOLBAR_CHILD_BUTTON,
NULL,
_("Next"),
NULL, NULL,
tmp_toolbar_icon, NULL, NULL);*/
button16 = gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar2),
"gtk-go-forward",
"gtk-go-forward",
NULL, NULL, NULL, -1);
gtk_widget_ref (button16);
gtk_object_set_data_full (GTK_OBJECT (window1), "button16", button16,
(GtkDestroyNotify) gtk_widget_unref);
gtk_button_set_relief(GTK_BUTTON(button16), GTK_RELIEF_NONE);
gtk_widget_show (button16);
gtk_signal_connect (GTK_OBJECT (button16), "clicked",
GTK_SIGNAL_FUNC (next_click),
this);
gtk_widget_set_sensitive(button16, false);
//cerr << "registered " << this << endl;
/*tmp_toolbar_icon = gnome_stock_pixmap_widget (window1, GNOME_STOCK_PIXMAP_STOP);
button17 = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar2),
GTK_TOOLBAR_CHILD_BUTTON,
NULL,
_("Break"),
NULL, NULL,
tmp_toolbar_icon, NULL, NULL);
*/
button17 = gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar2),
"gtk-stop",
"gtk-stop",
NULL, NULL, NULL, -1);
gtk_widget_ref (button17);
gtk_object_set_data_full (GTK_OBJECT (window1), "button17", button17,
(GtkDestroyNotify) gtk_widget_unref);
gtk_button_set_relief(GTK_BUTTON(button17), GTK_RELIEF_NONE);
gtk_widget_show (button17);
if (traceEnable)
gtk_widget_set_sensitive(button17, false);
gtk_signal_connect (GTK_OBJECT (button17), "clicked",
GTK_SIGNAL_FUNC (break_click),
this);
/*tmp_toolbar_icon = gnome_stock_pixmap_widget (window1, GNOME_STOCK_PIXMAP_EXEC);
button18 = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar2),
GTK_TOOLBAR_CHILD_BUTTON,
NULL,
_("Continue"),
NULL, NULL,
tmp_toolbar_icon, NULL, NULL);
*/
button18 = gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar2),
"gtk-execute",
"gtk-execute",
NULL, NULL, NULL, -1);
gtk_widget_ref (button18);
gtk_object_set_data_full (GTK_OBJECT (window1), "button18", button18,
(GtkDestroyNotify) gtk_widget_unref);
gtk_button_set_relief(GTK_BUTTON(button18), GTK_RELIEF_NONE);
gtk_widget_show (button18);
gtk_signal_connect (GTK_OBJECT (button18), "clicked",
GTK_SIGNAL_FUNC (cont_click),
this);
if (!traceEnable)
gtk_widget_set_sensitive(button18, false);
/*
const char *hide_name;
if (displayEnable)
hide_name=_("Hide");
else
hide_name=_("Show");
tmp_toolbar_icon = gnome_stock_pixmap_widget (window1, GNOME_STOCK_PIXMAP_CLOSE);
button19 = gtk_toolbar_append_element (GTK_TOOLBAR (toolbar2),
GTK_TOOLBAR_CHILD_BUTTON,
NULL,
hide_name,
NULL, NULL,
tmp_toolbar_icon, NULL, NULL);
*/
button19 = gtk_toolbar_insert_stock (GTK_TOOLBAR (toolbar2),
"gtk-close",
"gtk-close",
NULL, NULL, NULL, -1);
if(displayEnable)
{
rename_button(button19, "Hide");
}
else
{
rename_button(button19, "Show");
}
gtk_widget_ref (button19);
gtk_object_set_data_full (GTK_OBJECT (window1), "button19", button19,
(GtkDestroyNotify) gtk_widget_unref);
gtk_button_set_relief(GTK_BUTTON(button19), GTK_RELIEF_NONE);
gtk_widget_show (button19);
gtk_signal_connect (GTK_OBJECT (button19), "clicked",
GTK_SIGNAL_FUNC (show_hide_click),
this);
entry1 = gtk_entry_new_with_max_length (10);
gtk_entry_set_editable(GTK_ENTRY(entry1),false);
gtk_widget_ref (entry1);
gtk_object_set_data_full (GTK_OBJECT (window1), "entry1", entry1,
(GtkDestroyNotify) gtk_widget_unref);
gtk_widget_show (entry1);
gtk_toolbar_append_widget (GTK_TOOLBAR (toolbar2), entry1, NULL, NULL);
gtk_widget_show(window1);
} catch (BaseException *e)
{
gdk_threads_leave();
throw e->add(new NodeException(this, "Exception caught in Probe::specifigInitialize", __FILE__, __LINE__));
}
gdk_threads_leave();
}
void Probe::reset()
{
this->Node::reset();
}
void Probe::stop()
{
//cerr << "Setting exit_status" << endl;
exit_status = true;
next();
}
void Probe::next()
{
//cerr << "In Probe::next\n";
//sem_post(&sem);
pthread_mutex_lock(&mutex);
nbClick++;
pthread_cond_signal(&cond);
pthread_mutex_unlock(&mutex);
}
void Probe::cont()
{
traceEnable = false;
gdk_threads_enter();
gtk_widget_set_sensitive(button18, false);
gtk_widget_set_sensitive(button17, true);
gdk_threads_leave();
next();
}
void Probe::setBreak()
{
traceEnable = true;
//gdk_threads_enter();
gtk_widget_set_sensitive(button17, false);
gtk_widget_set_sensitive(button18, true);
//gtk_label_set_text(GTK_LABEL(GTK_BIN(button18)->child), "tata");
//gtk_label_set_text(GTK_LABEL(g_list_last(gtk_container_children(GTK_CONTAINER(GTK_BIN(button18)->child)))->data), "tata");
//gdk_threads_leave();
}
void Probe::show_hide()
{
displayEnable = !displayEnable;
if(displayEnable)
{
rename_button(button19, "Hide");
}
else
{
rename_button(button19, "Show");
}
}
void Probe::display()
{
}
void Probe::trace()
{
gdk_threads_enter();
gtk_widget_set_sensitive(button16, true);
//gtk_widget_set_sensitive(button17, false);
gtk_widget_set_sensitive(button18, true);
gdk_threads_leave();
if (exit_status)
throw new UserException;
//sem_wait(&sem);
pthread_mutex_lock(&mutex);
if (nbClick)
{
nbClick--;
pthread_mutex_unlock(&mutex);
} else {
pthread_cond_wait(&cond, &mutex);
nbClick--;
pthread_mutex_unlock(&mutex);
}
if (exit_status)
throw new UserException;
gdk_threads_enter();
//gtk_widget_set_sensitive(button17, true);
gtk_widget_set_sensitive(button16, false);
gtk_widget_set_sensitive(button18, false);
gdk_threads_leave();
}
ObjectRef Probe::getOutput(int output_id, int count)
{
//cerr << "before\n";
if (output_id==outputID)
{
NodeInput input = inputs[inputID];
inputValue = input.node->getOutput(input.outputID,count);
if (count % skip == 0)
{
char tmp[16];
sprintf (tmp,"%d",count);
gdk_threads_enter();
gtk_entry_set_text(GTK_ENTRY(entry1),tmp);
gdk_threads_leave();
}
if (displayEnable && (count % skip == 0))
display();
if (traceEnable && (count % skip == 0) && count >= breakAt)
trace();
//cerr << "after\n";
return inputValue;
}
else
throw new NodeException (this, "Probe: Unknown output id", __FILE__, __LINE__);
}
}//namespace FD
syntax highlighted by Code2HTML, v. 0.9.1