mirror of
https://github.com/Rockbox/rockbox.git
synced 2025-11-12 22:52:28 -05:00
This library allows events to be subscribed / recieved within a lua script
most events in rb are synchronous so flags are set and later checked by a
secondary thread to make them (semi?) asynchronous.
There are a few caveats to be aware of:
FIRST, The main lua state is halted till the lua callback(s) are finished
Yielding will not return control to your script from within a callback
Also, subsequent callbacks may be delayed by the code in your lua callback
SECOND, You must store the value returned from the event_register function
you might get away with it for a bit but gc will destroy your callback
eventually if you do not store the event
THIRD, You only get one cb per event type
["action", "button", "custom", "playback", "timer"]
(Re-registration of an event overwrites the previous one)
Usage:
possible events =["action", "button", "custom", "playback", "timer"]
local evX = rockev.register("event", cb_function, [timeout / flags])
cb_function([id] [, data]) ... end
rockev.suspend(["event"/nil][true/false]) passing nil affects all events
stops event from executing, any but the last event before
re-enabling will be lost, passing false, unregistering or re-registering
an event will clear the suspend
rockev.trigger("event", [true/false], [id])
sets an event to triggered,
NOTE!, CUSTOM_EVENT must be unset manually
id is only passed to callback by custom and playback events
rockev.unregister(evX)
Use unregister(evX) to remove an event
Unregistering is not necessary before script end, it will be
cleaned up on script exit
Change-Id: Iea12a5cc0c0295b955dcc1cdf2eec835ca7e354d
212 lines
6.6 KiB
Perl
Executable file
212 lines
6.6 KiB
Perl
Executable file
#!/usr/bin/env perl
|
|
############################################################################
|
|
# __________ __ ___.
|
|
# Open \______ \ ____ ____ | | _\_ |__ _______ ___
|
|
# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
|
|
# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
|
|
# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
|
|
# \/ \/ \/ \/ \/
|
|
# $Id$
|
|
#
|
|
# Copyright (C) 2019 by William Wilgus
|
|
#
|
|
# All files in this archive are subject to the GNU General Public License.
|
|
# See the file COPYING in the source tree root for full license agreement.
|
|
#
|
|
# This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
|
|
# KIND, either express or implied.
|
|
#
|
|
############################################################################
|
|
|
|
#rockbox to lua define generator, add names of constants to the array to include
|
|
|
|
my @rockbox_defines = (
|
|
'^HZ$',
|
|
'^LCD_(DEPTH|HEIGHT|WIDTH)$',
|
|
'^MODEL_NAME$',
|
|
'^SCREEN_MAIN$',
|
|
'^LCD_DEFAULT_(FG|BG)$',
|
|
'^LCD_REMOTE_(DEPTH|HEIGHT|WIDTH)$',
|
|
'^LCD_.+(BRIGHT|DARK)COLOR',
|
|
'^SCREEN_REMOTE$',
|
|
'^FONT_SYSFIXED$',
|
|
'^FONT_UI$',
|
|
'^PLAYBACK_EVENT_.*',
|
|
'^PLAYLIST_(INSERT|PREPEND|REPLACE)',
|
|
'^TOUCHSCREEN_(POINT|BUTTON)$',
|
|
'^SYS_CHARGER_(DIS|)CONNECTED$',
|
|
'^SYS_(TIMEOUT|POWEROFF)$',
|
|
'^SYS_USB_(DIS|)CONNECTED$',
|
|
'^HOME_DIR$',
|
|
'^PLUGIN_DIR$',
|
|
'^PLUGIN(_APPS_|_GAMES_|_)DATA_DIR$',
|
|
'^ROCKBOX_DIR$',
|
|
'^VIEWERS_DATA_DIR$');
|
|
|
|
my @captured_defines;
|
|
my @names_seen;
|
|
my @all_defines;
|
|
|
|
############# precompile regex for speed #############
|
|
my $def_regex = qr/#define\s+([^\s\r\n]+)\s+([^\r\n]+)/;
|
|
my $quot_regex = qr/.*([\"\']).*/;
|
|
my $num_regex = qr/.*([\+\-\*\\|&\d]).*/;
|
|
my $configh_regex = qr/^\s*#define\s*__CONFIG_H__\s*$/;
|
|
my $config_h = "?";
|
|
my $exclude_regex = qr/^#define\s*_?POSIX.*/;
|
|
my $exclude_enum_regex = qr/^#define\s*(_SC_|_PC_|_CS_).*/;
|
|
print <<EOF
|
|
#include <stdio.h>
|
|
#include <stdbool.h>
|
|
|
|
#define stringify(s) #s
|
|
|
|
/* auto generated defines */
|
|
|
|
|
|
EOF
|
|
;
|
|
|
|
while(my $line = <STDIN>)
|
|
{
|
|
if($config_h eq "?" && $line =~ $configh_regex) { $config_h = $line; }
|
|
next if($config_h eq "?"); #don't capture till we get to the config file
|
|
next if($line =~ $exclude_regex);
|
|
|
|
if($line =~ $def_regex) #does it begin with #define?
|
|
{
|
|
push(@all_defines, $line); #save all defines for possible ambiguous macros
|
|
$name = $1;
|
|
next if $name =~ /^(ATTRIBUTE_|print|__).*/; #don't add reserved
|
|
$value = $2;
|
|
|
|
if(grep($name =~ $_, @rockbox_defines))
|
|
{
|
|
push(@names_seen, $name);
|
|
push(@captured_defines, {'name' => $name, 'value' => $value});
|
|
print $line
|
|
}
|
|
else
|
|
{
|
|
$name =~ s{(\(.*\))}{}gx; #remove (...) on function type macros
|
|
#ifndef guard so we don't clash with the host
|
|
printf "#ifndef %s\n%s#endif\n\n", $name, $line;
|
|
}
|
|
}
|
|
elsif($line =~ /^(?!.*;)enum.*{/) #enum {
|
|
{
|
|
next if($line =~ /enum\s*__.*/); #don't add reserved
|
|
print $line;
|
|
next if($line =~ /.*};.*/);
|
|
do_enum($line)
|
|
}
|
|
elsif($line =~ /^(?!.*[;\(\)])enum.*/) #enum
|
|
{
|
|
next if($line =~ /enum\s*__.*/); #don't add reserved
|
|
#need to be careful might be a function returning enum
|
|
my $lastline = $line;
|
|
next if($line =~ /.*};.*/);
|
|
($line = <STDIN>);
|
|
if($line =~ /.*{.*/)
|
|
{
|
|
print $lastline;
|
|
print $line;
|
|
}
|
|
else { next; }
|
|
do_enum($line)
|
|
}
|
|
|
|
}
|
|
#warn "total defines: ".scalar @all_defines;
|
|
#warn "captured defines: ".scalar @captured_defines;
|
|
#Sort the functions
|
|
my @sorted_defines = sort { @$a{'name'} cmp @$b{'name'} } @captured_defines;
|
|
|
|
printf "int main(void)\n{\n";
|
|
printf "\tprintf(\"--[[Autogenerated rockbox constants]]\\n\\n\");";
|
|
# Print the C array
|
|
foreach my $define (@sorted_defines)
|
|
{
|
|
if(@$define{'value'} =~ /^0[xX][0-9a-fA-F]+$/) #hex number
|
|
{
|
|
printf "\tprintf(\"rb[\\\"%%s\\\"] = 0x%%x\\n\", stringify(%s), %s);\n", @$define{'name'}, @$define{'name'};
|
|
}
|
|
elsif(@$define{'value'} =~ /^[0-9]+$/) #number
|
|
{
|
|
printf "\tprintf(\"rb[\\\"%%s\\\"] = %%d\\n\", stringify(%s), %s);\n", @$define{'name'}, @$define{'name'};
|
|
}
|
|
else #might be a string but we don't know since the macro isn't expanded far enough
|
|
{
|
|
my $max_depth = 10;
|
|
my $var = @$define{'value'};
|
|
while($max_depth > 0) #follow the chain of #defines until we can see what type
|
|
{
|
|
$max_depth--;
|
|
$var = "\\\s*#define\\s+$var\\s+.*";
|
|
#warn $var;
|
|
if(my ($x) = grep($_ =~ /($var)/, @all_defines)) #check all the defines
|
|
{
|
|
#warn $x;
|
|
if($x =~ $def_regex)
|
|
{
|
|
$var = $2;
|
|
#warn $var;
|
|
last if ($var =~ $quot_regex);
|
|
last if ($var =~ $num_regex);
|
|
next
|
|
}
|
|
#warn "end ".$var;
|
|
last
|
|
}
|
|
else
|
|
{
|
|
$var = @$define{'value'};
|
|
last
|
|
}
|
|
}
|
|
if ($var =~$quot_regex) #has a quote it is a string
|
|
{
|
|
#guard with empty literals "" so gcc throws an error if it isn't a string
|
|
printf "\tprintf(\"rb[\\\"%%s\\\"] = \\\"%%s\\\"\\n\", stringify(%s), \"\" %s \"\");\n", @$define{'name'}, @$define{'name'};
|
|
}
|
|
elsif ($var =~$num_regex) #it must be a number
|
|
{
|
|
printf "\tprintf(\"rb[\\\"%%s\\\"] = %%d\\n\", stringify(%s), %s);\n", @$define{'name'}, @$define{'name'};
|
|
}
|
|
else { warn "Skipping ".@$define{'name'}." indeterminate macro type\n"; }
|
|
}
|
|
}
|
|
|
|
print <<EOF
|
|
return 0;
|
|
}
|
|
|
|
EOF
|
|
;
|
|
|
|
sub do_enum {
|
|
my ($line) = @_;
|
|
|
|
while($line = <STDIN>)
|
|
{
|
|
next if($line =~ $exclude_enum_regex);
|
|
if($line =~ /.*};.*/)
|
|
{
|
|
print $line;
|
|
last
|
|
}
|
|
elsif($line =~ /([^\s,\t]+)\s*=?.*,?/)
|
|
{
|
|
$name = $1;
|
|
#printf "%s WHATTT?", $name;
|
|
$value = "0"; #enums are always integers
|
|
}
|
|
print $line;
|
|
if(grep($name =~ $_, @rockbox_defines))
|
|
{
|
|
push(@names_seen, $name);
|
|
push(@captured_defines, {'name' => $name, 'value' => $value});
|
|
}
|
|
|
|
}
|
|
}
|