File Coverage

blib/lib/App/Asciio/Setup.pm
Criterion Covered Total %
statement 10 12 83.3
branch n/a
condition n/a
subroutine 4 4 100.0
pod n/a
total 14 16 87.5


line stmt bran cond sub pod time code
1              
2             package App::Asciio ;
3              
4             $|++ ;
5              
6 1     1   4 use strict;
  1         2  
  1         31  
7 1     1   4 use warnings;
  1         2  
  1         25  
8              
9 1     1   4 use Data::TreeDumper ;
  1         1  
  1         57  
10 1     1   257 use Eval::Context ;
  0            
  0            
11             use Carp ;
12             use Module::Util qw(find_installed) ;
13             use File::Basename ;
14              
15             #------------------------------------------------------------------------------------------------------
16              
17             sub setup
18             {
19             my($self, $setup_ini_files) = @_ ;
20              
21             for my $setup_file (@{$setup_ini_files})
22             {
23             print "Initializing with '$setup_file'\n" if $self->{DISPLAY_SETUP_INFORMATION};
24            
25             unless(-e $setup_file)
26             {
27             croak "Can't find setup data '$setup_file'\n" ;
28             }
29            
30             push @{$self->{SETUP_PATHS}}, $setup_file ;
31            
32             my ($setup_name, $setup_path, $setup_ext) = File::Basename::fileparse($setup_file, ('\..*')) ;
33            
34             my $ini_files ;
35              
36             {
37             my $context = new Eval::Context() ;
38             $ini_files = $context->eval
39             (
40             PRE_CODE => "use strict;\nuse warnings;\n",
41             CODE_FROM_FILE => $setup_file,
42             ) ;
43              
44             die "can't load '$setup_file': $! $@\n" if $@ ;
45             }
46            
47             $self->setup_stencils($setup_path, $ini_files->{STENCILS} || []) ;
48             $self->setup_hooks($setup_path, $ini_files->{HOOK_FILES} || []) ;
49             $self->setup_action_handlers($setup_path, $ini_files->{ACTION_FILES} || []) ;
50             $self->setup_import_export_handlers($setup_path, $ini_files->{IMPORT_EXPORT} || []) ;
51             $self->setup_object_options($setup_path, $ini_files->{ASCIIO_OBJECT_SETUP} || []) ;
52             }
53             }
54              
55             #------------------------------------------------------------------------------------------------------
56              
57             sub setup_stencils
58             {
59             my($self, $setup_path, $stencils) = @_ ;
60              
61             for my $stencil (@{$stencils})
62             {
63             if(-e "$setup_path/$stencil")
64             {
65             if(-f "$setup_path/$stencil")
66             {
67             print "loading stencil '$setup_path$stencil'\n" if $self->{DISPLAY_SETUP_INFORMATION} ;
68             $self->load_elements("$setup_path/$stencil", $stencil) ;
69             }
70             elsif(-d "$setup_path/$stencil")
71             {
72             for(glob("$setup_path/$stencil/*"))
73             {
74             print "batch loading stencil '$setup_path/$stencil/$_'\n" if $self->{DISPLAY_SETUP_INFORMATION} ;
75             $self->load_elements($_, $stencil) ;
76             }
77             }
78             else
79             {
80             print "Unknown type '$setup_path/$stencil'!\n" ;
81             }
82             }
83             else
84             {
85             print "Can't find '$setup_path/$stencil'!\n" ;
86             }
87             }
88             }
89              
90             #------------------------------------------------------------------------------------------------------
91              
92             my Readonly $CATEGORY = 0 ;
93             my Readonly $SHORTCUTS = 0 ;
94             my Readonly $CODE = 1 ;
95             my Readonly $ARGUMENTS = 2 ;
96             my Readonly $CONTEXT_MENUE_SUB = 3;
97             my Readonly $CONTEXT_MENUE_ARGUMENTS = 4 ;
98             my Readonly $NAME= 5 ;
99             my Readonly $ORIGIN= 6 ;
100              
101             sub setup_hooks
102             {
103             my($self, $setup_path, $hook_files) = @_ ;
104              
105             for my $hook_file (@{ $hook_files })
106             {
107             my $context = new Eval::Context() ;
108              
109             my @hooks ;
110            
111             $context->eval
112             (
113             REMOVE_PACKAGE_AFTER_EVAL => 0, # VERY IMPORTANT as we return code references that will cease to exist otherwise
114             INSTALL_SUBS => {register_hooks => sub{@hooks = @_}},
115             PRE_CODE => "use strict;\nuse warnings;\n",
116             CODE_FROM_FILE => "$setup_path/$hook_file" ,
117             ) ;
118              
119             die "can't load hook file '$hook_file ': $! $@\n" if $@ ;
120            
121             for my $hook (@hooks)
122             {
123             $self->{HOOKS}{$hook->[$CATEGORY]} = $hook->[$CODE] ;
124             }
125             }
126             }
127              
128             #------------------------------------------------------------------------------------------------------
129              
130             sub setup_action_handlers
131             {
132             my($self, $setup_path, $action_files) = @_ ;
133              
134             for my $action_file (@{ $action_files })
135             {
136             #~ print "setup_action_handlers: loading '$action_file'\n" ;
137            
138             my $context = new Eval::Context() ;
139              
140             #~ print "loading action '$setup_path$action_file'\n" ;
141            
142             my %action_handlers;
143             $context->eval
144             (
145             REMOVE_PACKAGE_AFTER_EVAL => 0, # VERY IMPORTANT as we return code references that will cease to exist otherwise
146             INSTALL_SUBS => {register_action_handlers => sub{%action_handlers = @_}},
147             PRE_CODE => "use strict;\nuse warnings;\n",
148             CODE_FROM_FILE => "$setup_path/$action_file",
149             ) ;
150              
151             die "can't load setup file '$action_file': $! $@\n" if $@ ;
152              
153             for my $name (keys %action_handlers)
154             {
155             my $action_handler ;
156             my $group_name ;
157            
158             my $shortcuts_definition ;
159             if('HASH' eq ref $action_handlers{$name})
160             {
161             $shortcuts_definition = $action_handlers{$name}{SHORTCUTS} ;
162             $action_handlers{$name}{GROUP_NAME} = $group_name = $name ;
163             $action_handlers{$name}{ORIGIN} = $action_file;
164            
165             $action_handler = $self->get_group_action_handler($action_handlers{$name}, $action_file) ;
166             }
167             elsif('ARRAY' eq ref $action_handlers{$name})
168             {
169             $shortcuts_definition= $action_handlers{$name}[$SHORTCUTS] ;
170             $action_handlers{$name}[$NAME] = $name ;
171             $action_handlers{$name}[$ORIGIN] = $action_file ;
172            
173             $action_handler = $action_handlers{$name} ;
174             }
175             else
176             {
177             #~ print "ignoring '$name'\n" ;
178             next ;
179             }
180            
181             $self->{ACTIONS_BY_NAME}{$name} = $action_handlers{$name} ;
182            
183             my $shortcuts ;
184             if('ARRAY' eq ref $shortcuts_definition)
185             {
186             $shortcuts = $shortcuts_definition ;
187             }
188             else
189             {
190             $shortcuts = [$shortcuts_definition] ;
191             }
192            
193             for my $shortcut (@$shortcuts)
194             {
195             if(exists $self->{ACTIONS}{$shortcut})
196             {
197             print "Overriding shortcut '$shortcut'!\n" ;
198             print "\tnew is '$name' defined in file '$action_file'\n" ;
199             print "\told was '$self->{ACTIONS}{$shortcut}[5]' defined in file '$self->{ACTIONS}{$shortcut}[6]'\n" ;
200             }
201            
202             $self->{ACTIONS}{$shortcut} = $action_handler ;
203            
204             if(defined $group_name)
205             {
206             $self->{ACTIONS}{$shortcut}{GROUP_NAME} = $group_name ;
207             $self->{ACTIONS}{$shortcut}{ORIGIN} = $action_file;
208             }
209             }
210             }
211             }
212             }
213              
214             sub get_group_action_handler
215             {
216             my ($self, $action_handler_definition, $action_file) = @_ ;
217              
218             my %handler ;
219              
220             for my $name (keys %{$action_handler_definition})
221             {
222             my $action_handler ;
223             my $group_name ;
224            
225             my $shortcuts_definition ;
226             if('SHORTCUTS' eq $name)
227             {
228             #~ print "Found shortcuts definition.\n" ;
229             next ;
230             }
231             elsif('HASH' eq ref $action_handler_definition->{$name})
232             {
233             $shortcuts_definition= $action_handler_definition->{$name}{SHORTCUTS} ;
234             $action_handler_definition->{$name}{GROUP_NAME} = $group_name = $name ;
235             $action_handler_definition->{$name}{ORIGIN} = $action_file ;
236            
237             $action_handler = $self->get_group_action_handler($action_handler_definition->{$name}, $action_file) ;
238             }
239             elsif('ARRAY' eq ref $action_handler_definition->{$name})
240             {
241             $shortcuts_definition= $action_handler_definition->{$name}[$SHORTCUTS] ;
242             $action_handler_definition->{$name}[$NAME] = $name ;
243             $action_handler_definition->{$name}[$ORIGIN] = $action_file ;
244            
245             $action_handler = $action_handler_definition->{$name} ;
246             }
247             else
248             {
249             #~ print "ignoring '$name'\n" ;
250             next ;
251             }
252            
253             my $shortcuts ;
254             if('ARRAY' eq ref $shortcuts_definition)
255             {
256             $shortcuts = $shortcuts_definition ;
257             }
258             else
259             {
260             $shortcuts = [$shortcuts_definition] ;
261             }
262            
263             for my $shortcut (@$shortcuts)
264             {
265             if(exists $handler{$shortcut})
266             {
267             print "Overriding action group '$shortcut' with definition from file'$action_file'!\n" ;
268             }
269            
270             $handler{$shortcut} = $action_handler ;
271            
272             if(defined $group_name)
273             {
274             $handler{$shortcut}{GROUP_NAME} = $group_name ;
275             }
276             }
277             }
278            
279             return \%handler ;
280             }
281              
282             #------------------------------------------------------------------------------------------------------
283              
284             sub setup_import_export_handlers
285             {
286             my($self, $setup_path, $import_export_files) = @_ ;
287              
288             for my $import_export_file (@{ $import_export_files })
289             {
290             my $context = new Eval::Context() ;
291              
292             my %import_export_handlers ;
293             $context->eval
294             (
295             REMOVE_PACKAGE_AFTER_EVAL => 0, # VERY IMPORTANT as we return code references that will cease to exist otherwise
296             INSTALL_SUBS => {register_import_export_handlers => sub{%import_export_handlers = @_}},
297             PRE_CODE => <<EOC ,
298             use strict;
299             use warnings;
300            
301             EOC
302             CODE_FROM_FILE => "$setup_path/$import_export_file",
303             ) ;
304            
305             die "can't load import/export handler defintion file '$import_export_file': $! $@\n" if $@ ;
306              
307             for my $extension (keys %import_export_handlers)
308             {
309             if(exists $self->{IMPORT_EXPORT_HANDLERS}{$extension})
310             {
311             print "Overriding import/export handler for extension '$extension'!\n" ;
312             }
313            
314             $self->{IMPORT_EXPORT_HANDLERS}{$extension} = $import_export_handlers{$extension} ;
315             }
316             }
317             }
318              
319             #------------------------------------------------------------------------------------------------------
320              
321             sub setup_object_options
322             {
323             my($self, $setup_path, $options_files) = @_ ;
324              
325             for my $options_file (@{ $options_files })
326             {
327             my $context = new Eval::Context() ;
328              
329             my %options =
330             $context->eval
331             (
332             PRE_CODE => "use strict;\nuse warnings;\n",
333             CODE_FROM_FILE => "$setup_path/$options_file",
334             ) ;
335            
336             for my $option_name (keys %options)
337             {
338             $self->{$option_name} = $options{$option_name} ;
339             }
340            
341             die "can't load setup file '$options_file': $! $@\n" if $@ ;
342             }
343            
344             $self->event_options_changed() ;
345             }
346              
347             #------------------------------------------------------------------------------------------------------
348              
349             sub run_script
350             {
351             my($self, $script) = @_ ;
352              
353             if(defined $script)
354             {
355             my $context = new Eval::Context() ;
356              
357             $context->eval
358             (
359             PRE_CODE => "use strict;\nuse warnings;\n",
360             CODE_FROM_FILE => $script,
361             INSTALL_VARIABLES =>
362             [ 
363             [ '$self' => $self => $Eval::Context::SHARED ],
364             ] ,
365             ) ;
366            
367             die "can't load setup file '$script': $! $@\n" if $@ ;
368             }
369             }
370              
371             #------------------------------------------------------------------------------------------------------
372              
373             1 ;
374              
375