/**********************************************************************
This file is part of Crack dot Com's free source code release of
Golgotha.
for
information about compiling & licensing issues visit this URL
If that doesn't help, contact Jonathan Clark at
golgotha_source@usa.net (Subject should have "GOLG" in it)
***********************************************************************/
#include "window/window.hh"
#include "window/style.hh"
#include "window/win_evt.hh"
#include "device/event.hh"
#include "time/timedev.hh"
#include "time/profile.hh"
#include "time/profile_stack.hh"
//2345678*012345678*012345678*012345678*012345678*012345678*012345678*012345678*012345678*012345678*
i4_profile_class pf_profile_draw("profile window refresh");
// sort in descending order
static int profile_compare(const void *a, const void *b)
{
i4_profile_class *ap=*((i4_profile_class **)a);
i4_profile_class *bp=*((i4_profile_class **)b);
if (ap->total_timetotal_time)
return 1;
else if (ap->total_time>bp->total_time)
return -1;
else return 0;
}
enum { CLOSE_WIN, POLL };
class i4_prof_win_class : public i4_parent_window_class
{
i4_bool update_stats;
i4_graphical_style_class *style;
i4_time_device_class::id poll_id;
i4_event_reaction_class *on_close;
w64 last_clock;
public:
i4_prof_win_class(w16 w, w16 h, i4_graphical_style_class *style,
i4_event_reaction_class *on_close)
: i4_parent_window_class(w,h),
style(style),
on_close(on_close)
{
i4_object_message_event_class poll(this, POLL);
poll_id=i4_time_dev.request_event(this, &poll, 5000); // update once every 5 secs
last_clock=i4_get_system_clock();
// count how many profile classes are in memory
for (i4_profile_class *p=i4_profile_class::list; p; p=p->next)
p->total_time=0;
i4_profile_on=1;
}
void parent_draw(i4_draw_context_class &context)
{
int t=0,i=0;
double total_time_measured=0.0;
i4_profile_class *p=i4_profile_class::list;
// count how many profile classes are in memory
for (; p; p=p->next)
{
total_time_measured+=(double)(sw64)p->total_time;
t++;
}
pf_profile_draw.start();
local_image->clear(0, context);
if (update_stats)
{
// put them all in a list and sort them by clocks
i4_profile_class **plist;
plist=(i4_profile_class **)i4_malloc(sizeof(i4_profile_class *)*t,"pl");
for (p=i4_profile_class::list; p; p=p->next)
{
plist[i]=p;
i++;
}
qsort(plist, t, sizeof(i4_profile_class *), profile_compare);
char buf[200];
int y=0, h=height();
int x=50;
w64 current_clock = i4_get_system_clock();
double oo_total = 1.0/(double)((sw64)current_clock - (sw64)last_clock);
last_clock=i4_get_system_clock();
i4_font_class *fnt=style->font_hint->small_font;
fnt->set_color(0x0000ff);
sprintf(buf,"%2.2f Total", ((double)(sw64)total_time_measured * oo_total) * 100.0);
fnt->put_string(local_image, x+1, y, buf, context);
y+=fnt->height(buf);
fnt->set_color(0xffff00);
for (i=0; itotal_time * oo_total;
sprintf(buf, "%2.2f %s", percent * 100.0, plist[i]->name);
int th=fnt->height(buf);
local_image->bar(x-(sw32)(percent * x), y, x, y+th-1, 0xffff, context);
plist[i]->total_time=0;
fnt->put_string(local_image, x+1, y, buf, context);
y+=th;
if (y>h)
break;
}
i4_free(plist);
update_stats=i4_F;
}
else last_clock=i4_get_system_clock();
pf_profile_draw.stop();
}
void receive_event(i4_event *ev);
~i4_prof_win_class()
{
if (on_close)
delete on_close;
i4_time_dev.cancel_event(poll_id);
i4_profile_stack_top=0;
i4_profile_on=0;
}
char *name() { return "profile window"; }
};
i4_parent_window_class *i4_prof_win=0;
void i4_prof_win_class::receive_event(i4_event *ev)
{
CAST_PTR(oev, i4_object_message_event_class, ev);
if (ev->type()==i4_event::OBJECT_MESSAGE && oev->object==this)
{
if (oev->sub_type==CLOSE_WIN) // close window
{
i4_prof_win=0;
i4_kernel.send(on_close);
}
else if (oev->sub_type==1) // update statics
{
update_stats=i4_T;
request_redraw();
i4_object_message_event_class poll(this, POLL);
poll_id=i4_time_dev.request_event(this, &poll, 5000); // update once every 5 secs
}
}
else i4_parent_window_class::receive_event(ev);
}
void i4_profile_watch(i4_graphical_style_class *style,
i4_parent_window_class *parent,
sw32 &win_x, sw32 &win_y,
w32 w, w32 h,
int open_type, // 0==close, 1==open, 2==toggle window
i4_event_reaction_class *on_close)
{
if (i4_prof_win && (open_type==0 || open_type==2))
{
win_x=i4_prof_win->get_parent()->x();
win_y=i4_prof_win->get_parent()->y();
style->close_mp_window(i4_prof_win);
i4_prof_win=0;
}
else if (!i4_prof_win && (open_type==1 || open_type==2))
{
i4_prof_win_class *p=new i4_prof_win_class(w,h, style, on_close);
i4_event_reaction_class *re;
re=new i4_event_reaction_class(p, new i4_object_message_event_class(p,CLOSE_WIN,i4_event::NOW));
i4_prof_win=style->create_mp_window(win_x, win_y, w,h,
i4gets("prof_win_title",i4_F), re);
i4_prof_win->add_child(0,0,p);
}
}