cgv
Loading...
Searching...
No Matches
register.cxx
1#include <cgv/base/register.h>
2#include <cgv/utils/convert.h>
3#include <cgv/utils/tokenizer.h>
5#include <cgv/utils/file.h>
6#include <cgv/type/variant.h>
7
8#include <algorithm>
9#include <vector>
10#include <set>
11
12#if defined(_WIN32)
13#include <Windows.h>
14#include <strsafe.h>
15#if defined(NDEBUG)
16#define CGV_NDEBUG
17#endif
18#else
19#if defined(DEBUG)
20#else
21#define CGV_NDEBUG
22#endif
23#endif
24
25using namespace cgv::utils;
26
27namespace cgv {
28namespace base {
29
30/**************** additional types *********************/
31
33{
34 bool registration_enabled;
35 bool permanent_registration;
36 bool registration_event_cleanup;
37 unsigned int nr_events_before_disable;
39 {
40 registration_enabled = false;
41 permanent_registration = true;
42 registration_event_cleanup = false;
43 nr_events_before_disable = 0;
44 }
45};
46
48{
49 std::string partial_order;
50 bool before_contructor_execution;
51 std::string when;
52 registration_order_info() : before_contructor_execution(false) {}
54 const std::string& _when)
55 : partial_order(_partial_order), before_contructor_execution(_before_contructor_execution), when(_when)
56 {
57 }
58};
59
61{
62 std::vector<base_ptr> objects;
63 void add_object(base_ptr object)
64 {
65 objects.push_back(object);
66 }
67 void remove_object(base_ptr object)
68 {
69 for (unsigned int i = 0; i < objects.size(); ++i) {
70 if (object == objects[i]) {
71 objects.erase(objects.begin() + i);
72 ++i;
73 }
74 }
75 }
76 void unregister_all_objects()
77 {
78 while (objects.size() > 0) {
79 unregister_object(objects.back());
80 }
81 }
82 named_ptr find_object_by_name(const std::string& name)
83 {
84 for (unsigned int oi = 0; oi < objects.size(); ++oi) {
85 named_ptr np = objects[oi]->cast<named>();
86 if (np && np->get_name() == name)
87 return np;
88 }
89 return named_ptr();
90 }
91 base_ptr find_object_by_type(const std::string& type_name)
92 {
93 for (unsigned int oi = 0; oi < objects.size(); ++oi) {
94 base_ptr bp = objects[oi];
95 if (type_name == bp->get_type_name())
96 return bp;
97 }
98 return base_ptr();
99 }
100 bool request_exit_from_all_objects()
101 {
102 bool exit = true;
103 for(unsigned int oi = 0; oi < objects.size(); ++oi) {
104 base_ptr bp = objects[oi];
105 exit = exit && bp->on_exit_request();
106 }
107 return exit;
108 }
109};
110
111/**************** static variables *********************/
112
113object_collection& ref_object_collection()
114{
115 static object_collection oc;
116 return oc;
117}
118
119std::vector<registration_order_info>& ref_registration_order_infos()
120{
121 static std::vector<registration_order_info> roi;
122 return roi;
123}
124
125std::string& ref_prog_name()
126{
127 static std::string prog_name;
128 return prog_name;
129}
130
132{
133 static std::string prog_path_prefix;
134 return prog_path_prefix;
135}
136
137std::string& ref_plugin_name()
138{
139 static std::string plugin_name;
140 return plugin_name;
141}
142
143std::map<std::string, resource_file_info>& ref_resource_file_map()
144{
145 static std::map<std::string, resource_file_info> resource_file_map;
146 return resource_file_map;
147}
148
149registration_info& ref_info()
150{
151 static registration_info ri;
152 return ri;
153}
154
155std::vector<std::pair<base_ptr, std::string>>& ref_registration_events()
156{
157 static std::vector<std::pair<base_ptr, std::string>> registration_events;
158 return registration_events;
159}
160
161std::vector<base_ptr>& ref_listeners()
162{
163 static std::vector<base_ptr> listeners;
164 return listeners;
165}
166
167/****************** helper functions **************/
168
169void show_split_lines(const std::string& s)
170{
171 if (s.empty())
172 return;
173 std::vector<token> toks;
174 bite_all(tokenizer(s).set_ws(";"), toks);
175 for (unsigned i = 0; i < toks.size(); ++i)
176 std::cout << "\n " << to_string(toks[i]).c_str();
177}
178
179bool& ref_registration_debugging_enabled()
180{
181#if defined CGV_FORCE_STATIC && defined _DEBUG
182 static bool is_debug = true;
183#else
184 static bool is_debug = false;
185#endif
186 return is_debug;
187}
188
189void show_object_debug_info(cgv::base::base_ptr o)
190{
191 std::cout << o->get_type_name();
192 if (o->get_named())
193 std::cout << "<" << o->get_named()->get_name() << ">";
194 bool is_c = o->get_interface<object_constructor>() != 0;
195 bool is_s = o->get_interface<server>() != 0;
196 bool is_d = o->get_interface<driver>() != 0;
197 bool is_l = o->get_interface<registration_listener>() != 0;
198
199 if (is_c || is_s || is_d || is_l) {
200 std::cout << " [";
201 if (is_c)
202 std::cout << "C";
203 if (is_s)
204 std::cout << "S";
205 if (is_d)
206 std::cout << "D";
207 if (is_l)
208 std::cout << "L";
209 std::cout << "]";
210 }
211}
212
214void register_object_internal(base_ptr object, const std::string& options)
215{
216 std::string all_options = object->get_default_options();
217 if (!all_options.empty() && !options.empty())
218 all_options += ";";
219 all_options += options;
221 std::cout << "REG OBJECT ('" << all_options << "') ";
222 show_object_debug_info(object);
223 std::cout << std::endl;
224
225 static std::map<cgv::base::base*, int> is_registered;
226 if (is_registered.find(&(*object)) == is_registered.end())
227 is_registered[&(*object)] = 1;
228 else {
229 ++is_registered[&(*object)];
230 std::cerr << "ERROR: last object registered " << is_registered[&(*object)] << " times" << std::endl;
231 }
232 }
233
234 // send register event to all listeners
235 for (unsigned i = 0; i < ref_listeners().size(); ++i)
236 ref_listeners()[i]->get_interface<registration_listener>()->register_object(object, all_options);
237
238 // perform permanent registration
240 ref_object_collection().add_object(object);
241 // send register event to object
242 object->on_register();
243}
244
245/****************** implementation of exported functions **************/
246
247void define_registration_order(const std::string& partial_order, bool before_contructor_execution,
248 const std::string& when)
249{
250 ref_registration_order_infos().push_back(registration_order_info(partial_order, before_contructor_execution, when));
251}
252
253void add_partially_ordered(const std::vector<std::set<unsigned>>& combined_partial_order,
254 std::vector<unsigned>& permutation, std::vector<bool>& appended, std::vector<bool>& delayed,
255 unsigned i)
256{
257 if (delayed[i]) {
258 std::cout << "REG ORDER cyclic dependency of registration event <"
259 << ref_registration_events()[i].first->get_type_name() << ">" << std::endl;
260 return;
261 }
262 delayed[i] = true;
263 // ensure that indices that have to come before i, are also added before i
264 for (auto j : combined_partial_order[i]) {
265 if (!appended[j])
266 add_partially_ordered(combined_partial_order, permutation, appended, delayed, j);
267 }
268 delayed[i] = false;
269 appended[i] = true;
270 permutation.push_back(i);
271}
272
273void sort_registration_events(bool before_contructor_execution)
274{
275 // initialized combined partial order
276 size_t N = ref_registration_events().size();
277 std::vector<std::set<unsigned>> combined_partial_order;
278 combined_partial_order.resize(N);
279 unsigned nr_partial_orders = 0;
280
281 // iterate all registration order infos
282 for (auto roi : ref_registration_order_infos()) {
283 // ignore if before_contructor_execution does not match
284 if (roi.before_contructor_execution != before_contructor_execution)
285 continue;
286
287 // ignore if "when" does not match
288 if (roi.when == "plugins") {
289 if (ref_plugin_name().empty())
290 continue;
291 }
292 else if (roi.when == "program") {
293 if (!ref_plugin_name().empty())
294 continue;
295 }
296 else if (roi.when != "always") {
297 if (ref_plugin_name() != roi.when)
298 continue;
299 }
300
301 // extract partial order
302 std::vector<cgv::utils::token> toks;
303 cgv::utils::tokenizer(roi.partial_order).set_ws(";").bite_all(toks);
304
305 // first construct a vector with indices of registration events
306 std::vector<unsigned> event_indices;
307 unsigned nr_matched = 0;
308 for (auto t : toks) {
309 bool found = false;
310 for (unsigned i = 0; i < N; ++i) {
311 std::string tn = ref_registration_events()[i].first->get_type_name();
312 if (t == tn) {
313 event_indices.push_back(i);
314 ++nr_matched;
315 found = true;
316 break;
317 }
318 }
319 if (!found) {
320 std::cout << "REG ORDER: could not find event <" << t << ">" << std::endl;
321 }
322 }
323 if (nr_matched < 2) {
324 std::cout << "REG ORDER: partial order <" << roi.partial_order << "> did match only " << nr_matched
325 << " object" << std::endl;
326 continue;
327 }
328
329 // extend combined partial order by current partial order
330 for (unsigned i = 1; i < event_indices.size(); ++i)
331 combined_partial_order[event_indices[i]].insert(event_indices[i - 1]);
332 ++nr_partial_orders;
333 }
334 if (nr_partial_orders == 0)
335 return;
336
337 // compute permutation
338 std::vector<unsigned> permutation;
339 std::vector<bool> appended(N, false);
340 std::vector<bool> delayed(N, false);
341 unsigned i;
342 for (i = 0; i < N; ++i) {
343 if (!appended[i])
344 add_partially_ordered(combined_partial_order, permutation, appended, delayed, i);
345 }
346 if (permutation.size() != N) {
347 std::cerr << "ERROR: could not compute valid permutation of registration events" << std::endl;
348 abort();
349 }
350
351 // permute registration events
352 std::vector<std::pair<base_ptr, std::string>> permuted_registration_events;
353 permuted_registration_events.resize(N);
354 for (i = 0; i < N; ++i)
355 permuted_registration_events[i] = ref_registration_events()[permutation[i]];
356 ref_registration_events() = permuted_registration_events;
357}
358
359registration_order_definition::registration_order_definition(const std::string& partial_order,
360 bool before_contructor_execution, const std::string& when)
361{
362 define_registration_order(partial_order, before_contructor_execution, when);
363}
364
366{
367 ref_registration_debugging_enabled() = true;
368}
371{
372 ref_registration_debugging_enabled() = false;
373}
374
377{
378 return ref_registration_debugging_enabled();
379}
382{
384 return;
385
387 std::cout << "REG ENABLE <" << (ref_plugin_name().empty() ? ref_prog_name() : ref_plugin_name()) << "> Begin"
388 << std::endl;
389
390 unsigned i, i0 = ref_info().nr_events_before_disable;
391
392 sort_registration_events(true);
393
394 // first execute delayed registrations by replacing constructor objects with constructed objects
395 for (i = i0; i < ref_registration_events().size(); ++i) {
396 base_ptr o = ref_registration_events()[i].first;
398 if (obr) {
400 std::cout << "REG CONSTRUCT " << obr->get_constructed_type_name() << "('"
401 << ref_registration_events()[i].second << "')";
402
403 ref_registration_events()[i].first = obr->construct_object();
404
406 std::cout << " -> ";
407 show_object_debug_info(ref_registration_events()[i].first);
408 std::cout << std::endl;
409 }
410 }
411 }
412
413 sort_registration_events(false);
414
415 // next register all servers
416 const std::vector<base_ptr>& L = ref_listeners();
417 for (i = i0; i < ref_registration_events().size(); ++i) {
418 base_ptr object = ref_registration_events()[i].first;
419 if (object->get_interface<server>() == 0)
420 continue;
421 register_object_internal(object, ref_registration_events()[i].second);
422 if (object->get_interface<registration_listener>() != 0)
423 ref_listeners().push_back(object);
424 }
425
426 // next register all drivers
427 for (i = i0; i < ref_registration_events().size(); ++i) {
428 base_ptr object = ref_registration_events()[i].first;
429 if (object->get_interface<driver>() == 0)
430 continue;
431 register_object_internal(object, ref_registration_events()[i].second);
432 if (object->get_interface<registration_listener>() != 0)
433 ref_listeners().push_back(object);
434 }
435
436 // next register all listeners
437 for (i = i0; i < ref_registration_events().size(); ++i) {
438 base_ptr object = ref_registration_events()[i].first;
439 auto* listener = object->get_interface<registration_listener>();
440 if (listener == 0)
441 continue;
442 if (object->get_interface<server>() == 0 && object->get_interface<driver>() == 0) {
443 register_object_internal(object, ref_registration_events()[i].second);
444 ref_listeners().push_back(object);
445 }
446 // send all buffered events
447 unsigned j;
448 for (j = 0; j < i0; ++j)
449 listener->register_object(ref_registration_events()[j].first, ref_registration_events()[j].second);
450 // send all previous listener registration
451 for (j = i0; j < i; ++j) {
452 base_ptr prev_object = ref_registration_events()[j].first;
453 if (prev_object->get_interface<registration_listener>() == 0)
454 continue;
455 listener->register_object(ref_registration_events()[j].first, ref_registration_events()[j].second);
456 }
457 }
458
459 // next register all remaining objects
460 for (i = i0; i < ref_registration_events().size(); ++i) {
461 base_ptr object = ref_registration_events()[i].first;
462 if (object->get_interface<registration_listener>() != 0 || object->get_interface<driver>() != 0 ||
463 object->get_interface<server>() != 0)
464 continue;
465 register_object_internal(object, ref_registration_events()[i].second);
466 }
467
468 // remove registration events
470 ref_registration_events().clear();
471
472 ref_info().nr_events_before_disable = (unsigned)ref_registration_events().size();
473 ref_info().registration_enabled = true;
474
476 std::cout << "REG ENABLE <" << (ref_plugin_name().empty() ? ref_prog_name() : ref_plugin_name()) << "> End"
477 << std::endl;
478}
479
481{
483 return;
485 std::cout << "REG DISABLE <" << (ref_plugin_name().empty() ? ref_prog_name() : ref_plugin_name()) << ">"
486 << std::endl;
487
488 ref_info().nr_events_before_disable = (unsigned)ref_registration_events().size();
489 ref_info().registration_enabled = false;
490}
491
494{
495 return ref_info().registration_enabled;
496}
497
499{
501 return;
503 std::cout << "ENABLE PERMANENT REGISTRATION" << std::endl;
504 }
505 ref_info().permanent_registration = true;
506}
507
509{
510 ref_object_collection().unregister_all_objects();
511}
512
514{
515 return ref_object_collection().request_exit_from_all_objects();
516}
517
520{
521 return (unsigned)ref_object_collection().objects.size();
522}
523
526{
528 return 0;
529 return ref_object_collection().objects[i];
530}
531
533{
535 return;
537 std::cout << "DISABLE PERMANENT REGISTRATION" << std::endl;
538 }
539 ref_info().permanent_registration = false;
540}
541
544{
545 return ref_info().permanent_registration;
546}
547
549{
551 return;
553 std::cout << "ENABLE REGISTRATION CLEANUP" << std::endl;
554 }
555 ref_info().registration_event_cleanup = true;
557 ref_registration_events().clear();
558 else
559 ref_registration_events().erase(ref_registration_events().begin(),
560 ref_registration_events().begin() + ref_info().nr_events_before_disable);
561 ref_info().nr_events_before_disable = 0;
562}
563
566{
568 return;
570 std::cout << "DISABLE REGISTRATION CLEANUP" << std::endl;
571 }
572 ref_info().registration_event_cleanup = false;
573}
574
576{
577 return ref_info().registration_event_cleanup;
578}
579
581void register_object(base_ptr object, const std::string& options)
582{
583 // if registration is disabled or if registratration event cleanup is disabled, store registration event
585 ref_registration_events().emplace_back(object, options);
586
588 std::cout << "REG EVENT ('" << options << "') ";
589 show_object_debug_info(object);
590 std::cout << std::endl;
591 }
592 }
594 return;
595
596 // execute object constructor in case of delayed registration
597 object_constructor* oc = object->get_interface<object_constructor>();
598 if (oc)
599 object = oc->construct_object();
600
601 // register as listener if necessary
602 registration_listener* rl = object->get_interface<registration_listener>();
603 if (rl) {
604 ref_listeners().push_back(object);
605 // send all buffered events
607 // next register all remaining objects
608 for (unsigned i = 0; i < ref_registration_events().size(); ++i)
609 rl->register_object(ref_registration_events()[i].first, ref_registration_events()[i].second);
610 }
611 }
612
613 register_object_internal(object, options);
614}
615
617void unregister_object(base_ptr object, const std::string& options)
618{
619 unsigned int i;
620
622 std::cout << "UNREG " << object.operator->() << ", '" << options << "' ("
623 << ref_object_collection().objects.size() << ")" << std::endl;
624 }
625
626 // remove from permanent registration
627 ref_object_collection().remove_object(object);
628
629 // remove from registration events
630 for (i = 0; i < ref_registration_events().size(); ++i)
631 if (ref_registration_events()[i].first == object) {
632 ref_registration_events().erase(ref_registration_events().begin() + i);
633 --i;
634 }
635
636 // remove from listeners
637 if (object->get_interface<registration_listener>()) {
638 for (i = 0; i < ref_listeners().size(); ++i) {
639 if (ref_listeners()[i] == object) {
640 ref_listeners().erase(ref_listeners().begin() + i);
641 --i;
642 }
643 }
644 }
645 // send unregister events to remaining listeners
646 for (unsigned int i = 0; i < ref_listeners().size(); ++i)
647 ref_listeners()[i]->get_interface<registration_listener>()->unregister_object(object, options);
648
649 // send unregister event to object itself
650 object->unregister();
651}
652
654named_ptr find_object_by_name(const std::string& name)
655{
656 return ref_object_collection().find_object_by_name(name);
657}
658
660base_ptr find_object_by_type(const std::string& type_name)
661{
662 return ref_object_collection().find_object_by_type(type_name);
663}
664
665std::string get_config_file_name(const std::string& _file_name)
666{
667 std::string file_name = _file_name;
668 if (file::get_extension(file_name) == "def") {
669 std::string fn = file::drop_extension(file_name) + ".cfg";
670 if (file::exists(fn))
671 file_name = fn;
672 }
673 return file_name;
674}
675
676// bool process_command_ext(const token& cmd, bool eliminate_quotes, bool* persistent = 0, config_file_observer* cfo =
677// 0, const char* begin = 0);
678bool process_command_ext(const command_info& info, bool* persistent = 0, config_file_observer* cfo = 0,
679 const char* begin = 0);
680
681config_file_driver*& ref_config_file_driver()
682{
683 static config_file_driver* driver = 0;
684 return driver;
685}
686
688{
689 if (ref_config_file_driver())
690 std::cerr << "warning: registering more than one config_file_driver" << std::endl;
691 ref_config_file_driver() = cfd;
692}
693
694config_file_observer* find_config_file_observer(const std::string& file_name, const std::string& content)
695{
696 if (!ref_config_file_driver()) {
697 std::cerr << "warning: attempt to use permanent registration without a registered config_file_driver"
698 << std::endl;
699 return 0;
700 }
701 return ref_config_file_driver()->find_config_file_observer(file_name, content);
702}
703
704bool process_config_file_ext(const std::string& _file_name, bool* persistent = 0)
705{
706 // update file name extension
707 std::string file_name = get_config_file_name(_file_name);
708 if (file_name.empty())
709 return false;
710 // try to read file
711 std::string content;
712 if (!file::read(file_name, content, true)) {
713 std::cerr << "couldn't read config file " << file_name.c_str() << std::endl;
714 return false;
715 }
716
717 bool pers = false;
718 if (!persistent)
719 persistent = &pers;
720
721 config_file_observer* cfo = find_config_file_observer(file_name, content);
722
723 // split file content into lines
724 std::vector<line> lines;
725 split_to_lines(content, lines);
726
727 // interpret each line as a command
728 unsigned int i;
729 std::string cfg_file_dir = cgv::utils::file::get_path(_file_name);
730 for (i = 0; i < lines.size(); ++i) {
731 command_info info;
732 std::string line;
733 const char* begin = lines[i].begin;
734 const char* iter = begin;
735 while (iter < lines[i].end) {
736 // find next appearance of '$'
737 iter = std::find(iter, lines[i].end, '$');
738 if (iter == lines[i].end) {
739 if (begin > lines[i].begin)
740 line += std::string(begin, lines[i].end);
741 break;
742 }
743 // check for '('
744 auto jter = iter;
745 std::string value;
746 if (++jter < lines[i].end) {
747 if (*jter == '(') {
748 // extract name of variable up to closing paranthesis
749 std::string var_name;
750 while (++jter < lines[i].end && *jter != ')') {
751 var_name.push_back(*jter);
752 }
753 if (jter < lines[i].end) {
754 // convert to upper case
755 var_name = cgv::utils::to_upper(var_name);
756 if (var_name == "CFG_FILE_DIR")
757 value = cfg_file_dir;
758 else {
759 value = std::string(getenv(var_name.c_str()));
760 }
761 }
762 }
763 }
764 if (value.empty()) {
765 ++iter;
766 continue;
767 }
768 line += std::string(begin, iter);
769 line += value;
770 begin = iter = jter + 1;
771 }
772 if (line.empty())
773 analyze_command(lines[i], false, &info);
774 else
775 analyze_command(token(line), false, &info);
776
777 process_command_ext(info, persistent, cfo, &content[0]);
778 // process_command_ext((token&)(lines[i]), false, persistent, cfo, &content[0]);
779 }
780 return true;
781}
782
783bool process_config_file(const std::string& _file_name)
784{
785 return process_config_file_ext(_file_name);
786}
787
789bool process_gui_file(const std::string& file_name)
790{
791 config_file_driver* cfd = ref_config_file_driver();
792 if (cfd)
793 return cfd->process_gui_file(file_name);
794 std::cerr << "attempt to process gui file without a config_file_driver registered" << std::endl;
795 return false;
796}
797
798test::test(const std::string& _test_name, bool (*_test_func)()) : test_name(_test_name), test_func(_test_func) {}
799
800std::string test::get_test_name() const
801{
802 return test_name;
803}
804
805bool test::exec_test() const
806{
807 return test_func();
808}
809
811
812std::string test::get_type_name() const
813{
814 return "test";
815}
816
821
823factory::factory(const std::string& _created_type_name, bool _singleton, const std::string& _object_options)
824 : created_type_name(_created_type_name), is_singleton(_singleton), object_options(_object_options)
825{
826}
827
830{
831 return object_options;
832}
833
836{
837 return "create:bool";
838}
839
841bool factory::set_void(const std::string& property, const std::string& value_type, const void* value_ptr)
842{
843 if (property == "create") {
844 bool do_create;
845 cgv::type::get_variant(do_create, value_type, value_ptr);
846 if (do_create)
848 return true;
849 }
850 else
851 return false;
852}
853
855bool factory::get_void(const std::string& property, const std::string& value_type, void* value_ptr)
856{
857 if (property == "create") {
858 cgv::type::set_variant(true, value_type, value_ptr);
859 return true;
860 }
861 else
862 return false;
863}
864
866const std::string& factory::get_created_type_name() const
867{
868 return created_type_name;
869}
872{
873 return is_singleton;
874}
875
878{
879 return singleton;
880}
886
889{
892 singleton = o;
893 return o;
894}
895
896std::string guess_created_type_name(const char* item_text)
897{
898 std::vector<token> toks;
899 tokenizer(item_text).set_ws("/").bite_all(toks);
900 if (toks.empty())
901 return "";
902 return to_string(toks.back());
903}
904
905void register_factory_object(base_ptr fo, const char* item_text, char shortcut)
906{
907 std::string options("menu_text=\"");
908 options += item_text;
909 options += "\";shortcut='Ctrl-";
910 options += shortcut;
911 options += "'";
912 register_object(fo, options);
913}
914
916{
917 ref_prog_name() = cgv::utils::file::get_file_name(_prog_name);
918 std::string prog_path_prefix = cgv::utils::file::clean_path(cgv::utils::file::get_path(_prog_name));
919 if (!prog_path_prefix.empty())
920 prog_path_prefix += '/';
922}
923
925 const std::string& _source_file)
926 : file_offset(_file_offset), file_length(_file_length), file_data(_file_data), source_file(_source_file)
927{
928}
929
930void register_resource_file(const std::string& file_path, unsigned int file_offset, unsigned int file_length,
931 const char* file_data, const std::string& source_file)
932{
933 ref_resource_file_map()[file_path] = resource_file_info(file_offset, file_length, file_data, source_file);
934}
935
936void register_resource_string(const std::string& string_name, const char* string_data)
937{
939 resource_file_info(-1, (unsigned)std::string(string_data).size(), string_data);
940}
941
942void show_implementation(bool& implements_shown, const std::string& type_name)
943{
944 if (implements_shown)
945 std::cout << ", ";
946 else {
947 std::cout << " implements ";
948 implements_shown = true;
949 }
950 std::cout << type_name;
951}
952
955{
956 const std::vector<base_ptr>& objects = ref_object_collection().objects;
957
958 std::cout << "\n\n_______________ show all registered objects ______________________\n\n";
959 for (unsigned int oi = 0; oi < objects.size(); ++oi) {
960 named_ptr np = objects[oi]->cast<named>();
961 if (np)
962 std::cout << "name(" << np->get_name().c_str() << "):" << np->get_type_name();
963 else
964 std::cout << "type(" << objects[oi]->get_type_name() << ")";
965 bool implements_shown = false;
966 if (objects[oi]->get_interface<server>())
967 show_implementation(implements_shown, "server");
968 if (objects[oi]->get_interface<driver>())
969 show_implementation(implements_shown, "driver");
971 show_implementation(implements_shown, "registration_listener");
972 if (objects[oi]->get_interface<factory>())
973 show_implementation(implements_shown, "factory");
974 show_split_lines(objects[oi]->get_property_declarations());
975 std::cout << "\n\n";
976 }
977 std::cout << "__________________________________________________________________\n" << std::endl;
978 return;
979}
980
981CommandType update_info(command_info* info_ptr, CommandType cmd, cgv::utils::token* args_tok_ptr = 0)
982{
983
984 if (info_ptr) {
985 info_ptr->command_type = cmd;
986 if (args_tok_ptr)
987 info_ptr->parameters.push_back(*args_tok_ptr);
988 }
989 return cmd;
990}
991
993{
994 // remove unnecessary stuff
995 token cmd_tok = cmd;
998
999 // detect empty lines and comments
1000 if (cmd_tok.empty())
1001 return update_info(info_ptr, CT_EMPTY);
1002
1003 // detect comments
1004 if (cmd_tok.get_length() > 1 && cmd_tok[0] == '/' && cmd_tok[1] == '/')
1005 return update_info(info_ptr, CT_COMMENT);
1006
1007 // detect predefined commands
1008 if (cmd_tok == "show all")
1009 return update_info(info_ptr, CT_SHOW);
1010 if (cmd_tok == "persistent")
1011 return update_info(info_ptr, CT_PERSISTENT);
1012 if (cmd_tok == "initial")
1013 return update_info(info_ptr, CT_INITIAL);
1014
1015 // determine command header
1016 token cmd_header = tokenizer(cmd_tok).set_sep(":").set_ws("").set_skip("\"'", "\"'").bite();
1017 if (cmd_header.end == cmd_tok.end)
1018 return update_info(info_ptr, CT_UNKNOWN);
1019
1020 // and command arguments
1022
1023 // eliminate quotes around argument, which need to be used in commands specified on the command line
1024 if (eliminate_quotes && args_tok.get_length() >= 2 &&
1025 ((args_tok[0] == '"' && args_tok[(int)args_tok.get_length() - 1] == '"') ||
1026 (args_tok[0] == '\'' && args_tok[(int)args_tok.get_length() - 1] == '\'')))
1027 {
1028 ++args_tok.begin;
1029 --args_tok.end;
1030 }
1031 std::string args(to_string(args_tok));
1032
1033 // detect direct commands
1034 if (cmd_header == "plugin")
1035 return update_info(info_ptr, CT_PLUGIN, &args_tok);
1036 if (cmd_header == "config")
1037 return update_info(info_ptr, CT_CONFIG, &args_tok);
1038 if (cmd_header == "gui")
1039 return update_info(info_ptr, CT_GUI, &args_tok);
1040
1041 // split composed commands into head and argument
1042 std::vector<token> toks;
1043 tokenizer(cmd_header).set_sep("()").set_ws("").bite_all(toks);
1044
1045 // check for name or type command
1046 if (toks.size() == 4 && toks[1] == "(" && toks[3] == ")" && (toks[0] == "name" || toks[0] == "type")) {
1047
1048 std::string identifier = to_string(toks[2]);
1049 if (info_ptr)
1050 info_ptr->parameters.push_back(toks[2]);
1051 return update_info(info_ptr, toks[0] == "name" ? CT_NAME : CT_TYPE, &args_tok);
1052 }
1053 return update_info(info_ptr, CT_UNKNOWN);
1054}
1055
1056bool process_command_ext(const command_info& info, bool* persistent, config_file_observer* cfo, const char* begin)
1057{
1058 switch (info.command_type) {
1059 case CT_SHOW:
1060 show_all();
1061 return true;
1062 case CT_PERSISTENT:
1063 if (persistent)
1064 *persistent = true;
1065 return true;
1066 case CT_INITIAL:
1067 if (persistent)
1068 *persistent = false;
1069 return true;
1070 case CT_PLUGIN: {
1071 if (load_plugin(to_string(info.parameters[0]))) {
1072 std::cout << "read plugin " << info.parameters[0] << std::endl;
1073 return true;
1074 }
1075 std::cerr << "error reading plugin " << info.parameters[0] << std::endl;
1076
1077 return false;
1078 }
1079 case CT_CONFIG:
1080 if (process_config_file_ext(to_string(info.parameters[0]), persistent)) {
1081 std::cout << "read config file " << get_config_file_name(to_string(info.parameters[0])) << std::endl;
1082 return true;
1083 }
1084 std::cerr << "error reading config file " << info.parameters[0] << std::endl;
1085 return false;
1086 case CT_GUI:
1087 if (process_gui_file(to_string(info.parameters[0]))) {
1088 std::cout << "read gui file " << info.parameters[0] << std::endl;
1089 return true;
1090 }
1091 std::cerr << "error reading gui file " << info.parameters[0] << std::endl;
1092 return false;
1093 case CT_NAME:
1094 case CT_TYPE: {
1095 base_ptr bp;
1096 if (info.command_type == CT_NAME) {
1097 named_ptr np = find_object_by_name(to_string(info.parameters[0]));
1098 if (np) {
1099 std::cout << "name(" << np->get_name().c_str() << ")";
1100 bp = np;
1101 }
1102 else
1103 std::cerr << "could not find object of name '" << info.parameters[0] << "'" << std::endl;
1104 }
1105 else {
1106 bp = find_object_by_type(to_string(info.parameters[0]));
1107 if (bp)
1108 std::cout << "type(" << bp->get_type_name() << ")";
1109 else
1110 std::cerr << "could not find object of type <" << info.parameters[0] << ">" << std::endl;
1111 }
1112 if (bp) {
1113 std::string args = to_string(info.parameters[1]);
1114 // replace single quotes by double quotes
1115 for (unsigned int x = 0; x < args.size(); ++x)
1116 if (args[x] == '\'')
1117 args[x] = '"';
1118
1119 show_split_lines(args);
1120 std::cout << "\n" << std::endl;
1121 if (persistent && *persistent && cfo)
1122 cfo->multi_observe(bp, args, info.parameters[1].begin - begin);
1123 else
1124 bp->multi_set(to_string(info.parameters[1]), true);
1125 return true;
1126 }
1127 return false;
1128 }
1129 }
1130 return false;
1131}
1132
1133/*
1134bool process_command_ext(const token& cmd, bool eliminate_quotes, bool* persistent, config_file_observer* cfo, const
1135char* begin)
1136{
1137 // remove unnecessary stuff
1138 token cmd_tok = cmd;
1139 cmd_tok.begin = skip_spaces(cmd_tok.begin, cmd_tok.end);
1140 cmd_tok.end = cutoff_spaces(cmd_tok.begin, cmd_tok.end);
1141
1142 // ignore empty lines and comments
1143 if (cmd_tok.empty() || cmd_tok[0] == '/')
1144 return true;
1145
1146 // interpret predefined commands
1147 if (cmd_tok == "show all") {
1148 show_all();
1149 return true;
1150 }
1151 if (cmd_tok == "persistent") {
1152 if (persistent)
1153 *persistent = true;
1154 return true;
1155 }
1156 if (cmd_tok == "initial") {
1157 if (persistent)
1158 *persistent = false;
1159 return true;
1160 }
1161
1162 // determine command header
1163 token cmd_header = tokenizer(cmd_tok).set_sep(":").set_ws("").set_skip("\"'","\"'").bite();
1164 if (cmd_header.end == cmd_tok.end) {
1165 std::cerr << "could not interpret command >" << to_string(cmd) << "< (probably missing a ':')!" << std::endl;
1166 return false;
1167 }
1168 // and command arguments
1169 token args_tok(cmd_header.end+1,cmd_tok.end);
1170
1171 // eliminate quotes around argument, which need to be used in commands specified on the command line
1172 if (eliminate_quotes && args_tok.get_length() >= 2 &&
1173 ( (args_tok[0] == '"' && args_tok[(int)args_tok.get_length()-1] == '"') ||
1174 (args_tok[0] == '\'' && args_tok[(int)args_tok.get_length()-1] == '\'') ) ) {
1175 ++args_tok.begin;
1176 --args_tok.end;
1177 }
1178 std::string args(to_string(args_tok));
1179
1180 // perform direct commands
1181 if (cmd_header == "plugin") {
1182 if (load_plugin(args)) {
1183 std::cout << "read plugin " << args << std::endl;
1184 return true;
1185 }
1186 else {
1187 std::cerr << "error reading plugin " << args << std::endl;
1188 return false;
1189 }
1190 }
1191 if (cmd_header == "config") {
1192 if (process_config_file_ext(args, persistent)) {
1193 std::cout << "read config file " << get_config_file_name(args) << std::endl;
1194 return true;
1195 }
1196 else {
1197 std::cerr << "error reading config file " << args << std::endl;
1198 return false;
1199 }
1200 }
1201 if (cmd_header == "gui") {
1202 if (process_gui_file(args)) {
1203 std::cout << "read gui file " << args << std::endl;
1204 return true;
1205 }
1206 else {
1207 std::cerr << "error reading gui file " << args << std::endl;
1208 return false;
1209 }
1210 }
1211
1212 // split composed commands into head and argument
1213 std::vector<token> toks;
1214 tokenizer(cmd_header).set_sep("()").set_ws("").bite_all(toks);
1215
1216 // check for name or type command
1217 if (toks.size() == 4 && toks[1] == "(" && toks[3] == ")" &&
1218 (toks[0]=="name" || toks[0]=="type") ) {
1219
1220
1221 // replace single quotes by double quotes
1222 for (unsigned int x=0; x<args.size(); ++x)
1223 if (args[x] == '\'')
1224 args[x] = '"';
1225
1226
1227 std::string identifier = to_string(toks[2]);
1228 if (toks[0]=="name") {
1229 named_ptr np = find_object_by_name(identifier);
1230 if (np) {
1231 std::cout << "name(" << np->get_name().c_str() << ")";
1232 show_split_lines(args);
1233 std::cout << "\n" << std::endl;
1234 if (persistent && *persistent && cfo)
1235 cfo->multi_observe(np, args, (unsigned)(args_tok.begin - begin));
1236 else
1237 np->multi_set(args, true);
1238 }
1239 else {
1240 std::cerr << "could not find object of name '" << identifier << "'" << std::endl;
1241 return false;
1242 }
1243 }
1244 else {
1245 base_ptr bp = find_object_by_type(identifier);
1246 if (bp) {
1247 std::cout << "type(" << bp->get_type_name() << ")";
1248 show_split_lines(args);
1249 std::cout << "\n" << std::endl;
1250 if (persistent && *persistent && cfo)
1251 cfo->multi_observe(bp, args, (unsigned)(args_tok.begin - begin));
1252 else
1253 bp->multi_set(args, true);
1254 }
1255 else {
1256 std::cerr << "could not find object of type <" << identifier << ">" << std::endl;
1257 return false;
1258 }
1259 }
1260 return true;
1261 }
1262 else {
1263 std::cerr << "could not interpret command >" << to_string(cmd) << "< !" << std::endl;
1264 return false;
1265 }
1266}
1267*/
1268
1270{
1271 return process_command_ext(info);
1272}
1273
1274bool process_command(const std::string& cmd, bool eliminate_quotes)
1275{
1276 command_info info;
1277 analyze_command(cmd, eliminate_quotes, &info);
1278 return process_command_ext(info);
1279 // return process_command_ext(token(cmd), eliminate_quotes);
1280}
1281
1284{
1286 for (int ai = 1; ai < argc; ++ai)
1287 process_command(argv[ai]);
1288}
1289
1291{
1292 const char* file_data = symbol + (int)symbol[0] + 9;
1293 std::string file_path(symbol + 1, (std::string::size_type)symbol[0]);
1294 symbol += symbol[0] + 1;
1295 unsigned int file_offset = (unsigned char)symbol[0];
1296 file_offset += ((unsigned int)(unsigned char)symbol[1] << 8);
1297 file_offset += ((unsigned int)(unsigned char)symbol[2] << 16);
1298 file_offset += ((unsigned int)(unsigned char)symbol[3] << 24);
1299 symbol += 4;
1300 unsigned int file_size = (unsigned char)symbol[0] + ((unsigned int)(unsigned char)symbol[1] << 8) +
1301 ((unsigned int)(unsigned char)symbol[2] << 16) +
1302 ((unsigned int)(unsigned char)symbol[3] << 24);
1303 std::string source_file = ref_plugin_name();
1304 if (source_file.empty())
1305 source_file = ref_prog_name();
1306 register_resource_file(file_path, file_offset, file_size, file_data, source_file);
1307}
1308
1313
1314std::string extend_plugin_name(const std::string& fn)
1315{
1316 std::string n = cgv::utils::file::drop_extension(fn);
1317#ifdef _WIN64
1318 n += "64";
1319#endif // _WIN64
1320
1321#if defined(_WIN32) || !defined(CGV_NDEBUG)
1322 n += "_";
1323#endif
1324#ifndef CGV_NDEBUG
1325 n += "d";
1326#endif
1327#ifdef _WIN32
1328#if defined(_MSC_VER) && _MSC_VER < 1500
1329 n += "8";
1330#elif defined(_MSC_VER) && _MSC_VER < 1600
1331 n += "9";
1332#elif defined(_MSC_VER) && _MSC_VER < 1700
1333 n += "10";
1334#elif defined(_MSC_VER) && _MSC_VER < 1800
1335 n += "11";
1336#elif defined(_MSC_VER) && _MSC_VER < 1900
1337 n += "12";
1338#elif defined(_MSC_VER) && _MSC_VER < 1910
1339 n += "14";
1340#elif defined(_MSC_VER) && _MSC_VER < 1920
1341 n += "141";
1342#elif defined(_MSC_VER) && _MSC_VER < 1930
1343 n += "142";
1344#elif defined(_MSC_VER)
1345 n += "143";
1346#endif
1347 n += ".dll";
1348#else
1349 n = std::string("lib") + n + ".so";
1350#endif
1351 return n;
1352}
1353
1354} // namespace base
1355} // namespace cgv
1356
1357#ifdef _WIN32
1358#include <windows.h>
1359#include <winbase.h>
1360#else
1361#include <unistd.h>
1362#include <dlfcn.h>
1363#endif
1364
1365namespace cgv {
1366namespace base {
1367
1368void* load_plugin_platform(const std::string& name)
1369{
1370#ifdef _WIN32
1371 SetLastError(0);
1372#ifdef _UNICODE
1373 return LoadLibrary(cgv::utils::str2wstr(name).c_str());
1374#else
1375 return LoadLibrary(name.c_str());
1376#endif
1377#else
1378 return dlopen(name.c_str(), RTLD_NOW);
1379#endif
1380}
1381
1382void record_error_platform(const std::string& dll_name, std::vector<std::string>& errors)
1383{
1384#ifdef _WIN32
1385 DWORD dw = GetLastError();
1386 LPVOID lpMsgBuf;
1387 FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS, nullptr,
1388 dw, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR)&lpMsgBuf, 0, nullptr);
1389 auto error = dll_name + ": " + std::string(static_cast<const char*>(lpMsgBuf));
1390 LocalFree(lpMsgBuf);
1391 errors.push_back(error);
1392#else
1393 auto errPtr = dlerror();
1394 auto error = std::string(errPtr) + "\n";
1395 errors.emplace_back(error);
1396#endif
1397}
1398
1399void* load_plugin(const std::string& file_name)
1400{
1401 std::vector<token> names;
1402 bite_all(tokenizer(file_name).set_ws(",|;"), names);
1403
1404 bool enabled = is_registration_enabled();
1405 if (enabled)
1407
1408 void* result = nullptr;
1409 std::vector<std::string> errors = {};
1410 for (auto& plugin_name : names) {
1411 std::string fn[2];
1412 fn[0] = to_string(plugin_name);
1413 fn[1] = extend_plugin_name(fn[0]);
1414#ifdef WIN32
1415 if (cgv::utils::to_lower(cgv::utils::file::get_extension(fn[0]) != "dll"))
1416 fn[0] += ".dll";
1417#elif __APPLE__
1418 if (cgv::utils::to_lower(cgv::utils::file::get_extension(fn[0]) != "dylib"))
1419 fn[0] = std::string("lib") + fn[0] + ".dylib";
1420#else
1421 if (cgv::utils::to_lower(cgv::utils::file::get_extension(fn[0]) != "so"))
1422 fn[0] = std::string("lib") + fn[0] + ".so";
1423#endif
1424#ifndef NDEBUG
1425 std::swap(fn[0], fn[1]);
1426#endif
1427
1428 result = nullptr;
1429 for (auto& dll_name : fn) {
1431 result = load_plugin_platform(dll_name);
1432 if (result) {
1433 break;
1434 }
1435
1436 record_error_platform(dll_name, errors);
1437 }
1438 }
1439
1440 if (enabled)
1442 ref_plugin_name().clear();
1443
1444 if (result == nullptr && !errors.empty()) {
1445 std::cerr << "failed to load plugin " << file_name << std::endl;
1446 for (const auto& err : errors) {
1447 std::cerr << " " << err;
1448 }
1449 }
1450
1451 return result;
1452}
1453
1454bool unload_plugin(void* handle)
1455{
1456#ifdef _WIN32
1457 return FreeLibrary((HMODULE)handle) != 0;
1458#else
1459 return dlclose(handle) != 0;
1460#endif
1461}
1462
1463} // namespace base
1464} // namespace cgv
More advanced text processing for splitting text into lines or tokens.
virtual bool end()
perform the leave part of the action on the current object
Definition action.cxx:48
T * get_interface()
use dynamic type cast to check for the given interface
Definition base.h:128
virtual data::ref_ptr< named, true > get_named()
perform downcast to named
Definition base.cxx:37
virtual std::string get_type_name() const
overload to return the type name of this object. By default the type interface is queried over get_ty...
Definition base.cxx:241
base class for all gui types
Definition named.h:20
complete implementation of method actions that only call one method when entering a node
Definition action.h:113
bool begin()
uses call_method of base class method_action to call the method refered to by the stored method point...
Definition action.h:122
structure used to register a test function
Definition register.h:369
std::string get_type_name() const
implementation of the type name function of the base class
Definition register.cxx:812
std::string get_test_name() const
access to name of test function
Definition register.cxx:800
bool exec_test() const
execute test and return whether this was successful
Definition register.cxx:805
test(const std::string &_test_name, bool(*_test_func)())
constructor for a test structure
Definition register.cxx:798
std::string test_name
name of test function
Definition register.h:375
static int nr_failed
static counter for all tests
Definition register.h:372
bool(* test_func)()
pointer to test function
Definition register.h:377
void clear()
set to null pointer
Definition ref_ptr.h:238
the tokenizer allows to split text into tokens in a convenient way.
Definition tokenizer.h:68
tokenizer & set_sep(const std::string &sep, bool merge)
set the list of separators and specify whether succeeding separators are merged into single tokens
Definition tokenizer.cxx:59
tokenizer & set_ws(const std::string &ws)
set the list of white spaces, that separate tokens and are skipped
Definition tokenizer.cxx:38
token bite()
bite away a single token from the front
tokenizer & set_skip(const std::string &open, const std::string &close)
set several character pairs that enclose tokens that are not split
Definition tokenizer.cxx:44
void register_object_internal(base_ptr object, const std::string &options)
register an object and send event to all current registration ref_listeners()
Definition register.cxx:214
unsigned get_nr_permanently_registered_objects()
access to number of permanently registered objects
Definition register.cxx:519
void unregister_all_objects()
unregister all existing objects to clean up
Definition register.cxx:508
bool process_command(const command_info &info)
process a command given by a command info structure, return whether command was processed correctly
std::string & ref_prog_path_prefix()
return a refence to the path prefix of the started executable, this can be prepended for example to d...
Definition register.cxx:131
void enable_permanent_registration()
register a registration listener that stores pointers to all registered objects
Definition register.cxx:498
data::ref_ptr< base, true > base_ptr
ref counted pointer to base
Definition base.h:37
void enable_registration_event_cleanup()
Enable cleanup of registration events (default).
Definition register.cxx:548
std::string & ref_plugin_name()
return a reference to the currently loaded plugin
Definition register.cxx:137
void disable_registration()
if registration is disable, all registration events are stored and sent at the momement when registra...
Definition register.cxx:480
base_ptr get_permanently_registered_object(unsigned i)
access to i-th permanently registered object
Definition register.cxx:525
void enable_registration_debugging()
enable registration debugging
Definition register.cxx:365
named_ptr find_object_by_name(const std::string &name)
in case permanent registration is active, look for a registered object by name
Definition register.cxx:654
bool is_registration_event_cleanup_enabled()
return whether registration cleanup is enabled
Definition register.cxx:575
CommandType analyze_command(const cgv::utils::token &cmd, bool eliminate_quotes, command_info *info_ptr)
parse a command and optionally store result in the command info, returns the command type
Definition register.cxx:992
CommandType
enumerate type for all command types supported in configuration files
Definition register.h:470
bool is_registration_enabled()
check whether registration is enabled
Definition register.cxx:493
void register_config_file_driver(config_file_driver *cfd)
method to register a config_file_driver
Definition register.cxx:687
void register_resource_file(const std::string &file_path, unsigned int file_offset, unsigned int file_length, const char *file_data, const std::string &source_file)
register a resource file
Definition register.cxx:930
void disable_permanent_registration()
deregister registration listener and dereference pointers to registered objects
Definition register.cxx:532
bool request_exit_from_all_objects()
calls the on_exit_request method for all registered objects and return true if exiting is allowed
Definition register.cxx:513
bool is_registration_debugging_enabled()
check whether registration debugging is enabled
Definition register.cxx:376
void register_prog_name(const char *_prog_name)
set the file name of the current program.
Definition register.cxx:915
void show_all()
show information about all registered members
Definition register.cxx:954
void unregister_object(base_ptr object, const std::string &options)
unregister an object and send event to all current registration ref_listeners()
Definition register.cxx:617
void enable_registration()
enable registration and send all registration events that where emitted during disabled registration
Definition register.cxx:381
void disable_registration_debugging()
disable registration debugging
Definition register.cxx:370
void process_command_line_args(int argc, char **argv)
process the command line arguments: extract program name and load all plugins
std::map< std::string, resource_file_info > & ref_resource_file_map()
return a reference to a mapping of resource file names to resource file infos
Definition register.cxx:143
data::ref_ptr< named, true > named_ptr
ref counted pointer to a node
Definition named.h:13
bool process_gui_file(const std::string &file_name)
interpret a gui file
Definition register.cxx:789
void * load_plugin(const std::string &file_name)
load a plugin or dll and return a handle to the plugin, or 0 if loading was not successful.
void register_resource_string(const std::string &string_name, const char *string_data)
register a resource string
Definition register.cxx:936
void register_object(base_ptr object, const std::string &options)
register an object and send event to all current registration ref_listeners()
Definition register.cxx:581
std::string & ref_prog_name()
return a refence to the name of the started executable
Definition register.cxx:125
void define_registration_order(const std::string &partial_order, bool before_contructor_execution, const std::string &when)
specify a partial order of objects for registration
Definition register.cxx:247
base_ptr find_object_by_type(const std::string &type_name)
in case permanent registration is active, look for a registered object by type name
Definition register.cxx:660
bool is_permanent_registration_enabled()
check whether permanent registration is enabled
Definition register.cxx:543
void disable_registration_event_cleanup()
disable cleanup of registration events (see enable_registration_event_cleanup).
Definition register.cxx:565
bool process_config_file(const std::string &_file_name)
interpret a config file
Definition register.cxx:783
bool unload_plugin(void *handle)
unload the plugin with the given handle
namespace that holds tools that dont fit any other namespace
std::string to_string(const std::string &v, unsigned int w, unsigned int p, bool)
specialization of conversion from string to strings
void split_to_lines(const char *global_begin, const char *global_end, std::vector< line > &lines, bool truncate_trailing_spaces)
this function splits a text range at the newline characters into single lines.
char to_lower(char c)
convert char to lower case
Definition scan.cxx:39
void bite_all(tokenizer &t, std::vector< token > &result)
bite all tokens into a token vector
Definition tokenizer.h:121
char to_upper(char c)
convert char to upper case
Definition scan.cxx:106
std::wstring str2wstr(const std::string &s)
convert a 8-bit string to a 16-bit string
Definition convert.cxx:11
const char * cutoff_spaces(const char *begin, const char *end)
return new end pointer by cutting off spaces at the end
Definition scan.cxx:690
const char * skip_spaces(const char *begin, const char *end)
return new start pointer by skipping spaces at begin
Definition scan.cxx:683
the cgv namespace
Definition print.h:11
a structure to store an analized command
Definition register.h:486
abstract interface for a config file driver that handles permanent registration and gui config files.
Definition register.h:555
virtual config_file_observer * find_config_file_observer(const std::string &file_name, const std::string &content)=0
create or find a config_file_observer from the given file name and the read content of the config fil...
interfaces that add several listeners and objects.
Definition register.h:210
bool set_void(const std::string &property, const std::string &value_type, const void *value_ptr)
abstract interface for the setter of a dynamic property.
Definition register.cxx:841
base_ptr singleton
pointer to the single object created by the factory in case is_singleton is true
Definition register.h:234
bool is_singleton
store whether the factory can only create one object
Definition register.h:232
std::string object_options
store the options used for registering newly created objects
Definition register.h:236
base_ptr create_object()
overload to create an object
Definition register.cxx:888
std::string created_type_name
store the type name of the to be created objects
Definition register.h:230
bool is_singleton_factory() const
return whether the factory can only generate one instance of the given type
Definition register.cxx:871
std::string get_property_declarations()
support creation of object by setting create property to true
Definition register.cxx:835
virtual std::string get_object_options() const
return the options string used for object registration
Definition register.cxx:829
factory(const std::string &_created_type_name, bool _singleton=false, const std::string &_object_options="")
construct
Definition register.cxx:823
bool get_void(const std::string &property, const std::string &value_type, void *value_ptr)
abstract interface for the getter of a dynamic property.
Definition register.cxx:855
const std::string & get_created_type_name() const
overload to return the type name of the objects that the factory can create
Definition register.cxx:866
base_ptr get_singleton() const
return pointer to singleton
Definition register.cxx:877
void release_singleton()
release the singleton pointer
Definition register.cxx:882
virtual base_ptr create_object_impl()=0
overload to create an object
abstract base class of helpers to perform delayed registration and creation of objects in case that t...
Definition register.h:98
interfaces that allows to listen to registration events.
Definition register.h:218
information registered with each resource file
Definition register.h:418
resource_file_info(unsigned int _file_offset=0, unsigned int _file_length=0, const char *_file_data=0, const std::string &_source_file="")
construct resource file info
Definition register.cxx:924
resource_file_registration(const char *file_data)
builds a resource file info and registers it with the register_resource_file function
resource_string_registration(const std::string &string_name, const char *string_data)
builds a resource file info and registers it with the register_resource_file function
interfaces that add provides very basic functionality.
Definition register.h:203
test_registration(const std::string &_test_name, bool(*_test_func)())
the constructor creates a test structure and registeres the test
Definition register.cxx:817
a line in a text is simply represented as a token
representation of a token in a text by two pointers begin and end, that point to the first character ...
Definition token.h:18
bool empty() const
return whether the token is empty
Definition token.h:56
const char * begin
pointers that define the range of characters
Definition token.h:20