1 /* === S Y N F I G ========================================================= */
2 /*! \file tool/optionsprocessor.cpp
3 ** \brief Synfig Tool Options Processor Class
4 **
5 ** $Id$
6 **
7 ** \legal
8 ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 ** Copyright (c) 2007, 2008 Chris Moore
10 ** Copyright (c) 2009-2014 Diego Barrios Romero
11 **
12 ** This package is free software; you can redistribute it and/or
13 ** modify it under the terms of the GNU General Public License as
14 ** published by the Free Software Foundation; either version 2 of
15 ** the License, or (at your option) any later version.
16 **
17 ** This package is distributed in the hope that it will be useful,
18 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 ** General Public License for more details.
21 ** \endlegal
22 */
23 /* ========================================================================= */
24
25 #ifdef USING_PCH
26 # include "pch.h"
27 #else
28 #ifdef HAVE_CONFIG_H
29 # include <config.h>
30 #endif
31
32 #include <iostream>
33 #include <boost/filesystem.hpp>
34 #include <boost/format.hpp>
35
36 #include <autorevision.h>
37 #include <synfig/general.h>
38 #include <synfig/localization.h>
39 #include <synfig/canvas.h>
40 #include <synfig/canvasfilenaming.h>
41 #include <synfig/context.h>
42 #include <synfig/target.h>
43 #include <synfig/layer.h>
44 #include <synfig/module.h>
45 #include <synfig/main.h>
46 #include <synfig/importer.h>
47 #include <synfig/loadcanvas.h>
48 #include <synfig/guid.h>
49 #include <synfig/valuenode_registry.h>
50 #include <synfig/filesystemgroup.h>
51 #include <synfig/filesystemnative.h>
52 #include <synfig/filecontainerzip.h>
53
54 #include "definitions.h"
55 #include "job.h"
56 #include "synfigtoolexception.h"
57 #include "printing_functions.h"
58 #include "optionsprocessor.h"
59
60 #endif
61
62 using namespace std;
63 using namespace synfig;
64 namespace bfs=boost::filesystem;
65
OptionsProcessor(boost::program_options::variables_map & vm,const boost::program_options::options_description & po_visible)66 OptionsProcessor::OptionsProcessor(
67 boost::program_options::variables_map& vm,
68 const boost::program_options::options_description& po_visible)
69 : _vm(vm), _po_visible(po_visible)
70 {
71 _allowed_video_codecs.push_back(VideoCodec("flv", "Flash Video (FLV) / Sorenson Spark / Sorenson H.263."));
72 _allowed_video_codecs.push_back(VideoCodec("h263p", "H.263+ / H.263-1998 / H.263 version 2."));
73 _allowed_video_codecs.push_back(VideoCodec("huffyuv", "Huffyuv / HuffYUV."));
74 _allowed_video_codecs.push_back(VideoCodec("libtheora", "libtheora Theora."));
75 _allowed_video_codecs.push_back(VideoCodec("libx264", "H.264 / AVC / MPEG-4 AVC."));
76 _allowed_video_codecs.push_back(VideoCodec("libx264-lossless", "H.264 / AVC / MPEG-4 AVC (LossLess)."));
77 _allowed_video_codecs.push_back(VideoCodec("mjpeg", "MJPEG (Motion JPEG)."));
78 _allowed_video_codecs.push_back(VideoCodec("mpeg1video", "Raw MPEG-1 video."));
79 _allowed_video_codecs.push_back(VideoCodec("mpeg2video", "Raw MPEG-2 video."));
80 _allowed_video_codecs.push_back(VideoCodec("mpeg4", "MPEG-4 part 2 (XviD/DivX)."));
81 _allowed_video_codecs.push_back(VideoCodec("msmpeg4", "MPEG-4 part 2 Microsoft variant version 3."));
82 _allowed_video_codecs.push_back(VideoCodec("msmpeg4v1", "MPEG-4 part 2 Microsoft variant version 1."));
83 _allowed_video_codecs.push_back(VideoCodec("msmpeg4v2", "MPEG-4 part 2 Microsoft variant version 2."));
84 _allowed_video_codecs.push_back(VideoCodec("wmv1", "Windows Media Video 7."));
85 _allowed_video_codecs.push_back(VideoCodec("wmv2", "Windows Media Video 8."));
86 }
87
extract_canvas_info(Job & job)88 void OptionsProcessor::extract_canvas_info(Job& job)
89 {
90 job.canvas_info = true;
91 string value;
92 string values = _vm["canvas-info"].as<string>();
93
94 std::string::size_type pos;
95 while (!values.empty())
96 {
97 pos = values.find_first_of(',');
98 if (pos == std::string::npos)
99 {
100 value = values;
101 values = "";
102 }
103 else
104 {
105 value = values.substr(0, pos);
106 values = values.substr(pos+1);
107 }
108 if (value == "all")
109 {
110 job.canvas_info_all = true;
111 return;
112 }
113
114 if (value == "time_start") job.canvas_info_time_start = true;
115 else if (value == "time_end") job.canvas_info_time_end = true;
116 else if (value == "frame_rate") job.canvas_info_frame_rate = true;
117 else if (value == "frame_start") job.canvas_info_frame_start = true;
118 else if (value == "frame_end") job.canvas_info_frame_end = true;
119 else if (value == "w") job.canvas_info_w = true;
120 else if (value == "h") job.canvas_info_h = true;
121 else if (value == "image_aspect") job.canvas_info_image_aspect = true;
122 else if (value == "pw") job.canvas_info_pw = true;
123 else if (value == "ph") job.canvas_info_ph = true;
124 else if (value == "pixel_aspect") job.canvas_info_pixel_aspect = true;
125 else if (value == "tl") job.canvas_info_tl = true;
126 else if (value == "br") job.canvas_info_br = true;
127 else if (value == "physical_w") job.canvas_info_physical_w = true;
128 else if (value == "physical_h") job.canvas_info_physical_h = true;
129 else if (value == "x_res") job.canvas_info_x_res = true;
130 else if (value == "y_res") job.canvas_info_y_res = true;
131 else if (value == "span") job.canvas_info_span = true;
132 else if (value == "interlaced") job.canvas_info_interlaced = true;
133 else if (value == "antialias") job.canvas_info_antialias = true;
134 else if (value == "clamp") job.canvas_info_clamp = true;
135 else if (value == "flags") job.canvas_info_flags = true;
136 else if (value == "focus") job.canvas_info_focus = true;
137 else if (value == "bg_color") job.canvas_info_bg_color = true;
138 else if (value == "metadata") job.canvas_info_metadata = true;
139 else
140 {
141 cerr << _("Unrecognised canvas variable: ") << "'" << value.c_str() << "'" << endl;
142 cerr << _("Recognized variables are:") << endl <<
143 " all, time_start, time_end, frame_rate, frame_start, frame_end, w, h," << endl <<
144 " image_aspect, pw, ph, pixel_aspect, tl, br, physical_w, physical_h," << endl <<
145 " x_res, y_res, span, interlaced, antialias, clamp, flags," << endl <<
146 " focus, bg_color, metadata" << endl;
147 }
148
149 if (pos == std::string::npos)
150 break;
151 };
152 }
153
process_settings_options()154 void OptionsProcessor::process_settings_options()
155 {
156 if (_vm.count("verbose"))
157 {
158 SynfigToolGeneralOptions::instance()->set_verbosity(_vm["verbose"].as<int>());
159 VERBOSE_OUT(1) << _("verbosity set to ")
160 << SynfigToolGeneralOptions::instance()->get_verbosity()
161 << std::endl;
162 }
163
164 if (_vm.count("benchmarks"))
165 {
166 SynfigToolGeneralOptions::instance()->set_should_print_benchmarks(true);
167 }
168
169 if (_vm.count("quiet"))
170 {
171 SynfigToolGeneralOptions::instance()->set_should_be_quiet(true);
172 }
173
174 if (_vm.count("threads"))
175 {
176 SynfigToolGeneralOptions::instance()->set_threads(_vm["threads"].as<int>());
177 }
178
179 VERBOSE_OUT(1) << _("Threads set to ")
180 << SynfigToolGeneralOptions::instance()->get_threads() << std::endl;
181 }
182
process_info_options()183 void OptionsProcessor::process_info_options()
184 {
185 if (_vm.count("help"))
186 {
187 print_usage();
188 cout << _po_visible;
189
190 throw (SynfigToolException(SYNFIGTOOL_HELP));
191 }
192
193 if (_vm.count("info"))
194 {
195 cout << PACKAGE "-" VERSION << endl;
196 #ifdef DEVEL_VERSION
197 cout << endl << DEVEL_VERSION << endl << endl;
198 #endif
199 cout << "Compiled on " __DATE__ /* " at "__TIME__ */;
200 #ifdef __GNUC__
201 cout << " with GCC " << __VERSION__;
202 #endif
203 #ifdef _MSC_VER
204 cout << " with Microsoft Visual C++ "
205 << (_MSC_VER>>8) << '.' << (_MSC_VER&255);
206 #endif
207 #ifdef __TCPLUSPLUS__
208 cout << " with Borland Turbo C++ "
209 << (__TCPLUSPLUS__>>8) << '.'
210 << ((__TCPLUSPLUS__&255)>>4) << '.'
211 << (__TCPLUSPLUS__&15);
212 #endif
213 cout << endl << SYNFIG_COPYRIGHT << endl;
214 cout << endl;
215
216 throw (SynfigToolException(SYNFIGTOOL_HELP));
217 }
218
219 if (_vm.count("version"))
220 {
221 cerr << PACKAGE << " " << VERSION << endl;
222
223 throw (SynfigToolException(SYNFIGTOOL_HELP));
224 }
225
226 if (_vm.count("license"))
227 {
228 cerr << PACKAGE << " " << VERSION << endl;
229 cout << SYNFIG_COPYRIGHT << endl << endl;
230 cerr << SYNFIG_LICENSE << endl << endl;
231
232 throw (SynfigToolException(SYNFIGTOOL_HELP));
233 }
234
235 if (_vm.count("target-video-codecs"))
236 {
237 print_target_video_codecs_help();
238
239 throw (SynfigToolException(SYNFIGTOOL_HELP));
240 }
241
242 if (_vm.count("layers"))
243 {
244 synfig::Layer::Book::iterator iter =
245 synfig::Layer::book().begin();
246 for(; iter != synfig::Layer::book().end(); iter++)
247 if (iter->second.category != CATEGORY_DO_NOT_USE)
248 cout << (iter->first).c_str() << endl;
249
250 throw (SynfigToolException(SYNFIGTOOL_HELP));
251 }
252
253 if (_vm.count("layer-info"))
254 {
255 Layer::Handle layer =
256 synfig::Layer::create(_vm["layer-info"].as<string>());
257
258 cout << _("Layer Name: ") << layer->get_name() << endl;
259 cout << _("Localized Layer Name: ")
260 << layer->get_local_name() << endl;
261 cout << _("Version: ") << layer->get_version() << endl;
262
263 Layer::Vocab vocab = layer->get_param_vocab();
264 for(; !vocab.empty(); vocab.pop_front())
265 {
266 cout << _("param - ") << vocab.front().get_name().c_str();
267 if(!vocab.front().get_critical())
268 cout << _(" (not critical)");
269 cout << endl << _("\tLocalized Name: ")
270 << vocab.front().get_local_name().c_str() << endl;
271
272 if(!vocab.front().get_description().empty())
273 cout << _("\tDescription: ")
274 << vocab.front().get_description().c_str() << endl;
275
276 if(!vocab.front().get_hint().empty())
277 cout << _("\tHint: ")
278 << vocab.front().get_hint().c_str() << endl;
279 }
280
281 throw (SynfigToolException(SYNFIGTOOL_HELP));
282 }
283
284 if (_vm.count("modules"))
285 {
286 synfig::Module::Book::iterator iter =
287 synfig::Module::book().begin();
288 for(; iter != synfig::Module::book().end(); iter++)
289 cout << (iter->first).c_str() << endl;
290
291 throw (SynfigToolException(SYNFIGTOOL_HELP));
292 }
293
294 if (_vm.count("targets"))
295 {
296 synfig::Target::Book::iterator iter =
297 synfig::Target::book().begin();
298 for(; iter != synfig::Target::book().end(); iter++)
299 cout << (iter->first).c_str() << endl;
300
301 throw (SynfigToolException(SYNFIGTOOL_HELP));
302 }
303
304 if (_vm.count("valuenodes"))
305 {
306 synfig::ValueNodeRegistry::Book::iterator iter =
307 synfig::ValueNodeRegistry::book().begin();
308 for(; iter != synfig::ValueNodeRegistry::book().end(); iter++)
309 cout << (iter->first).c_str() << endl;
310
311 throw (SynfigToolException(SYNFIGTOOL_HELP));
312 }
313
314 if (_vm.count("importers"))
315 {
316 synfig::Importer::Book::iterator iter =
317 synfig::Importer::book().begin();
318 for(; iter != synfig::Importer::book().end(); iter++)
319 cout << (iter->first).c_str() << endl;
320
321 throw (SynfigToolException(SYNFIGTOOL_HELP));
322 }
323 }
324
extract_renddesc(const RendDesc & renddesc)325 RendDesc OptionsProcessor::extract_renddesc(const RendDesc& renddesc)
326 {
327 RendDesc desc = renddesc;
328 int w, h;
329 float span;
330 span = w = h = 0;
331
332 if (_vm.count("width"))
333 w = _vm["width"].as<int>();
334
335 if (_vm.count("height"))
336 h = _vm["height"].as<int>();
337
338 if (_vm.count("antialias"))
339 {
340 int a;
341 a = _vm["antialias"].as<int>();
342 desc.set_antialias(a);
343 VERBOSE_OUT(1) << boost::format(_("Antialiasing set to %d, "
344 "(%d samples per pixel)")) % a % (a*a)
345 << std::endl;
346 }
347 if (_vm.count("span"))
348 {
349 span = _vm["span"].as<int>();
350 VERBOSE_OUT(1) << boost::format(_("Span set to %d units")) % span
351 << std::endl;
352 }
353 if (_vm.count("fps"))
354 {
355 float fps;
356 fps = _vm["fps"].as<float>();
357 desc.set_frame_rate(fps);
358 VERBOSE_OUT(1) << boost::format(_("Frame rate set to %d frames per "
359 "second")) % fps << std::endl;
360 }
361 if (_vm.count("dpi"))
362 {
363 float dpi, dots_per_meter;
364 dpi = _vm["dpi"].as<float>();
365 dots_per_meter = dpi * 39.3700787402;
366 desc.set_x_res(dots_per_meter);
367 desc.set_y_res(dots_per_meter);
368 VERBOSE_OUT(1) << boost::format(_("Physical resolution set to %f "
369 "dpi")) % dpi << std::endl;
370 }
371 if (_vm.count("dpi-x"))
372 {
373 float dpi, dots_per_meter;
374 dpi = _vm["dpi-x"].as<float>();
375 dots_per_meter = dpi * 39.3700787402;
376 desc.set_x_res(dots_per_meter);
377 VERBOSE_OUT(1) << boost::format(_("Physical X resolution set to %f "
378 "dpi")) % dpi << std::endl;
379 }
380 if (_vm.count("dpi-y"))
381 {
382 float dpi, dots_per_meter;
383 dpi = _vm["dpi-y"].as<float>();
384 dots_per_meter = dpi * 39.3700787402;
385 desc.set_y_res(dots_per_meter);
386 VERBOSE_OUT(1) << boost::format(_("Physical Y resolution set to %f "
387 "dpi")) % dpi << std::endl;
388 }
389 if (_vm.count("start-time"))
390 {
391 std::string seconds = _vm["start-time"].as<std::string>();
392 desc.set_time_start(Time(seconds.c_str(), desc.get_frame_rate()));
393 }
394 if (_vm.count("begin-time"))
395 {
396 std::string seconds = _vm["begin-time"].as<std::string>();
397 desc.set_time_start(Time(seconds.c_str(), desc.get_frame_rate()));
398 }
399 if (_vm.count("end-time"))
400 {
401 std::string seconds = _vm["end-time"].as<std::string>();
402 desc.set_time_end(Time(seconds.c_str(), desc.get_frame_rate()));
403 }
404 if (_vm.count("time"))
405 {
406 std::string seconds = _vm["time"].as<std::string>();
407 desc.set_time(Time(seconds.c_str(), desc.get_frame_rate()));
408
409 VERBOSE_OUT(1) << _("Rendering frame at ")
410 << desc.get_time_start().get_string(desc.get_frame_rate())
411 << endl;
412 }
413 if (_vm.count("gamma"))
414 {
415 synfig::warning(_("Gamma argument is currently ignored"));
416 //int gamma;
417 //gamma = _vm["gamma"].as<int>();
418 //desc.set_gamma(Gamma(gamma));
419 }
420
421 if (w || h)
422 {
423 // scale properly
424 if (!w)
425 w = desc.get_w() * h / desc.get_h();
426 else if (!h)
427 h = desc.get_h() * w / desc.get_w();
428
429 desc.set_wh(w, h);
430 VERBOSE_OUT(1) << boost::format(_("Resolution set to %dx%d.")) % w % h
431 << std::endl;
432 }
433
434 if(span)
435 desc.set_span(span);
436
437 return desc;
438 }
439
extract_targetparam()440 TargetParam OptionsProcessor::extract_targetparam()
441 {
442 TargetParam params;
443
444 // Both parameters are co-dependent
445 if (_vm.count("video-codec") ^ _vm.count("video-bitrate"))
446 throw (SynfigToolException(SYNFIGTOOL_MISSINGARGUMENT,
447 _("Both video codec and bitrate parameters are necessary.")));
448
449 if (_vm.count("video-codec"))
450 {
451 params.video_codec = _vm["video-codec"].as<std::string>();
452
453 // video_codec string to lowercase
454 transform (params.video_codec.begin(),
455 params.video_codec.end(),
456 params.video_codec.begin(),
457 ::tolower);
458
459 bool found = false;
460 // Check if the given video codec is allowed.
461 for (std::vector<VideoCodec>::const_iterator itr = _allowed_video_codecs.begin();
462 itr != _allowed_video_codecs.end(); ++itr)
463 {
464 if (params.video_codec == itr->name)
465 {
466 found = true;
467 }
468 }
469
470 if (!found)
471 {
472 throw SynfigToolException(SYNFIGTOOL_UNKNOWNARGUMENT,
473 (boost::format(_("Video codec \"%s\" is not supported."))
474 % params.video_codec).str());
475 }
476
477 VERBOSE_OUT(1) << _("Target video codec set to: ") << params.video_codec
478 << std::endl;
479 }
480 if(_vm.count("video-bitrate"))
481 {
482 params.bitrate = _vm["video-bitrate"].as<int>();
483 VERBOSE_OUT(1) << _("Target bitrate set to: ") << params.bitrate << "k."
484 << std::endl;
485 }
486 if(_vm.count("sequence-separator"))
487 {
488 params.sequence_separator = _vm["sequence-separator"].as<std::string>();
489 VERBOSE_OUT(1) << _("Output file sequence separator set to: '")
490 << params.sequence_separator
491 << "'."
492 << std::endl;
493 }
494
495 return params;
496 }
497
extract_job()498 Job OptionsProcessor::extract_job()
499 {
500 Job job;
501
502 // Common input file loading
503 if (_vm.count("input-file"))
504 {
505 job.filename = _vm["input-file"].as<string>();
506
507 // Open the composition
508 string errors, warnings;
509 try
510 {
511 if (FileSystem::Handle file_system = CanvasFileNaming::make_filesystem(job.filename))
512 {
513 FileSystem::Identifier identifier = file_system->get_identifier(CanvasFileNaming::project_file(job.filename));
514 job.root = open_canvas_as(identifier, job.filename, errors, warnings);
515 }
516 else
517 {
518 errors.append("Cannot open container " + job.filename + "\n");
519 }
520 }
521 catch(runtime_error& x)
522 {
523 job.root = 0;
524 }
525
526 // By default, the canvas to render is the root canvas
527 // This can be changed through --canvas option
528 job.canvas = job.root;
529
530 if(!job.canvas)
531 {
532 throw SynfigToolException(SYNFIGTOOL_FILENOTFOUND,
533 (boost::format(_("Unable to load file '%s'.")) % job.filename).str());
534 }
535
536 job.root->set_time(0);
537 }
538 else
539 {
540 throw SynfigToolException(SYNFIGTOOL_MISSINGARGUMENT,
541 _("No input file provided."));
542 }
543
544 if (_vm.count("target"))
545 {
546 job.target_name = _vm["target"].as<std::string>();
547 VERBOSE_OUT(1) << _("Target set to ") << job.target_name << std::endl;
548 }
549
550 // Determine output
551 if (_vm.count("output-file"))
552 {
553 job.outfilename = _vm["output-file"].as<std::string>();
554 }
555
556 if (_vm.count("extract-alpha"))
557 {
558 job.extract_alpha = true;
559 }
560
561 if (_vm.count("quality"))
562 job.quality = _vm["quality"].as<int>();
563 else
564 job.quality = DEFAULT_QUALITY;
565
566 VERBOSE_OUT(1) << _("Quality set to ") << job.quality << std::endl;
567
568 // WARNING: canvas must be before append
569
570 if (_vm.count("canvas"))
571 {
572 std::string canvasid;
573 canvasid = _vm["canvas"].as<std::string>();
574
575 try
576 {
577 std::string warnings;
578 job.canvas = job.root->find_canvas(canvasid, warnings);
579 // TODO: This exceptions should not terminate the program if multi-job
580 // processing is available.
581 }
582 catch(Exception::IDNotFound&)
583 {
584 throw SynfigToolException(SYNFIGTOOL_INVALIDJOB,
585 (boost::format(_("Unable to find canvas with ID \"%s\" in %s.\n"
586 "Throwing out job..."))
587 % canvasid % job.filename).str());
588 }
589 catch(Exception::BadLinkName&)
590 {
591 throw SynfigToolException(SYNFIGTOOL_INVALIDJOB,
592 (boost::format(_("Invalid canvas name \"%s\" in %s.\n"
593 "Throwing out job..."))
594 % canvasid % job.filename).str());
595 }
596
597 // Later we need to set the other parameters for the jobs
598 }
599
600 // WARNING: append must be before list-canvases
601
602 if (_vm.count("append"))
603 {
604 // TODO: Enable multi-appending. Disabled in the previous CLI version
605 std::string composite_file = _vm["append"].as<std::string>();
606
607 std::string errors, warnings;
608 Canvas::Handle composite;
609 if (FileSystem::Handle file_system = CanvasFileNaming::make_filesystem(composite_file))
610 {
611 FileSystem::Identifier identifier = file_system->get_identifier(CanvasFileNaming::project_file(composite_file));
612 composite = open_canvas_as(identifier, composite_file, errors, warnings);
613 }
614 else
615 {
616 errors.append("Cannot open container " + composite_file + "\n");
617 }
618
619 if(!composite)
620 {
621 VERBOSE_OUT(1) << _("Unable to append '") << composite_file.c_str()
622 << "'." << endl;
623 }
624 else
625 {
626 Canvas::reverse_iterator iter;
627 for(iter=composite->rbegin(); iter!=composite->rend(); ++iter)
628 {
629 Layer::Handle layer(*iter);
630 //if(layer->active())
631 job.canvas->push_front(layer->clone(composite));
632 }
633 }
634
635 VERBOSE_OUT(2) << _("Appended contents of ") << composite_file << endl;
636 }
637
638 if (_vm.count("list-canvases") || _vm.count("canvases"))
639 {
640 print_child_canvases(job.filename + "#", job.root);
641 std::cerr << std::endl;
642
643 throw SynfigToolException(SYNFIGTOOL_OK);
644 }
645
646 if (_vm.count("canvas-info"))
647 {
648 extract_canvas_info(job);
649 print_canvas_info(job);
650
651 throw SynfigToolException(SYNFIGTOOL_OK);
652 }
653
654 return job;
655 }
656
print_target_video_codecs_help() const657 void OptionsProcessor::print_target_video_codecs_help() const
658 {
659 for (std::vector<VideoCodec>::const_iterator itr = _allowed_video_codecs.begin();
660 itr != _allowed_video_codecs.end(); ++itr)
661 {
662 std::cout << " " << itr->name << ": \t" << itr->description
663 << std::endl;
664 }
665 }
666
667 #ifdef _DEBUG
668
669 // DEBUG auxiliar functions
guid_test()670 void guid_test()
671 {
672 std::cout << "GUID Test" << std::endl;
673 for(int i = 20; i; i--)
674 std::cout << synfig::GUID().get_string() << ' '
675 << synfig::GUID().get_string() << std::endl;
676 }
677
signal_test_func()678 void signal_test_func()
679 {
680 std::cout << "**SIGNAL CALLED**" << std::endl;
681 }
682
signal_test()683 void signal_test()
684 {
685 sigc::signal<void> sig;
686 sigc::connection conn;
687 std::cout << "Signal Test" << std::endl;
688 conn = sig.connect(sigc::ptr_fun(signal_test_func));
689 std::cout << "Next line should exclaim signal called." << std::endl;
690 sig();
691 conn.disconnect();
692 std::cout << "Next line should NOT exclaim signal called." << std::endl;
693 sig();
694 std::cout << "done." << std::endl;
695 }
696
697 // DEBUG options ----------------------------------------------
process_debug_options()698 void OptionsProcessor::process_debug_options() throw (SynfigToolException&)
699 {
700 if (_vm.count("signal-test"))
701 {
702 signal_test();
703 throw (SynfigToolException(SYNFIGTOOL_HELP));
704 }
705
706 if (_vm.count("guid-test"))
707 {
708 guid_test();
709 throw (SynfigToolException(SYNFIGTOOL_HELP));
710 }
711 }
712
713 #endif
714
715