Fix compilation errors.
[Ale.git] / ui / ui.h
blob4dfa1ca21c5cbf00e246e72fbeeb39ca4c3cd19d
1 // Copyright 2004 David Hilvert <dhilvert@auricle.dyndns.org>,
2 // <dhilvert@ugcs.caltech.edu>
4 /* This file is part of the Anti-Lamenessing Engine.
6 The Anti-Lamenessing Engine is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 The Anti-Lamenessing Engine is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with the Anti-Lamenessing Engine; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
21 #ifndef __ui_h__
22 #define __ui_h__
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <stdarg.h>
28 #include <assert.h>
29 #include "../ale_pos.h"
30 #include "../config.h"
31 #if HAVE_TIME_H
32 #include <time.h>
33 #endif
34 #if HAVE_SYS_TIME_H
35 #include <sys/time.h>
36 #endif
38 #include <map>
41 * Time structures.
44 namespace d2 {
45 struct trans_multi;
46 typedef trans_multi transformation;
47 struct trans_abstract;
48 struct trans_single;
51 class ale_timer_t {
52 #if HAVE_GETTIMEOFDAY
53 struct timeval tv;
54 #else
55 time_t tt;
56 #endif
57 double total;
59 public:
61 ale_timer_t() {
62 total = 0;
65 void start() {
66 #if HAVE_GETTIMEOFDAY
67 gettimeofday(&tv, NULL);
68 #else
69 tt = time(NULL);
70 #endif
73 void stop() {
74 #if HAVE_GETTIMEOFDAY
75 timeval t;
77 gettimeofday(&t, NULL);
79 t.tv_sec -= tv.tv_sec;
80 t.tv_usec -= tv.tv_usec;
82 total += t.tv_sec + ((double) 1 / (double) 1000000) * t.tv_usec;
83 #else
84 time_t t = time(NULL);
85 t -= tt;
87 total += t;
88 #endif
91 double get_total() {
92 return total;
97 * User interface messages.
100 class ui_wo;
102 class ui {
103 private:
104 static ui *singleton;
107 * UI type
109 * 0. stream
110 * 1. tty
111 * 2. log
112 * 3. quiet
115 static int type;
117 static int output_performance_data;
119 protected:
122 * Data
125 FILE *ui_stream;
127 struct status_type {
128 enum {
130 * Special
133 UNDEFINED,
136 * Incremental rendering.
139 LOAD_FILE, EXPOSURE_PASS_1,
140 LODCLUSTER_CREATE, PREMATCH, ALIGN, GLOBAL_ALIGN, POSTMATCH,
141 EXPOSURE_PASS_2, RENDERA, RENDERD, RENDERO, WRITED,
142 WRITEO, FRAME_DONE, SET_DONE, MULTI,
145 * Irani-Peleg rendering.
148 IP_RENDER, IP_STEP_DONE, IP_UPDATE, IP_WRITE,
151 * 3D.
154 D3_CONTROL_POINT_SOLVE, D3_SUBDIVIDING_SPACE,
155 D3_UPDATING_OCCUPANCY, D3_RENDER
157 } code, orender_current;
159 int arender_current;
160 double match_value;
161 int onum;
162 int steps;
163 int steps_completed;
164 int step_type;
165 double exp_multiplier[3];
166 double perturb_size;
167 double align_lod;
168 unsigned int frame_num;
169 unsigned int irani_peleg_stage;
170 unsigned int secondary_frame_num;
171 unsigned int view_num;
172 unsigned int x_coordinate, y_coordinate;;
173 unsigned int filtering, focusing;
174 unsigned int space_num;
175 unsigned int total_spaces;
176 double cp_max_perturb;
177 double cp_min_perturb;
178 double cp_cur_perturb;
179 double cp_cur_error;
180 int cache;
182 status_type() {
183 code = UNDEFINED;
184 steps_completed = 0;
185 cache = 1;
187 for (int k = 0; k < 3; k++)
188 exp_multiplier[k] = 1;
190 } status;
193 * Performance data
196 ale_timer_t d2_align_sample;
197 ale_timer_t d2_align_sim;
198 ale_timer_t d2_incremental;
199 ale_timer_t d2_irani_peleg;
200 std::map<double,ale_timer_t> perturb_timers;
203 * Constructor
206 ui() {
207 ui_stream = stderr;
211 * Print function
214 virtual void printf(const char *format, ...) = 0;
217 * UI update function
220 virtual void update() = 0;
223 * Match format strings for textual UIs.
226 const char *format_string_ok() {
227 return " okay (%9.6f%% match)";
229 const char *format_string_no_match() {
230 return " no match (%9.6f%% match)";
232 const char *format_string_working() {
233 return " (%9.6f%% match)";
236 public:
239 * Handle options and other user input.
242 static void handle_input(int argc, const char *argv[], const char *package,
243 const char *short_version, const char *version);
245 static ui *get();
247 static void set_stream() {
248 assert(singleton == NULL);
249 type = 0;
252 static void set_tty() {
253 assert(singleton == NULL);
254 type = 1;
257 static void set_log() {
258 assert (singleton == NULL);
259 type = 2;
262 static void set_quiet() {
263 assert(singleton == NULL);
264 type = 3;
267 static void set_profile() {
268 output_performance_data = 1;
272 * Messages from the engine
275 virtual void identify_output(const char *name) {
276 printf("Output file will be '%s'.\n", name);
279 virtual void d2_align_sim_start() {
280 d2_align_sim.start();
283 virtual void d2_align_sim_stop() {
284 d2_align_sim.stop();
287 virtual void d2_align_sample_start() {
288 d2_align_sample.start();
291 virtual void d2_align_sample_stop() {
292 d2_align_sample.stop();
295 virtual void d2_incremental_start() {
296 d2_incremental.start();
299 virtual void d2_incremental_stop() {
300 d2_incremental.stop();
303 virtual void d2_irani_peleg_start() {
304 d2_irani_peleg.start();
307 virtual void d2_irani_peleg_stop() {
308 d2_irani_peleg.stop();
311 virtual void exp_multiplier(double m0, double m1, double m2) {
312 status.exp_multiplier[0] = m0;
313 status.exp_multiplier[1] = m1;
314 status.exp_multiplier[2] = m2;
317 void exp_multiplier(double mult[3]) {
318 exp_multiplier(mult[0], mult[1], mult[2]);
321 virtual void set_steps(int count, int type = 0) {
322 status.steps = count;
323 status.step_type = type;
326 virtual void set_steps_completed(int count) {
327 status.steps_completed = count;
330 virtual void set_match(double match) {
331 status.match_value = (1 - match) * 100;
332 update();
335 virtual void set_offset(d2::trans_single offset);
336 virtual void set_offset(d2::trans_multi offset);
338 virtual void gs_mo(ale_pos gs_mo) {
341 virtual void cache_status(unsigned int c) {
342 status.cache = c;
345 virtual void loading_file() {
346 status.code = status.LOAD_FILE;
347 update();
350 virtual void exposure_1() {
351 status.code = status.EXPOSURE_PASS_1;
352 update();
355 virtual void exposure_2() {
356 status.code = status.EXPOSURE_PASS_2;
357 update();
360 virtual void prematching() {
361 status.code = status.PREMATCH;
362 update();
365 virtual void postmatching() {
366 status.code = status.POSTMATCH;
367 update();
370 virtual void constructing_lod_clusters(ale_pos lod) {
371 status.code = status.LODCLUSTER_CREATE;
372 status.align_lod = lod;
373 update();
376 virtual void global_alignment(ale_pos perturb, ale_pos lod) {
377 status.perturb_size = perturb;
378 status.align_lod = lod;
379 status.code = status.GLOBAL_ALIGN;
380 update();
383 virtual void aligning(ale_pos perturb, ale_pos lod) {
384 perturb_timers[perturb].start();
385 status.perturb_size = perturb;
386 status.align_lod = lod;
387 status.code = status.ALIGN;
388 update();
391 virtual void multi() {
392 status.code = status.MULTI;
393 update();
396 virtual void following() {
399 virtual void set_orender_current(int num) {
400 status.onum = num;
401 if (num == 0)
402 status.orender_current = status.RENDERD;
403 else
404 status.orender_current = status.RENDERO;
407 virtual void set_arender_current() {
408 status.arender_current = 1;
411 virtual void clear_arender_current() {
412 status.arender_current = 0;
415 virtual void rendering() {
417 * Current alignment rendering tasks must complete
418 * before any current output rendering tasks can
419 * start.
421 if (status.arender_current) {
422 status.code = status.RENDERA;
423 status.arender_current = 0;
424 } else {
425 status.code = status.orender_current;
427 update();
430 virtual void writing_output(int num) {
431 status.onum = num;
432 if (num == 0)
433 status.code = status.WRITED;
434 else
435 status.code = status.WRITEO;
436 update();
439 virtual void d3_control_point_data(double max_perturbation, double min_perturbation, double cur_perturbation,
440 double current_error) {
441 status.cp_max_perturb = max_perturbation;
442 status.cp_min_perturb = min_perturbation;
443 status.cp_cur_perturb = cur_perturbation;
444 status.cp_cur_error = current_error;
445 update();
448 virtual void d3_control_point_step() {
449 printf(".");
450 update();
453 virtual void d3_subdivision_status(unsigned int primary_frame, unsigned int secondary_frame,
454 unsigned int i, unsigned int j) {
455 status.code = status.D3_SUBDIVIDING_SPACE;
456 status.frame_num = primary_frame;
457 status.secondary_frame_num = secondary_frame;
458 status.y_coordinate = i;
459 status.x_coordinate = j;
461 update();
464 virtual void d3_total_spaces(int total_spaces) {
465 status.total_spaces = total_spaces;
468 virtual void d3_increment_spaces() {
469 status.total_spaces++;
472 virtual void d3_occupancy_status(int frame) {
473 status.code = status.D3_UPDATING_OCCUPANCY;
474 status.frame_num = frame;
475 status.space_num = 0;
476 update();
479 virtual void d3_increment_space_num() {
480 status.space_num++;
481 update();
484 virtual void d3_render_status(int filter, int focus, int frame, int view, int i, int j, int space) {
485 status.code = status.D3_RENDER;
487 status.filtering = filter;
488 status.focusing = focus;
490 status.frame_num = frame;
491 status.view_num = view;
492 status.y_coordinate = i;
493 status.x_coordinate = j;
495 status.space_num = space;
497 update();
502 * Informational output
505 virtual void ip_start() {
506 printf("Iterating Irani-Peleg");
509 virtual void refilter_start() {
510 printf("Re-filtering incremental results");
513 virtual void ip_frame_start(unsigned int num) {
514 status.code = status.IP_RENDER;
515 status.frame_num = num;
516 status.irani_peleg_stage = 0;
517 update();
520 virtual void ip_frame_simulate_start() {
521 status.code = status.IP_RENDER;
522 status.irani_peleg_stage = 1;
523 update();
526 virtual void ip_frame_correct_start() {
527 status.code = status.IP_RENDER;
528 status.irani_peleg_stage = 2;
529 update();
532 virtual void ip_update() {
533 status.code = status.IP_UPDATE;
534 update();
537 virtual void ip_write() {
538 status.code = status.IP_WRITE;
539 update();
542 virtual void ip_step_done() {
543 status.code = status.IP_STEP_DONE;
544 printf(".");
547 virtual void ip_done() {
548 printf("\n");
551 virtual void refilter_done() {
552 printf(".\n");
555 virtual void original_frame_start(const char *name) {
556 status.code = status.UNDEFINED;
557 printf("Original Frame:\n");
558 printf(" '%s'", name);
561 virtual void original_frame_done() {
562 status.code = status.FRAME_DONE;
563 update();
566 virtual void supplemental_frame_start(const char *name) {
567 static int section_announced = 0;
569 if (!section_announced) {
570 printf("Supplemental Frames:\n");
571 section_announced = 1;
574 status.code = status.UNDEFINED;
575 status.steps_completed = 0;
576 printf(" '%s'", name);
579 virtual void supplemental_frame_done() {
580 status.code = status.FRAME_DONE;
581 update();
584 virtual void alignment_degree_complete(int degree) {
585 if (status.step_type == 1) {
586 status.steps_completed++;
587 printf("*");
591 virtual void alignment_perturbation_level(ale_pos perturb, ale_pos lod) {
592 perturb_timers[status.perturb_size].stop();
593 perturb_timers[perturb].start();
594 status.perturb_size = perturb;
595 status.align_lod = lod;
596 if (status.step_type == 0) {
597 status.steps_completed++;
598 printf(".");
602 virtual void alignment_dims(unsigned int hr, unsigned int wr, unsigned int hi, unsigned int wi) {
605 virtual void start_multi_alignment_element(d2::trans_multi &tm) {
608 virtual void alignment_match_ok() {
609 status.code = status.UNDEFINED;
610 printf(format_string_ok(), status.match_value);
613 virtual void alignment_no_match() {
614 status.code = status.UNDEFINED;
615 printf(format_string_no_match(), status.match_value);
618 virtual void ale_2d_done(double value) {
619 status.code = status.UNDEFINED;
620 printf("Average match: %f%%", value);
621 status.code = status.SET_DONE;
622 update();
623 if (output_performance_data) {
624 printf("\n");
625 printf("Real time measurements\n");
626 printf("======================\n");
627 printf("\n");
628 printf("Alignment (sampling) : %f s\n", d2_align_sample.get_total());
629 printf("Alignment (checking) : %f s\n", d2_align_sim.get_total());
630 printf("Incremental rendering : %f s\n", d2_incremental.get_total());
631 printf("Irani-Peleg rendering : %f s\n", d2_irani_peleg.get_total());
632 printf("\n");
634 printf("Details (local alignment)\n");
635 printf("-------------------------\n");
637 int have_details = 0;
638 for (std::map<double,ale_timer_t>::iterator i = perturb_timers.begin();
639 i != perturb_timers.end(); i++) {
640 if (i->second.get_total() == 0.0
641 && i == perturb_timers.begin())
642 continue;
644 printf("Alignment (perturb %f): %f s\n",
645 i->first, i->second.get_total());
647 have_details = 1;
650 if (!have_details) {
651 printf("No local alignment performed.\n");
654 printf("\n");
658 virtual void d3_start() {
659 status.code = status.UNDEFINED;
660 printf("Rendering 3D");
661 update();
664 virtual void d3_control_point_solve() {
665 status.code = status.D3_CONTROL_POINT_SOLVE;
666 update();
669 virtual void d3_init_view_angle(double angle) {
670 status.code = status.UNDEFINED;
671 update();
674 virtual void d3_final_view_angle(double angle) {
675 status.code = status.UNDEFINED;
676 update();
679 virtual void d3_control_point_solve_done() {
680 status.code = status.UNDEFINED;
681 update();
684 virtual void d3_subdividing_space() {
685 status.code = status.D3_SUBDIVIDING_SPACE;
686 update();
689 virtual void d3_subdividing_space_done() {
690 status.code = status.UNDEFINED;
691 update();
694 virtual void d3_updating_occupancy() {
695 status.code = status.D3_UPDATING_OCCUPANCY;
696 update();
699 virtual void d3_updating_occupancy_done() {
700 status.code = status.UNDEFINED;
701 update();
704 virtual void d3_writing_output(const char *name) {
705 static int section_announced = 0;
707 if (!section_announced) {
708 printf(":\n");
709 section_announced = 1;
712 printf(" '%s'", name);
714 update();
717 virtual void d3_writing_output_done() {
718 status.code = status.UNDEFINED;
719 printf(".\n");
720 update();
724 * Warnings
727 virtual void warn(const char *string) {
728 printf("\n\n*** Warning: %s. ***\n\n\n");
732 * Errors
735 virtual void exec_failure(const char *exec, const char *arg1, const char *arg2) {
736 printf("\n\n*** An error occurred while running `%s %s %s`. ***\n\n\n", exec, arg1, arg2);
737 exit(1);
740 virtual void fork_failure(const char *location) {
741 printf("\n\n*** Could not fork in %s. ***\n\n\n", location);
742 exit(1);
745 virtual void memory_error(const char *purpose) {
746 printf("\n\n*** Unable to allocate memory for %s. ***\n\n\n", purpose);
747 exit(1);
750 virtual void memory_error_location(const char *location) {
751 printf("\n\n*** Unable to allocate memory in %s.\n\n\n", location);
752 exit(1);
755 virtual void cli_not_enough(const char *option) {
756 printf("\n\n*** Not enough arguments for `%s' ***\n\n\n", option);
757 exit(1);
760 virtual void cli_bad_arg(const char *option) {
761 printf("\n\n*** Bad argument to `%s' ***\n\n", option);
762 exit(1);
765 virtual void error(const char *string) {
766 printf("\n\n*** Error: %s. ***\n\n\n", string);
767 exit(1);
770 virtual void illegal_option(const char *string) {
771 printf("\n\n*** Error: illegal option %s ***\n\n", string);
772 exit(1);
775 virtual void unknown_device(const char *string) {
776 printf("\n\n*** Error: unknown device %s ***\n\n", string);
777 exit(1);
780 virtual void error_hint(const char *error, const char *hint) {
781 printf("\n\n*** Error: %s", error);
782 printf( "\n*** Hint: %s\n\n\n", hint);
783 exit(1);
786 virtual void cache(double usage, double max) {
789 virtual void log_message(const char *message) {
792 virtual ~ui() {
796 #include "ui_wo.h"
798 #endif