-
Notifications
You must be signed in to change notification settings - Fork 1
/
precache.pm
109 lines (95 loc) · 3.03 KB
/
precache.pm
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# Gmusicbrowser: Copyright (C) 2005-2015 Quentin Sculo <squentin@free.fr>
# Precache plugin: Copyright (C) 2015 Justas Lavišius <bucaneer@gmail.com>
#
# This file is part of Gmusicbrowser.
# Gmusicbrowser is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License version 3, as
# published by the Free Software Foundation
=gmbplugin PRECACHE
name Cache next song
title Cache next song
desc Caches next song in the playlist into virtual memory.
req exec(/vmtouch)
=cut
package GMB::Plugin::PRECACHE;
use strict;
use utf8;
use warnings;
use POSIX ':sys_wait_h';
use constant
{ OPT => 'PLUGIN_PRECACHE_',
};
::SetDefaultOptions(OPT, 'cachesize'=>5, 'usepage'=>1, 'cmd'=>'vmtouch', 'args'=>'-qlt');
my $watcher;
my $curfile;
my $pid;
my $pagemode;
my @deathlist;
sub precache
{ return if $curfile && $::NextFileToPlay && $::NextFileToPlay eq $curfile;
$curfile = $::NextFileToPlay;
kill_pid();
return unless $curfile;
my $size = $::Options{OPT.'cachesize'};
my @cmd = split(/ /, $::Options{OPT.'cmd'});
push @cmd, ("-p", "${size}M") if $pagemode && $::Options{OPT.'usepage'};
push @cmd, (split(/ /, $::Options{OPT.'args'}), $curfile);
$pid=fork;
if ($pid==0)
{ exec @cmd or print STDERR "PRECACHE: couldn't exec: $!\n";
}
print "PRECACHE: Cached $size MB of $curfile\n" if $::debug;
}
sub check_pagemode
{ for (qx($::Options{OPT.'cmd'} 2>&1))
{ if (m/^vmtouch v(\d+)\.(\d+).(\d+)/ &&
($1 > 1 || ($1 == 1 && $2 > 0) || ($1 == 1 && $2 == 0 && $3 >= 1)))
{ return 1;
}
}
return 0;
}
sub kill_wait
{ waitpid(-1,WNOHANG);
@deathlist = grep kill(0,$_), @deathlist;
return 0 unless @deathlist;
kill 'KILL' => @deathlist;
}
sub kill_pid
{ return unless $pid;
kill 'INT', $pid;
push @deathlist, $pid;
Glib::Timeout->add(100, \&kill_wait);
undef $pid;
}
sub Start
{ $watcher = {};
$pagemode = check_pagemode();
::Watch($watcher,'NextSongs', \&precache);
::Watch($watcher, 'Quit', \&kill_pid);
}
sub Stop
{ ::UnWatch($watcher,'NextSongs');
::UnWatch($watcher, 'Quit');
kill_pid();
}
sub prefbox {
my $sg1=Gtk2::SizeGroup->new('horizontal');
my $sg2=Gtk2::SizeGroup->new('horizontal');
my $vbox=Gtk2::VBox->new;
my $cmd = ::NewPrefEntry(OPT.'cmd',_"vmtouch executable:", sizeg1=> $sg1, sizeg2=>$sg2);
my $args = ::NewPrefEntry(OPT.'args',_"vmtouch options:", sizeg1=> $sg1, sizeg2=>$sg2);
my $vbox_page=Gtk2::VBox->new;
my $spin_size = ::NewPrefSpinButton(OPT.'cachesize',1,500, step=>1, page=>5, text=>_"Cache size (MB): ", sizeg1=> $sg1);
my ($radio_full, $radio_page) = ::NewPrefRadio(OPT.'usepage',
[_"Cache entire file" => 0, _"Cache start of file (recommended)" => 1],
cb=>sub{$spin_size->set_sensitive($::Options{OPT.'usepage'})});
$radio_page->set_tooltip_text(_"Requires vmtouch v1.0.1 or newer");
$spin_size->set_sensitive($::Options{OPT.'usepage'});
$vbox_page->pack_start($_,::FALSE,::FALSE,2) for $radio_page, $spin_size;
$vbox_page->set_sensitive($pagemode);
$vbox->pack_start($_,::FALSE,::FALSE,2)
for $cmd, $args, Gtk2::HSeparator->new, $radio_full, $vbox_page;
return $vbox;
}
1