line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
package Cog::Base; |
2
|
2
|
|
|
2
|
|
1023
|
use Mo; |
|
2
|
|
|
|
|
3
|
|
|
2
|
|
|
|
|
12
|
|
3
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
# System singleton object pointers. |
5
|
|
|
|
|
|
|
my $app; |
6
|
|
|
|
|
|
|
my $config; |
7
|
|
|
|
|
|
|
my $maker; |
8
|
|
|
|
|
|
|
my $runner; |
9
|
|
|
|
|
|
|
my $webapp; |
10
|
|
|
|
|
|
|
my $json; |
11
|
|
|
|
|
|
|
|
12
|
|
|
|
|
|
|
# The config reference must be initialized at startup. |
13
|
|
|
|
|
|
|
$Cog::Base::initialize = sub { |
14
|
|
|
|
|
|
|
$app ||= $_[0]; |
15
|
|
|
|
|
|
|
$config ||= $_[1]; |
16
|
|
|
|
|
|
|
}; |
17
|
|
|
|
|
|
|
|
18
|
|
|
|
|
|
|
# The accessors to common singleton objects are kept in single file |
19
|
|
|
|
|
|
|
# scoped lexicals, so that every Cog::Base subclass can access them |
20
|
|
|
|
|
|
|
# without needing to store them in their objects. This keeps things |
21
|
|
|
|
|
|
|
# clean and fast, and avoids needless circular refs. |
22
|
|
|
|
|
|
|
my $singleton = sub { |
23
|
|
|
|
|
|
|
my ($type) = @_; |
24
|
|
|
|
|
|
|
my $method = lc($type) . "_class"; |
25
|
|
|
|
|
|
|
my $class = $app->$method |
26
|
|
|
|
|
|
|
or die "Can't determine class for '$type'"; |
27
|
|
|
|
|
|
|
unless (UNIVERSAL::isa($class, 'Cog::Base')) { |
28
|
|
|
|
|
|
|
eval "require $class; 1" or die $@; |
29
|
|
|
|
|
|
|
} |
30
|
|
|
|
|
|
|
return $class->new(); |
31
|
|
|
|
|
|
|
}; |
32
|
|
|
|
|
|
|
|
33
|
0
|
|
|
0
|
0
|
|
sub app { $app } |
34
|
0
|
|
|
0
|
0
|
|
sub config { $config } |
35
|
0
|
0
|
|
0
|
0
|
|
sub maker { $maker || ($maker = $singleton->('Maker')) } |
36
|
0
|
0
|
|
0
|
0
|
|
sub runner { $runner || ($runner = $singleton->('Runner')) } |
37
|
0
|
0
|
|
0
|
0
|
|
sub webapp { $webapp || ($webapp = $singleton->('WebApp')) } |
38
|
|
|
|
|
|
|
|
39
|
|
|
|
|
|
|
# Cog plugins need to know their distribution name. This name is used to |
40
|
|
|
|
|
|
|
# locate shared files using File::ShareDir and other methods. |
41
|
|
|
|
|
|
|
# |
42
|
|
|
|
|
|
|
# This method will figure out the correct dist name most of the time. |
43
|
|
|
|
|
|
|
# Otherwise the class can hardcode it like this: |
44
|
|
|
|
|
|
|
# |
45
|
|
|
|
|
|
|
# package Foo::Bar; |
46
|
|
|
|
|
|
|
# use constant DISTNAME => 'Foo-X'; |
47
|
|
|
|
|
|
|
sub DISTNAME { |
48
|
0
|
|
|
0
|
0
|
|
my $class = shift; |
49
|
0
|
|
|
|
|
|
my $module = $class; |
50
|
0
|
|
|
|
|
|
while (1) { |
51
|
2
|
|
|
2
|
|
681
|
no strict 'refs'; |
|
2
|
|
|
|
|
2
|
|
|
2
|
|
|
|
|
389
|
|
52
|
0
|
0
|
|
|
|
|
last if ${"${module}::VERSION"}; |
|
0
|
|
|
|
|
|
|
53
|
0
|
|
|
|
|
|
eval "require $module"; |
54
|
0
|
0
|
|
|
|
|
last if ${"${module}::VERSION"}; |
|
0
|
|
|
|
|
|
|
55
|
0
|
0
|
|
|
|
|
$module =~ s/(.*)::.*/$1/ |
56
|
|
|
|
|
|
|
or die "Can't determine DISTNAME for $class"; |
57
|
|
|
|
|
|
|
} |
58
|
0
|
|
|
|
|
|
my $dist = $module; |
59
|
0
|
|
|
|
|
|
$dist =~ s/::/-/g; |
60
|
0
|
|
|
|
|
|
return $dist; |
61
|
|
|
|
|
|
|
} |
62
|
|
|
|
|
|
|
|
63
|
|
|
|
|
|
|
# Access to a set up JSON object |
64
|
|
|
|
|
|
|
sub json { |
65
|
0
|
|
0
|
0
|
0
|
|
$json ||= do { |
66
|
0
|
|
|
|
|
|
require JSON; |
67
|
0
|
|
|
|
|
|
my $j = JSON->new; |
68
|
0
|
|
|
|
|
|
$j->allow_blessed; |
69
|
0
|
|
|
|
|
|
$j->convert_blessed; |
70
|
0
|
|
|
|
|
|
$j; |
71
|
|
|
|
|
|
|
}; |
72
|
0
|
|
|
|
|
|
return $json; |
73
|
|
|
|
|
|
|
} |
74
|
|
|
|
|
|
|
|
75
|
|
|
|
|
|
|
1; |