diff --git a/control/eventMacros.txt b/control/eventMacros.txt new file mode 100644 index 0000000000..b093399330 --- /dev/null +++ b/control/eventMacros.txt @@ -0,0 +1,45 @@ + +automacro test_slot1 { + exclusive 1 + InMap prontera + disabled 0 + overrideAI 1 + slot 1 + call { + log This is working in slot 1 start + pause 1 + do c hey + pause 1.5 + log This is working in slot 1 end + } +} + +automacro test_slot2 { + exclusive 1 + InMap prontera + disabled 0 + overrideAI 1 + slot 2 + call { + log This is working in slot 2 start + pause 1.5 + do c there + pause 1 + log This is working in slot 2 end + } +} + +automacro test_slot3 { + exclusive 1 + InMap prontera + disabled 0 + overrideAI 1 + slot 3 + call { + log This is working in slot 3 start + pause 2 + do c man + pause 0.5 + log This is working in slot 3 end + } +} \ No newline at end of file diff --git a/plugins/eventMacro/README.md b/plugins/eventMacro/README.md index e80f329006..f83a71f967 100644 --- a/plugins/eventMacro/README.md +++ b/plugins/eventMacro/README.md @@ -5,6 +5,5 @@ TODO: 1 - Create more conditions, at least the same number as the old macro plugin had. 2 - Hook AI only when we are sure an automacro is to be activated. -3 - Make slot system for automacros and macros, so in each slot a macro can be run and a group of automacros can be checked (so multiple macros can be run at the same time). -4 - Transfer macro code check to parsing time. -5 - Review macro condition code parsing (old Parser.pm and Script.pm) +3 - Transfer macro code check to parsing time. +4 - Review macro condition code parsing (old Parser.pm and Script.pm) diff --git a/plugins/eventMacro/eventMacro.pl b/plugins/eventMacro/eventMacro.pl index 399e87dd19..e332faccab 100644 --- a/plugins/eventMacro/eventMacro.pl +++ b/plugins/eventMacro/eventMacro.pl @@ -113,10 +113,10 @@ sub commandHandler { "eventMacro auto AUTOMACRO: Get info on an automacro and it's conditions\n". "eventMacro list: Lists available macros and automacros\n". "eventMacro status [macro|automacro]: Shows current status of automacro, macro or both\n". - "eventMacro check [force_stop|force_start|resume]: Sets the state of automacros checking\n". - "eventMacro stop: Stops current running macro\n". - "eventMacro pause: Pauses current running macro\n". - "eventMacro unpause: Unpauses current running macro\n". + "eventMacro check [force_stop|force_start|resume] [slot]: Sets the state of automacros checking\n". + "eventMacro stop [slot]: Stops current running macro\n". + "eventMacro pause [slot]: Pauses current running macro\n". + "eventMacro unpause [slot]: Unpauses current running macro\n". "eventMacro var_get: Shows the value of one or all variables\n". "eventMacro var_set: Set the value of a variable\n". "eventMacro enable [automacro]: Enable one or all automacros\n". @@ -196,157 +196,222 @@ sub commandHandler { message "[eventMacro] '".$params[0]."' is not a valid option\n"; return; } - if (!defined $params[0] || $params[0] eq 'macro') { - my $macro = $eventMacro->{Macro_Runner}; - if ( $macro ) { - message( "There's a macro currently running\n", "list" ); - message( sprintf( "Paused: %s\n", $macro->is_paused ? "yes" : "no" ) ); - - my $macro_tree_message = "Macro tree: '".$macro->get_name."'"; - my $submacro = $macro; - while (defined $submacro->{subcall}) { - $submacro = $submacro->{subcall}; - $macro_tree_message .= " --> '".$submacro->get_name."'"; + + my $show_automacro = (!defined $params[0] || $params[0] eq 'automacro') ? 1 : 0; + my $show_macro = (!defined $params[0] || $params[0] eq 'macro') ? 1 : 0; + + foreach my $slot (sort keys %{$eventMacro->{Automacro_Checking_slots}}) { + message( center( " Slot ".$slot." ", 30, '-' ) . "\n", 'list' ); + + if ($show_automacro) { + message( center( " Automacro ", 20, '-' ) . "\n", 'list' ); + my $status = $eventMacro->get_automacro_checking_status($slot); + if ($status == CHECKING_AUTOMACROS) { + message "- Automacros are being checked normally.\n"; + } elsif ($status == PAUSED_BY_EXCLUSIVE_MACRO) { + message "- Automacros are not being checked because there's an uninterruptible macro running ('".$eventMacro->{Macro_Runner}{$slot}->last_subcall_name."').\n"; + } elsif ($status == PAUSE_FORCED_BY_USER) { + message "- Automacros checking is stopped because the user forced it.\n"; + } else { + message "- Automacros checking is active because the user forced it.\n"; } - $macro_tree_message .= ".\n"; - message( $macro_tree_message, "list" ); - - while () { - message( center( " Macro ", 25, '-' ) . "\n", 'list' ); - message( sprintf( "Macro name: %s\n", $macro->get_name ), "list" ); - message( sprintf( "overrideAI: %s\n", $macro->overrideAI ), "list" ); - message( sprintf( "interruptible: %s\n", $macro->interruptible ), "list" ); - message( sprintf( "orphan method: %s\n", $macro->orphan ), "list" ); - message( sprintf( "remaining repeats: %s\n", $macro->repeat ), "list" ); - message( sprintf( "macro delay: %s\n", $macro->macro_delay ), "list" ); - - message( sprintf( "current command: %s\n", $macro->{current_line} ), "list" ); + message "\n"; + } + + if ($show_macro) { + message( center( " Macro ", 20, '-' ) . "\n", 'list' ); + if (!exists $eventMacro->{Macro_Runner}{$slot}) { + message( "- There's no macro currently running.\n", "list" ); - my $time_until_next_command = (($macro->timeout->{time} + $macro->timeout->{timeout}) - time); - message( sprintf( "time until next command: %s\n", $macro->macro_delay ), "list" ) if ($time_until_next_command > 0); + } else { + my $macro = $eventMacro->{Macro_Runner}{$slot}; - message "\n"; + my $macro_tree_message = "- Macro tree: '".$macro->get_name."'"; + my $submacro = $macro; + while (defined $submacro->{subcall}) { + $submacro = $submacro->{subcall}; + $macro_tree_message .= " --> '".$submacro->get_name."'"; + } + $macro_tree_message .= ".\n"; + message( $macro_tree_message, "list" ); - last if (!defined $macro->{subcall}); - $macro = $macro->{subcall}; + while () { + message( sprintf( "- Macro name: %s\n", $macro->get_name ), "list" ); + message( sprintf( "- Paused: %s\n", $macro->is_paused ? "yes" : "no" ) ); + message( sprintf( "- overrideAI: %s\n", $macro->overrideAI ), "list" ); + message( sprintf( "- interruptible: %s\n", $macro->interruptible ), "list" ); + message( sprintf( "- orphan method: %s\n", $macro->orphan ), "list" ); + message( sprintf( "- remaining repeats: %s\n", $macro->repeat ), "list" ); + message( sprintf( "- slot: %s\n", $macro->slot ), "list" ); + message( sprintf( "- macro delay: %s\n", $macro->macro_delay ), "list" ); + + message( sprintf( "- current command: %s\n", $macro->{current_line} ), "list" ); + + my $time_until_next_command = (($macro->timeout->{time} + $macro->timeout->{timeout}) - time); + message( sprintf( "- time until next command: %s\n", $time_until_next_command ), "list" ) if ($time_until_next_command > 0); + + message "\n"; + + last if (!defined $macro->{subcall}); + $macro = $macro->{subcall}; + } } - } else { - message "There's no macro currently running.\n"; - } - } - if (!defined $params[0] || $params[0] eq 'automacro') { - my $status = $eventMacro->get_automacro_checking_status(); - if ($status == CHECKING_AUTOMACROS) { - message "Automacros are being checked normally.\n"; - } elsif ($status == PAUSED_BY_EXCLUSIVE_MACRO) { - message "Automacros are not being checked because there's an uninterruptible macro running ('".$eventMacro->{Macro_Runner}->last_subcall_name."').\n"; - } elsif ($status == PAUSE_FORCED_BY_USER) { - message "Automacros checking is stopped because the user forced it.\n"; - } else { - message "Automacros checking is active because the user forced it.\n"; + message "\n"; } } ### parameter: check } elsif ($arg eq 'check') { if (!defined $params[0] || (defined $params[0] && $params[0] ne 'force_stop' && $params[0] ne 'force_start' && $params[0] ne 'resume')) { - message "usage: eventMacro check [force_stop|force_start|resume]\n", "list"; - message - "eventMacro check force_stop: forces the stop of automacros checking\n". - "eventMacro check force_start: forces the start of automacros checking\n". - "eventMacro check resume: return automacros checking to the normal state\n"; + message "usage: eventMacro check [force_stop|force_start|resume] [slot]\n", "list"; + message + "eventMacro check force_stop [slot]: forces the stop of automacros checking [in a certain slot].\n". + "eventMacro check force_start [slot]: forces the start of automacros checking [in a certain slot].\n". + "eventMacro check resume [slot]: return automacros checking to the normal state [in a certain slot].\n"; return; } - my $status = $eventMacro->get_automacro_checking_status(); - debug "[eventMacro] Command 'check' used with parameter '".$params[0]."'.\n", "eventMacro", 2; - debug "[eventMacro] Previous checking status '".$status."'.\n", "eventMacro", 2; - if ($params[0] eq 'force_stop') { - if ($status == CHECKING_AUTOMACROS) { - message "[eventMacro] Automacros checking forcely stopped.\n"; - $eventMacro->set_automacro_checking_status(PAUSE_FORCED_BY_USER); - } elsif ($status == PAUSED_BY_EXCLUSIVE_MACRO) { - message "[eventMacro] Automacros were not being checked because there's an uninterruptible macro running ('".$eventMacro->{Macro_Runner}->last_subcall_name."').". - "Now they will be forcely stopped even after macro ends (caution).\n"; - $eventMacro->set_automacro_checking_status(PAUSE_FORCED_BY_USER); - } elsif ($status == PAUSE_FORCED_BY_USER) { - message "[eventMacro] Automacros checking is already forcely stopped.\n"; - } else { - message "[eventMacro] Automacros checking is forcely active, now it will be forcely stopped.\n"; - $eventMacro->set_automacro_checking_status(PAUSE_FORCED_BY_USER); + + my $new_status = $params[0]; + + if (defined $params[1]) { + my $slot = $params[1]; + + if ($slot !~ /^\d+$/) { + message "[eventMacro] '".$slot."' is not a valid option\n"; + return; } - } elsif ($params[0] eq 'force_start') { - if ($status == CHECKING_AUTOMACROS) { - message "[eventMacro] Automacros are already being checked, now it will be forcely kept this way.\n"; - $eventMacro->set_automacro_checking_status(CHECKING_FORCED_BY_USER); - } elsif ($status == PAUSED_BY_EXCLUSIVE_MACRO) { - message "[eventMacro] Automacros were not being checked because there's an uninterruptible macro running ('".$eventMacro->{Macro_Runner}->last_subcall_name."').". - "Now automacros checking will be forcely activated (caution).\n"; - $eventMacro->set_automacro_checking_status(CHECKING_FORCED_BY_USER); - } elsif ($status == PAUSE_FORCED_BY_USER) { - message "[eventMacro] Automacros checking is forcely stopped, now it will be forcely activated.\n"; - $eventMacro->set_automacro_checking_status(CHECKING_FORCED_BY_USER); - } else { - message "[eventMacro] Automacros checking is already forcely active.\n"; + if (!exists $eventMacro->{Automacros_Checking_Status}{$slot}) { + message "[eventMacro] Slot '".$slot."' does not exist\n"; + return; } + + debug "[eventMacro] Command 'check' used with parameter '".$new_status."' and slot ".$slot.".\n", "eventMacro", 2; + + check_command_enforce($new_status, $slot); + } else { - if ($status == CHECKING_AUTOMACROS || $status == PAUSED_BY_EXCLUSIVE_MACRO) { - message "[eventMacro] Automacros checking is not forced by the user to be able to resume.\n"; - } else { - if (!defined $eventMacro->{Macro_Runner}) { - message "[eventMacro] Since there's no macro in execution automacros will resume to being normally checked.\n"; - $eventMacro->set_automacro_checking_status(CHECKING_AUTOMACROS); - } elsif ($eventMacro->{Macro_Runner}->last_subcall_interruptible == 1) { - message "[eventMacro] Since there's a macro in execution, and it is interruptible, automacros will resume to being normally checked.\n"; - $eventMacro->set_automacro_checking_status(CHECKING_AUTOMACROS); - } elsif ($eventMacro->{Macro_Runner}->last_subcall_interruptible == 0) { - message "[eventMacro] Since there's a macro in execution ('".$eventMacro->{Macro_Runner}->last_subcall_name."') , and it is not interruptible, automacros won't resume to being checked until it ends.\n"; - $eventMacro->set_automacro_checking_status(PAUSED_BY_EXCLUSIVE_MACRO); - } + debug "[eventMacro] Command 'check' used with parameter '".$new_status."' and no slot defined.\n", "eventMacro", 2; + foreach my $slot (sort keys %{$eventMacro->{Automacro_Checking_slots}}) { + check_command_enforce($new_status, $slot); } } ### parameter: stop } elsif ($arg eq 'stop') { - my $macro = $eventMacro->{Macro_Runner}; - if ( $macro ) { - message "Stopping macro '".$eventMacro->{Macro_Runner}->last_subcall_name."'.\n"; - $eventMacro->clear_queue(); + + if (defined $params[0]) { + if ($params[0] !~ /\d+/) { + message "[eventMacro] '".$params[0]."' is not a valid option\n"; + return; + } + + my $slot = $params[0]; + + if (!exists $eventMacro->{Automacro_Checking_slots}{$slot}) { + message "[eventMacro] Slot '".$params[0]."' does not exist.\n"; + return; + } + + if (!exists $eventMacro->{Macro_Runner}{$slot}) { + message "[eventMacro] There's no macro currently running in slot '".$params[0]."'.\n"; + return; + } + + my $macro = $eventMacro->{Macro_Runner}{$slot}; + message "[eventMacro] Stopping macro '".$macro->last_subcall_name."'.\n"; + $eventMacro->clear_queue($slot); + } else { - message "There's no macro currently running.\n"; + foreach my $slot (keys %{$eventMacro->{Macro_Runner}}) { + my $macro = $eventMacro->{Macro_Runner}{$slot}; + message "[eventMacro] Stopping macro '".$macro->last_subcall_name."'.\n"; + $eventMacro->clear_queue($slot); + } } ### parameter: pause } elsif ($arg eq 'pause') { - my $macro = $eventMacro->{Macro_Runner}; - if ( $macro ) { + + if (defined $params[0]) { + if ($params[0] !~ /\d+/) { + message "[eventMacro] '".$params[0]."' is not a valid option\n"; + return; + } + + my $slot = $params[0]; + + if (!exists $eventMacro->{Automacro_Checking_slots}{$slot}) { + message "[eventMacro] Slot '".$params[0]."' does not exist.\n"; + return; + } + + if (!exists $eventMacro->{Macro_Runner}{$slot}) { + message "[eventMacro] There's no macro currently running in slot '".$params[0]."'.\n"; + return; + } + + my $macro = $eventMacro->{Macro_Runner}{$slot}; + if ($macro->is_paused()) { - message "Macro '".$eventMacro->{Macro_Runner}->last_subcall_name."' is already paused.\n"; - } else { - message "Pausing macro '".$eventMacro->{Macro_Runner}->last_subcall_name."'.\n"; - $eventMacro->{Macro_Runner}->pause(); + message "[eventMacro] Macro '".$macro->last_subcall_name."' is already paused.\n"; + return; } + + message "[eventMacro] Pausing macro '".$macro->last_subcall_name."'.\n"; + $macro->pause(); + } else { - message "There's no macro currently running.\n"; + foreach my $slot (keys %{$eventMacro->{Macro_Runner}}) { + my $macro = $eventMacro->{Macro_Runner}{$slot}; + next if ($macro->is_paused()); + message "[eventMacro] Pausing macro '".$macro->last_subcall_name."'.\n"; + $macro->pause(); + } } ### parameter: unpause } elsif ($arg eq 'unpause') { - my $macro = $eventMacro->{Macro_Runner}; - if ( $macro ) { - if ($macro->is_paused()) { - message "Unpausing macro '".$eventMacro->{Macro_Runner}->last_subcall_name."'.\n"; - $eventMacro->{Macro_Runner}->unpause(); - } else { - message "Macro '".$eventMacro->{Macro_Runner}->last_subcall_name."' is not paused.\n"; + + if (defined $params[0]) { + if ($params[0] !~ /\d+/) { + message "[eventMacro] '".$params[0]."' is not a valid option\n"; + return; } + + my $slot = $params[0]; + + if (!exists $eventMacro->{Automacro_Checking_slots}{$slot}) { + message "[eventMacro] Slot '".$params[0]."' does not exist.\n"; + return; + } + + if (!exists $eventMacro->{Macro_Runner}{$slot}) { + message "[eventMacro] There's no macro currently running in slot '".$params[0]."'.\n"; + return; + } + + my $macro = $eventMacro->{Macro_Runner}{$slot}; + + unless ($macro->is_paused()) { + message "[eventMacro] Macro '".$macro->last_subcall_name."' is not paused.\n"; + return; + } + + message "[eventMacro] Unpausing macro '".$macro->last_subcall_name."'.\n"; + $macro->unpause(); + } else { - message "There's no macro currently running.\n"; + foreach my $slot (keys %{$eventMacro->{Macro_Runner}}) { + my $macro = $eventMacro->{Macro_Runner}{$slot}; + next unless ($macro->is_paused()); + message "[eventMacro] Unpausing macro '".$macro->last_subcall_name."'.\n"; + $macro->unpause(); + } } - ### parameter: var_get } elsif ($arg eq 'var_get') { if (!defined $params[0]) { @@ -578,18 +643,24 @@ sub commandHandler { ### if nothing triggered until here it's probably a macro name } elsif ( !$eventMacro->{Macro_List}->getByName( $arg ) ) { error "[eventMacro] Macro $arg not found\n"; - } elsif ( $eventMacro->{Macro_Runner} ) { - warning "[eventMacro] A macro is already running. Wait until the macro has finished or call 'eventMacro stop'\n"; - return; + } else { my $opt = {}; - GetOptionsFromArray( \@params, $opt, 'repeat|r=i', 'overrideAI', 'exclusive', 'macro_delay=f', 'orphan=s' ); + GetOptionsFromArray( \@params, $opt, 'repeat|r=i', 'slot=i', 'overrideAI', 'exclusive', 'macro_delay=f', 'orphan=s' ); + + my $slot = defined $opt->{slot} ? $opt->{slot} : 1; + + if ( exists $eventMacro->{Macro_Runner}{$slot} ) { + warning "[eventMacro] A macro is already running in slot ".$slot.". Wait until the macro has finished or call 'eventMacro stop [".$slot."]'\n"; + return; + } $eventMacro->set_full_array( ".param", \@params ); - $eventMacro->{Macro_Runner} = new eventMacro::Runner( + $eventMacro->{Macro_Runner}{$slot} = new eventMacro::Runner( $arg, defined $opt->{repeat} ? $opt->{repeat} : 1, + $slot, defined $opt->{exclusive} ? $opt->{exclusive} ? 0 : 1 : undef, defined $opt->{overrideAI} ? $opt->{overrideAI} : undef, defined $opt->{orphan} ? $opt->{orphan} : undef, @@ -597,11 +668,69 @@ sub commandHandler { defined $opt->{macro_delay} ? $opt->{macro_delay} : undef, 0 ); + + if (!defined $eventMacro->{Macro_Runner}{$slot}) { + error "[eventMacro] unable to create macro queue.\n"; + delete $eventMacro->{Macro_Runner}{$slot}; + return; + } + + if (keys %{$eventMacro->{Macro_Runner}} == 1) { + my $iterate_macro_sub = sub { $eventMacro->iterate_macro(); }; + $eventMacro->{AI_start_Macros_Running_Hook_Handle} = Plugins::addHook( 'AI_start', $iterate_macro_sub, undef ); + } + } +} - if ( defined $eventMacro->{Macro_Runner} ) { - $eventMacro->{AI_start_Macros_Running_Hook_Handle} = Plugins::addHook( 'AI_start', sub { $eventMacro->iterate_macro }, undef ); +sub check_command_enforce { + my ($new_status, $slot) = @_; + my $old_status = $eventMacro->get_automacro_checking_status($slot); + debug "[eventMacro] Previous slot ".$slot." checking status '".$old_status."'.\n", "eventMacro", 2; + + if ($new_status eq 'force_stop') { + if ($old_status == CHECKING_AUTOMACROS) { + message "[eventMacro] Slot ".$slot.": Automacros checking forcely stopped.\n"; + $eventMacro->set_automacro_checking_status($slot, PAUSE_FORCED_BY_USER); + } elsif ($old_status == PAUSED_BY_EXCLUSIVE_MACRO) { + message "[eventMacro] Slot ".$slot.": Automacros were not being checked because there's an uninterruptible macro running ('".$eventMacro->{Macro_Runner}{$slot}->last_subcall_name."').\n". + "Now they will be forcely stopped even after macro ends (caution).\n"; + $eventMacro->set_automacro_checking_status($slot, PAUSE_FORCED_BY_USER); + } elsif ($old_status == PAUSE_FORCED_BY_USER) { + message "[eventMacro] Slot ".$slot.": Automacros checking is already forcely stopped.\n"; } else { - error "[eventMacro] unable to create macro queue.\n"; + message "[eventMacro] Slot ".$slot.": Automacros checking is forcely active, now it will be forcely stopped.\n"; + $eventMacro->set_automacro_checking_status($slot, PAUSE_FORCED_BY_USER); + } + + } elsif ($new_status eq 'force_start') { + if ($old_status == CHECKING_AUTOMACROS) { + message "[eventMacro] Slot ".$slot.": Automacros are already being checked, now it will be forcely kept this way.\n"; + $eventMacro->set_automacro_checking_status($slot, CHECKING_FORCED_BY_USER); + } elsif ($old_status == PAUSED_BY_EXCLUSIVE_MACRO) { + message "[eventMacro] Slot ".$slot.": Automacros were not being checked because there's an uninterruptible macro running ('".$eventMacro->{Macro_Runner}{$slot}->last_subcall_name."').\n". + "Now automacros checking will be forcely activated (caution).\n"; + $eventMacro->set_automacro_checking_status($slot, CHECKING_FORCED_BY_USER); + } elsif ($old_status == PAUSE_FORCED_BY_USER) { + message "[eventMacro] Slot ".$slot.": Automacros checking is forcely stopped, now it will be forcely activated.\n"; + $eventMacro->set_automacro_checking_status($slot, CHECKING_FORCED_BY_USER); + } else { + message "[eventMacro] Slot ".$slot.": Automacros checking is already forcely active.\n"; + } + + } elsif ($new_status eq 'resume') { + if ($old_status == CHECKING_AUTOMACROS || $old_status == PAUSED_BY_EXCLUSIVE_MACRO) { + message "[eventMacro] Slot ".$slot.": Automacros checking is not forced by the user to be able to resume.\n"; + } else { + if (!exists $eventMacro->{Macro_Runner}{$slot}) { + message "[eventMacro] Slot ".$slot.": Since there's no macro in execution automacros will resume to being normally checked.\n"; + $eventMacro->set_automacro_checking_status($slot, CHECKING_AUTOMACROS); + } elsif ($eventMacro->{Macro_Runner}{$slot}->last_subcall_interruptible == 1) { + message "[eventMacro] Slot ".$slot.": Since there's a macro in execution, and it is interruptible, automacros will resume to being normally checked.\n"; + $eventMacro->set_automacro_checking_status($slot, CHECKING_AUTOMACROS); + } elsif ($eventMacro->{Macro_Runner}{$slot}->last_subcall_interruptible == 0) { + message "[eventMacro] Slot ".$slot.": Since there's a macro in execution ('".$eventMacro->{Macro_Runner}{$slot}->last_subcall_name."'), and it is not interruptible, automacros won't resume to being checked until it ends.\n"; + $eventMacro->set_automacro_checking_status($slot, PAUSED_BY_EXCLUSIVE_MACRO); + } } } } diff --git a/plugins/eventMacro/eventMacro/Automacro.pm b/plugins/eventMacro/eventMacro/Automacro.pm index ab7a6465c2..7eba0df3d4 100644 --- a/plugins/eventMacro/eventMacro/Automacro.pm +++ b/plugins/eventMacro/eventMacro/Automacro.pm @@ -132,6 +132,7 @@ sub set_parameters { if (!defined $self->{parameters}{'repeat'}) { $self->{parameters}{'repeat'} = 1; } + $self->{parameters}{'slot'} ||= 1; $self->{parameters}{time} = 0; } diff --git a/plugins/eventMacro/eventMacro/Core.pm b/plugins/eventMacro/eventMacro/Core.pm index 71c78f4749..dc4592a425 100644 --- a/plugins/eventMacro/eventMacro/Core.pm +++ b/plugins/eventMacro/eventMacro/Core.pm @@ -24,8 +24,8 @@ sub new { $self->{Macro_List} = new eventMacro::Lists; $self->{Automacro_List} = new eventMacro::Lists; + $self->{Condition_Modules_Loaded} = {}; - $self->{automacros_index_to_AI_check_state} = {}; $self->{Event_Related_Hooks} = {}; $self->{Hook_Handles} = {}; @@ -40,9 +40,6 @@ sub new { $self->{Array_Variable_List_Hash} = {}; $self->{Hash_Variable_List_Hash} = {}; - #must add a sorting algorithm here later - $self->{triggered_prioritized_automacros_index_list} = []; - $self->{automacro_index_to_queue_index} = {}; my $parse_result = parseMacroFile($file, 0); @@ -52,28 +49,40 @@ sub new { } $self->create_macro_list($parse_result->{macros}); + + $self->{Automacro_Checking_slots} = {}; $self->create_automacro_list($parse_result->{automacros}); $self->{subs_list} = $parse_result->{subs}; - - $self->define_automacro_check_state; $self->{AI_state_change_Hook_Handle} = Plugins::addHook( 'AI_state_change', sub { my $state = $_[1]->{new}; $self->adapt_to_AI_state($state); }, undef ); - $self->{Currently_AI_state_Adapted_Automacros} = undef; + $self->{automacros_index_to_AI_check_state} = {}; + $self->define_automacro_check_state; + #$self->{Currently_AI_state_Adapted_Automacros} = {}; $self->adapt_to_AI_state(AI::state); $self->{AI_start_Macros_Running_Hook_Handle} = undef; - $self->{AI_start_Automacros_Check_Hook_Handle} = undef; - $self->set_automacro_checking_status(); + + $self->{AI_start_Automacros_Check_Hook_Handle} = {}; + + $self->{Automacros_Checking_Status} = {}; + + foreach my $slot (keys %{$self->{Automacro_Checking_slots}}) { + + #must add a sorting algorithm here later + $self->{triggered_prioritized_automacros_index_list}{$slot} = []; + $self->{automacro_index_to_queue_index}{$slot} = {}; + + $self->{number_of_triggered_automacros}{$slot} = 0; + $self->set_automacro_checking_status($slot); + } $self->create_callbacks(); - $self->{Macro_Runner} = undef; - - $self->{number_of_triggered_automacros} = 0; + $self->{Macro_Runner} = {}; $self->set_arrays_size_to_zero(); $self->set_hashes_size_to_zero(); @@ -84,7 +93,7 @@ sub new { sub adapt_to_AI_state { my ($self, $state) = @_; - $self->{Currently_AI_state_Adapted_Automacros} = undef; + $self->{Currently_AI_state_Adapted_Automacros} = {}; foreach my $automacro (@{$self->{Automacro_List}->getItems()}) { my $automacro_index = $automacro->get_index; @@ -106,9 +115,17 @@ sub adapt_to_AI_state { sub unload { my ($self) = @_; - $self->clear_queue(); + + foreach my $slot (keys %{$self->{Macro_Runner}}) { + $self->clear_queue($slot); + } + $self->clean_hooks(); - Plugins::delHook($self->{AI_start_Automacros_Check_Hook_Handle}) if ($self->{AI_start_Automacros_Check_Hook_Handle}); + + foreach my $slot (keys %{$self->{AI_start_Automacros_Check_Hook_Handle}}) { + Plugins::delHook($self->{AI_start_Automacros_Check_Hook_Handle}{$slot}); + } + Plugins::delHook($self->{AI_state_change_Hook_Handle}) if ($self->{AI_state_change_Hook_Handle}); } @@ -118,46 +135,49 @@ sub clean_hooks { } sub set_automacro_checking_status { - my ($self, $status) = @_; + my ($self, $slot, $new_status) = @_; - if (!defined $self->{Automacros_Checking_Status}) { - debug "[eventMacro] Initializing automacro checking by default.\n", "eventMacro", 2; - $self->{Automacros_Checking_Status} = CHECKING_AUTOMACROS; - $self->{AI_start_Automacros_Check_Hook_Handle} = Plugins::addHook( 'AI_start', sub { my $state = $_[1]->{state}; $self->AI_start_checker($state); }, undef ); + if (!exists $self->{Automacros_Checking_Status}{$slot}) { + debug "[eventMacro] Initializing automacro checking by default in slot ".$slot.".\n", "eventMacro", 2; + $self->{Automacros_Checking_Status}{$slot} = CHECKING_AUTOMACROS; + $self->{AI_start_Automacros_Check_Hook_Handle}{$slot} = Plugins::addHook( 'AI_start', sub { my $state = $_[1]->{state}; $self->AI_start_checker($state, $slot); }, undef ); return; - } elsif ($self->{Automacros_Checking_Status} == $status) { - debug "[eventMacro] automacro checking status is already $status.\n", "eventMacro", 2; + } + + my $current_status = $self->{Automacros_Checking_Status}{$slot}; + + if ($current_status == $new_status) { + debug "[eventMacro] automacro checking status is already '".$new_status."' in slot ".$slot.".\n", "eventMacro", 2; + } else { - debug "[eventMacro] Changing automacro checking status from '".$self->{Automacros_Checking_Status}."' to '".$status."'.\n", "eventMacro", 2; - if ( - ($self->{Automacros_Checking_Status} == CHECKING_AUTOMACROS || $self->{Automacros_Checking_Status} == CHECKING_FORCED_BY_USER) && - ($status == PAUSED_BY_EXCLUSIVE_MACRO || $status == PAUSE_FORCED_BY_USER) - ) { - if (defined $self->{AI_start_Automacros_Check_Hook_Handle}) { - debug "[eventMacro] Deleting AI_start hook.\n", "eventMacro", 2; - Plugins::delHook($self->{AI_start_Automacros_Check_Hook_Handle}); - $self->{AI_start_Automacros_Check_Hook_Handle} = undef; + debug "[eventMacro] Changing automacro checking status from '".$current_status."' to '".$new_status."' in slot ".$slot.".\n", "eventMacro", 2; + + if (($current_status == CHECKING_AUTOMACROS || $current_status == CHECKING_FORCED_BY_USER) && ($new_status == PAUSED_BY_EXCLUSIVE_MACRO || $new_status == PAUSE_FORCED_BY_USER)) { + if (exists $self->{AI_start_Automacros_Check_Hook_Handle}{$slot}) { + debug "[eventMacro] Deleting AI_start hook in slot ".$slot.".\n", "eventMacro", 2; + Plugins::delHook($self->{AI_start_Automacros_Check_Hook_Handle}{$slot}); + delete $self->{AI_start_Automacros_Check_Hook_Handle}{$slot}; + } else { - error "[eventMacro] Tried to delete AI_start hook and for some reason it is already undefined.\n"; + error "[eventMacro] Tried to delete AI_start hook in slot ".$slot." and for some reason it is already undefined.\n"; } - } elsif ( - ($self->{Automacros_Checking_Status} == PAUSED_BY_EXCLUSIVE_MACRO || $self->{Automacros_Checking_Status} == PAUSE_FORCED_BY_USER) && - ($status == CHECKING_AUTOMACROS || $status == CHECKING_FORCED_BY_USER) - ) { - if (defined $self->{AI_start_Automacros_Check_Hook_Handle}) { - error "[eventMacro] Tried to add AI_start hook and for some reason it is already defined.\n"; + + } elsif (($current_status == PAUSED_BY_EXCLUSIVE_MACRO || $current_status == PAUSE_FORCED_BY_USER) && ($new_status == CHECKING_AUTOMACROS || $new_status == CHECKING_FORCED_BY_USER)) { + if (!exists $self->{AI_start_Automacros_Check_Hook_Handle}{$slot}) { + debug "[eventMacro] Adding AI_start hook in slot ".$slot.".\n", "eventMacro", 2; + $self->{AI_start_Automacros_Check_Hook_Handle}{$slot} = Plugins::addHook( 'AI_start', sub { my $state = $_[1]->{state}; $self->AI_start_checker($state, $slot); }, undef ); + } else { - debug "[eventMacro] Adding AI_start hook.\n", "eventMacro", 2; - $self->{AI_start_Automacros_Check_Hook_Handle} = Plugins::addHook( 'AI_start', sub { my $state = $_[1]->{state}; $self->AI_start_checker($state); }, undef ); + error "[eventMacro] Tried to add AI_start hook in slot ".$slot." and for some reason it is already defined.\n"; } } - $self->{Automacros_Checking_Status} = $status; + $self->{Automacros_Checking_Status}{$slot} = $new_status; } } sub get_automacro_checking_status { - my ($self) = @_; - return $self->{Automacros_Checking_Status}; + my ($self, $slot) = @_; + return $self->{Automacros_Checking_Status}{$slot}; } sub create_macro_list { @@ -289,6 +309,10 @@ sub create_automacro_list { } elsif ($parameter->{'key'} eq "repeat" && $parameter->{'value'} !~ /\d+/) { error "[eventMacro] Ignoring automacro '$name' (repeat parameter should be a number)\n"; next AUTOMACRO; + ###Parameter: slot + } elsif ($parameter->{'key'} eq "slot" && ($parameter->{'value'} !~ /^\d+$/ || $parameter->{'value'} == 0)) { + error "[eventMacro] Ignoring automacro '$name' (slot parameter should be a number 1 or bigger)\n"; + next AUTOMACRO; } else { $currentParameters{$parameter->{'key'}} = $parameter->{'value'}; } @@ -359,6 +383,7 @@ sub create_automacro_list { $currentAutomacro = new eventMacro::Automacro($name, \%currentParameters); my $new_index = $self->{Automacro_List}->add($currentAutomacro); $self->{Automacro_List}->get($new_index)->parse_and_create_conditions(\%currentConditions); + push(@{$self->{Automacro_Checking_slots}{$currentAutomacro->get_parameter('slot')}}, $new_index); } } @@ -1244,12 +1269,14 @@ sub manage_variables_callbacks { sub add_to_triggered_prioritized_automacros_index_list { my ($self, $automacro) = @_; + + my $slot = $automacro->get_parameter('slot'); my $priority = $automacro->get_parameter('priority'); my $index = $automacro->get_index; - my $list = $self->{triggered_prioritized_automacros_index_list} ||= []; + my $list = $self->{triggered_prioritized_automacros_index_list}{$slot}; - my $index_hash = $self->{automacro_index_to_queue_index}; + my $index_hash = $self->{automacro_index_to_queue_index}{$slot}; # Find where we should insert this item. my $new_index; @@ -1263,10 +1290,10 @@ sub add_to_triggered_prioritized_automacros_index_list { $index_hash->{$list->[$auto_index_in_queue]->{index}} = $auto_index_in_queue; } - $self->{number_of_triggered_automacros}++; + $self->{number_of_triggered_automacros}{$slot}++; $automacro->running_status(1); - debug "[eventMacro] Automacro '".$automacro->get_name()."' met it's conditions. Adding it to running queue in position '".$new_index."'.\n", "eventMacro"; + debug "[eventMacro] Automacro '".$automacro->get_name()."' met it's conditions. Adding it to running queue of slot ".$slot." in position '".$new_index."'.\n", "eventMacro"; # Return the insertion index. return $new_index; @@ -1274,12 +1301,14 @@ sub add_to_triggered_prioritized_automacros_index_list { sub remove_from_triggered_prioritized_automacros_index_list { my ($self, $automacro) = @_; + + my $slot = $automacro->get_parameter('slot'); my $priority = $automacro->get_parameter('priority'); my $index = $automacro->get_index; - my $list = $self->{triggered_prioritized_automacros_index_list}; + my $list = $self->{triggered_prioritized_automacros_index_list}{$slot}; - my $index_hash = $self->{automacro_index_to_queue_index}; + my $index_hash = $self->{automacro_index_to_queue_index}{$slot}; # Find from where we should delete this item. my $queue_index = delete $index_hash->{$index}; @@ -1292,10 +1321,10 @@ sub remove_from_triggered_prioritized_automacros_index_list { $index_hash->{$list->[$auto_index_in_queue]->{index}} = $auto_index_in_queue; } - $self->{number_of_triggered_automacros}--; + $self->{number_of_triggered_automacros}{$slot}--; $automacro->running_status(0); - debug "[eventMacro] Automacro '".$automacro->get_name()."' no longer meets it's conditions. Removing it from running queue from position '".$queue_index."'.\n", "eventMacro"; + debug "[eventMacro] Automacro '".$automacro->get_name()."' no longer meets it's conditions. Removing it from running queue of slot ".$slot." from position '".$queue_index."'.\n", "eventMacro"; # Return the removal index. return $queue_index; @@ -1339,12 +1368,13 @@ sub manage_event_callbacks { debug $debug_message."\n", "eventMacro", 2; - my ($event_type_automacro_call_index, $event_type_automacro_call_priority); + my %event_type_automacro_call; foreach my $automacro_index (keys %{$check_list_hash}) { my ($automacro, $conditions_indexes_hash, $check_event_type) = ($self->{Automacro_List}->get($automacro_index), $check_list_hash->{$automacro_index}, 0); + my $automacro_name = $automacro->get_name(); - debug "[eventMacro] Conditions of state type will be checked in automacro '".$automacro->get_name()."'.\n", "eventMacro", 2; + debug "[eventMacro] Conditions of state type will be checked in automacro '".$automacro_name."'.\n", "eventMacro", 2; my @conditions_indexes_array = keys %{ $conditions_indexes_hash }; @@ -1356,15 +1386,15 @@ sub manage_event_callbacks { $check_event_type = 1; next; } else { - debug "[eventMacro] Variable value will be updated in condition of state type in automacro '".$automacro->get_name()."'.\n", "eventMacro", 3 if ($callback_type eq 'variable'); + debug "[eventMacro] Variable value will be updated in condition of state type in automacro '".$automacro_name."'.\n", "eventMacro", 3 if ($callback_type eq 'variable'); my $result = $automacro->check_state_type_condition($condition_index, $callback_type, $callback_name, $callback_args); - #add to running queue + # Remove from running queue if (!$result && $automacro->running_status) { $self->remove_from_triggered_prioritized_automacros_index_list($automacro); - #remove from running queue + # Add to running queue } elsif ($result && exists $self->{Currently_AI_state_Adapted_Automacros}{$automacro_index} && $automacro->can_be_added_to_queue) { $self->add_to_triggered_prioritized_automacros_index_list($automacro); @@ -1374,28 +1404,35 @@ sub manage_event_callbacks { if ($check_event_type) { + my $automacro_slot = $automacro->get_parameter('slot'); + if ($callback_type eq 'variable') { - debug "[eventMacro] Variable value will be updated in condition of event type in automacro '".$automacro->get_name()."'.\n", "eventMacro", 3; + debug "[eventMacro] Variable value will be updated in condition of event type in automacro '".$automacro_name."'.\n", "eventMacro", 3; $automacro->check_event_type_condition($callback_type, $callback_name, $callback_args); - } elsif (exists $self->{Currently_AI_state_Adapted_Automacros}{$automacro_index} && ($self->get_automacro_checking_status == CHECKING_AUTOMACROS || $self->get_automacro_checking_status == CHECKING_FORCED_BY_USER) && $automacro->can_be_run_from_event) { - debug "[eventMacro] Condition of event type will be checked in automacro '".$automacro->get_name()."'.\n", "eventMacro", 3; + } elsif (exists $self->{Currently_AI_state_Adapted_Automacros}{$automacro_index} && ($self->get_automacro_checking_status($automacro_slot) == CHECKING_AUTOMACROS || $self->get_automacro_checking_status($automacro_slot) == CHECKING_FORCED_BY_USER) && $automacro->can_be_run_from_event) { + + my $automacro_priority = $automacro->get_parameter('priority'); + + debug "[eventMacro] Condition of event type will be checked in automacro '".$automacro_name."'.\n", "eventMacro", 3; if ($automacro->check_event_type_condition($callback_type, $callback_name, $callback_args)) { debug "[eventMacro] Condition of event type was fulfilled.\n", "eventMacro", 3; - if (!defined $event_type_automacro_call_priority) { - debug "[eventMacro] Automacro '".$automacro->get_name."' of priority '".$automacro->get_parameter('priority')."' was added to the top of queue.\n", "eventMacro", 3; - $event_type_automacro_call_index = $automacro_index; - $event_type_automacro_call_priority = $automacro->get_parameter('priority'); + if (!exists $event_type_automacro_call{$automacro_slot}) { + debug "[eventMacro] Automacro '".$automacro_name."' of priority '".$automacro_priority."' was added to the top of queue of slot ".$automacro_slot.".\n", "eventMacro", 3; + $event_type_automacro_call{$automacro_slot}{name} = $automacro_name; + $event_type_automacro_call{$automacro_slot}{index} = $automacro_index; + $event_type_automacro_call{$automacro_slot}{priority} = $automacro_priority; - } elsif ($event_type_automacro_call_priority >= $automacro->get_parameter('priority')) { - debug "[eventMacro] Automacro '".$automacro->get_name."' of priority '".$automacro->get_parameter('priority')."' was added to the top of queue and took place of automacro '".$self->{Automacro_List}->get($event_type_automacro_call_index)->get_name."' which has priority '".$event_type_automacro_call_priority."'.\n", "eventMacro", 3; - $event_type_automacro_call_index = $automacro_index; - $event_type_automacro_call_priority = $automacro->get_parameter('priority'); + } elsif ($event_type_automacro_call{$automacro_slot}{priority} >= $automacro_priority) { + debug "[eventMacro] Automacro '".$automacro_name."' of priority '".$automacro_priority."' was added to the top of queue of slot ".$automacro_slot." and took place of automacro '".$event_type_automacro_call{$automacro_slot}{name}."' which has priority '".$event_type_automacro_call{$automacro_slot}{priority}."'.\n", "eventMacro", 3; + $event_type_automacro_call{$automacro_slot}{name} = $automacro_name; + $event_type_automacro_call{$automacro_slot}{index} = $automacro_index; + $event_type_automacro_call{$automacro_slot}{priority} = $automacro_priority; } else { - debug "[eventMacro] Automacro '".$automacro->get_name()."' was not added to running queue because there already is a higher priority event only automacro in it (automacro '".$self->{Automacro_List}->get($event_type_automacro_call_index)->get_name."' which has priority '".$event_type_automacro_call_priority."').\n", "eventMacro", 3; + debug "[eventMacro] Automacro '".$automacro_name."' was not added to running queue of slot ".$automacro_slot." because there already is a higher priority event only automacro in it (automacro '".$event_type_automacro_call{$automacro_slot}{name}."' which has priority '".$event_type_automacro_call{$automacro_slot}{priority}."').\n", "eventMacro", 3; } @@ -1405,19 +1442,19 @@ sub manage_event_callbacks { } } else { - debug "[eventMacro] Condition of event type will not be checked in automacro '".$automacro->get_name()."' because it is not necessary.\n", "eventMacro", 3; + debug "[eventMacro] Condition of event type will not be checked in automacro '".$automacro_name."' because it is not necessary.\n", "eventMacro", 3; } } } - if (defined $event_type_automacro_call_index) { + foreach my $slot (keys %event_type_automacro_call) { - my $automacro = $self->{Automacro_List}->get($event_type_automacro_call_index); + my $automacro_call = $self->{Automacro_List}->get($event_type_automacro_call{$slot}{index}); - message "[eventMacro] Event of type '".$callback_type."', and of name '".$callback_name."' activated automacro '".$automacro->get_name()."', calling macro '".$automacro->get_parameter('call')."'\n", "system"; + message "[eventMacro] Event of type '".$callback_type."', and of name '".$callback_name."' activated automacro '".$event_type_automacro_call{$slot}{name}."', calling macro '".$automacro_call->get_parameter('call')."' on slot ".$slot.".\n", "system"; - $self->call_macro($automacro); + $self->call_macro($automacro_call); } } @@ -1469,14 +1506,14 @@ sub manage_dynamic_hook_add_and_delete { } sub AI_start_checker { - my ($self, $state) = @_; + my ($self, $state, $slot) = @_; - foreach my $array_member (@{$self->{triggered_prioritized_automacros_index_list}}) { + foreach my $array_member (@{$self->{triggered_prioritized_automacros_index_list}{$slot}}) { my $automacro = $self->{Automacro_List}->get($array_member->{index}); next unless $automacro->is_timed_out; - message "[eventMacro] Conditions met for automacro '".$automacro->get_name()."', calling macro '".$automacro->get_parameter('call')."'\n", "system"; + message "[eventMacro] Conditions met for automacro '".$automacro->get_name()."', calling macro '".$automacro->get_parameter('call')."' in slot ".$slot."\n", "system"; $self->call_macro($automacro); @@ -1516,9 +1553,6 @@ sub enable_automacro { sub call_macro { my ($self, $automacro) = @_; - if (defined $self->{Macro_Runner}) { - $self->clear_queue(); - } if ($automacro->get_parameter('call') =~ /\s+/) { @@ -1545,9 +1579,16 @@ sub call_macro { $self->set_scalar_var($variable_name, $variable_value, 0); } - $self->{Macro_Runner} = new eventMacro::Runner( + my $slot = $automacro->get_parameter('slot'); + + if (exists $self->{Macro_Runner}{$slot}) { + $self->clear_queue($slot); + } + + $self->{Macro_Runner}{$slot} = new eventMacro::Runner( $automacro->get_parameter('call'), $automacro->get_parameter('repeat'), + $slot, $automacro->get_parameter('exclusive') ? 0 : 1, $automacro->get_parameter('overrideAI'), $automacro->get_parameter('orphan'), @@ -1556,11 +1597,15 @@ sub call_macro { 0 ); - if (defined $self->{Macro_Runner}) { + if (!defined $self->{Macro_Runner}{$slot}) { + error "[eventMacro] unable to create macro queue.\n"; + delete $self->{Macro_Runner}{$slot}; + return; + } + + if (keys %{$self->{Macro_Runner}} == 1) { my $iterate_macro_sub = sub { $self->iterate_macro(); }; $self->{AI_start_Macros_Running_Hook_Handle} = Plugins::addHook( 'AI_start', $iterate_macro_sub, undef ); - } else { - error "[eventMacro] unable to create macro queue.\n" } } @@ -1568,54 +1613,78 @@ sub call_macro { sub iterate_macro { my $self = shift; - # These two cheks are actually not necessary, but they can prevent future code bugs. - if ( !defined $self->{Macro_Runner} ) { - debug "[eventMacro] For some reason the running macro object got undefined, clearing queue to prevent errors.\n", "eventMacro", 2; - $self->clear_queue(); - return; - } elsif ($self->{Macro_Runner}->finished) { - debug "[eventMacro] For some reason macro '".$self->{Macro_Runner}->get_name()."' finished but 'processCmd' did not clear it, clearing queue to prevent errors.\n", "eventMacro", 2; - $self->clear_queue(); - return; - } - - return if $self->{Macro_Runner}->is_paused(); - - my $macro_timeout = $self->{Macro_Runner}->timeout; + my @slots = sort(keys %{$self->{Macro_Runner}}); - if (timeOut($macro_timeout) && $self->ai_is_eventMacro) { - do { - last unless ( $self->processCmd( $self->{Macro_Runner}->next ) ); - } while ($self->{Macro_Runner} && !$self->{Macro_Runner}->is_paused() && $self->{Macro_Runner}->macro_block); + foreach my $slot (@slots) { + + # These two cheks are actually not necessary, but they can prevent future code bugs. + if (!exists $self->{Macro_Runner}{$slot}) { + debug "[eventMacro] For some reason the running macro slot ".$slot." got deleted, clearing queue slot to prevent errors.\n", "eventMacro", 2; + $self->clear_queue($slot); + next; + + } elsif (!defined $self->{Macro_Runner}{$slot}) { + debug "[eventMacro] For some reason the running macro object got undefined on slot ".$slot.", clearing queue slot to prevent errors.\n", "eventMacro", 2; + $self->clear_queue($slot); + next; + } + + my $macro = $self->{Macro_Runner}{$slot}; + + if ($macro->finished) { + debug "[eventMacro] For some reason macro '".$macro->get_name()."' on slot ".$slot." finished but 'processCmd' did not clear it, clearing queue slot to prevent errors.\n", "eventMacro", 2; + $self->clear_queue($slot); + next; + } + + next if $macro->is_paused(); + + if (timeOut($macro->timeout) && $self->is_current_macro_in_AI($slot)) { + do { + last unless ( $self->processCmd( $macro ) ); + } while ($macro && !$macro->is_paused() && $macro->macro_block); + } + } } -sub ai_is_eventMacro { - my $self = shift; - return 1 if $self->{Macro_Runner}->last_subcall_overrideAI; - - # now check for orphaned script object - # may happen when messing around with "ai clear" and stuff. - $self->enforce_orphan if (defined $self->{Macro_Runner} && !AI::inQueue('eventMacro')); +sub is_current_macro_in_AI { + my ($self, $slot) = @_; + return 1 if $self->{Macro_Runner}{$slot}->last_subcall_overrideAI; + + my $macro_index = AI::findAction('eventMacro'); + + if (defined $macro_index) { + my $macro_args = AI::args($macro_index); + + if (exists $macro_args->{$slot}) { + return 1 if ($macro_index == 0); + return 1 if (AI::is('deal')); + return 1 if (AI::is('NPC') && $char->args->waitingForSteps); + } else { + $self->enforce_orphan($slot, $macro_index); + } + + } else { + $self->enforce_orphan($slot); + } - return 1 if (AI::is('eventMacro', 'deal')); - return 1 if (AI::is('NPC') && $char->args->waitingForSteps); return 0; } sub enforce_orphan { - my $self = shift; - my $method = $self->{Macro_Runner}->last_subcall_orphan; - message "[eventMacro] Running macro '".$self->{Macro_Runner}->last_subcall_name."' got orphaned, its orphan method is '".$method."'.\n"; + my ($self, $slot, $index) = @_; + my $method = $self->{Macro_Runner}{$slot}->last_subcall_orphan; + message "[eventMacro] Running macro '".$self->{Macro_Runner}{$slot}->last_subcall_name."' on slot ".$slot." got orphaned, its orphan method is '".$method."'.\n"; # 'terminate' undefs the whole macro tree and returns "ai is not idle" if ($method eq 'terminate') { - $self->clear_queue(); + $self->clear_queue($slot); return 0; # 'terminate_last_call' undefs only the specific macro call that got orphaned, keeping the rest of the macro call tree. } elsif ($method eq 'terminate_last_call') { - my $macro = $self->{Macro_Runner}; + my $macro = $self->{Macro_Runner}{$slot}; if (defined $macro->{subcall}) { while (defined $macro->{subcall}) { #cheap way of stopping on the second to last subcall @@ -1625,70 +1694,81 @@ sub enforce_orphan { $macro->clear_subcall; } else { #since there was no subcall we delete all macro tree - $self->clear_queue(); + $self->clear_queue($slot); } return 0; # 'reregister' re-inserts "eventMacro" in ai_queue at the first position } elsif ($method eq 'reregister') { - my $macro = $self->{Macro_Runner}; + my $macro = $self->{Macro_Runner}{$slot}; while (defined $macro->{subcall}) { $macro = $macro->{subcall}; } - $macro->register; + if (defined $index) { + my $macro_args = AI::args($index); + $macro->register_add($macro_args); + } else { + $macro->register_new; + } return 1; # 'reregister_safe' waits until AI is idle then re-inserts "eventMacro" } elsif ($method eq 'reregister_safe') { if (AI::isIdle || AI::is('deal')) { - my $macro = $self->{Macro_Runner}; + my $macro = $self->{Macro_Runner}{$slot}; while (defined $macro->{subcall}) { $macro = $macro->{subcall}; } - $macro->register; + if (defined $index) { + my $macro_args = AI::args($index); + $macro->register_add($macro_args); + } else { + $macro->register_new; + } return 1 } return 0; } else { - error "[eventMacro] Unknown orphan method '".$method."'. terminating whole macro tree\n", "eventMacro"; - $self->clear_queue(); + error "[eventMacro] Unknown orphan method '".$method."'. terminating whole macro tree on slot ".$slot.".\n", "eventMacro"; + $self->clear_queue($slot); return 0; } } sub processCmd { - my ($self, $command) = @_; - my $macro_name = $self->{Macro_Runner}->last_subcall_name; + my ($self, $macro) = @_; + my $command = $macro->next; + my $slot = $macro->slot; + my $macro_name = $macro->last_subcall_name; if (defined $command) { if ($command ne '') { unless (Commands::run($command)) { my $error_message = sprintf("[eventMacro] %s failed with %s\n", $macro_name, $command); error $error_message, "eventMacro"; - $self->clear_queue(); + $self->clear_queue($slot); return; } } - if (defined $self->{Macro_Runner} && $self->{Macro_Runner}->finished) { - $self->clear_queue(); + if (defined $macro && $macro->finished) { + $self->clear_queue($slot); - } elsif (!defined $self->{Macro_Runner}) { + } elsif (!defined $macro) { debug "[eventMacro] Macro runner object got undefined during a command.\n", "eventMacro", 2; return; } else { - $self->{Macro_Runner}->ok; + $macro->ok; } } else { - my $macro = $self->{Macro_Runner}; while (defined $macro->{subcall}) { $macro = $macro->{subcall}; } my $error_message = $macro->error_message; error $error_message, "eventMacro"; - $self->clear_queue(); + $self->clear_queue($slot); return; } @@ -1696,15 +1776,18 @@ sub processCmd { } sub clear_queue { - my ($self) = @_; - debug "[eventMacro] Clearing queue\n", "eventMacro", 2; - if ( defined $self->{Macro_Runner} && $self->get_automacro_checking_status() == PAUSED_BY_EXCLUSIVE_MACRO ) { - debug "[eventMacro] Uninterruptible macro '".$self->{Macro_Runner}->last_subcall_name."' ended. Automacros will return to being checked.\n", "eventMacro", 2; - $self->set_automacro_checking_status(CHECKING_AUTOMACROS); + my ($self, $slot) = @_; + debug "[eventMacro] Clearing queue in slot ".$slot.".\n", "eventMacro", 2; + if (exists $self->{Macro_Runner}{$slot} && defined $self->{Macro_Runner}{$slot} && $self->get_automacro_checking_status($slot) == PAUSED_BY_EXCLUSIVE_MACRO ) { + debug "[eventMacro] Uninterruptible macro '".$self->{Macro_Runner}{$slot}->last_subcall_name."' in slot ".$slot." ended. Automacros in slot ".$slot." will return to being checked.\n", "eventMacro", 2; + $self->set_automacro_checking_status($slot, CHECKING_AUTOMACROS); + } + delete $self->{Macro_Runner}{$slot}; + + if (!keys %{$self->{Macro_Runner}}) { + Plugins::delHook($self->{AI_start_Macros_Running_Hook_Handle}); + undef $self->{AI_start_Macros_Running_Hook_Handle}; } - $self->{Macro_Runner} = undef; - Plugins::delHook($self->{AI_start_Macros_Running_Hook_Handle}) if (defined $self->{AI_start_Macros_Running_Hook_Handle}); - $self->{AI_start_Macros_Running_Hook_Handle} = undef; } sub include { diff --git a/plugins/eventMacro/eventMacro/Data.pm b/plugins/eventMacro/eventMacro/Data.pm index 12c26bab91..f789d60d23 100644 --- a/plugins/eventMacro/eventMacro/Data.pm +++ b/plugins/eventMacro/eventMacro/Data.pm @@ -49,6 +49,7 @@ our %parameters = ( 'priority' => 1, # option: automacro priority 'exclusive' => 1, # option: is macro interruptible 'repeat' => 1, # option: the number of times the called macro will repeat itself + 'slot' => 1, # option: The slot in which the automaro and the called macro should run 'CheckOnAI' => 1, # option: on which AI state the automacro will be checked ); diff --git a/plugins/eventMacro/eventMacro/Runner.pm b/plugins/eventMacro/eventMacro/Runner.pm index 486ea61bd0..c7b855f818 100644 --- a/plugins/eventMacro/eventMacro/Runner.pm +++ b/plugins/eventMacro/eventMacro/Runner.pm @@ -24,7 +24,7 @@ use eventMacro::Automacro; # Creates the object sub new { - my ($class, $name, $repeat, $interruptible, $overrideAI, $orphan, $delay, $macro_delay, $is_submacro) = @_; + my ($class, $name, $repeat, $slot, $interruptible, $overrideAI, $orphan, $delay, $macro_delay, $is_submacro) = @_; return undef unless ($eventMacro->{Macro_List}->getByName($name)); @@ -55,7 +55,7 @@ sub new { if ($is_submacro) { $self->{submacro} = 1; - $eventMacro->{Macro_Runner}->last_subcall_name($self->get_name); + $eventMacro->{Macro_Runner}{$slot}->last_subcall_name($self->get_name); } else { $self->{submacro} = 0; $self->last_subcall_name($self->get_name); @@ -67,6 +67,12 @@ sub new { $self->repeat(1); } + if (defined $slot && $slot =~ /^\d+$/ && $slot >= 1) { + $self->slot($slot); + } else { + $self->slot(1); + } + if (defined $interruptible && $interruptible =~ /^[01]$/) { $self->interruptible($interruptible); } else { @@ -162,12 +168,12 @@ sub interruptible { sub validate_automacro_checking_to_interruptible { my ($self, $interruptible) = @_; - my $checking_status = $eventMacro->get_automacro_checking_status(); + my $checking_status = $eventMacro->get_automacro_checking_status($self->{slot}); if (!$self->{submacro}) { $self->last_subcall_interruptible($interruptible); } else { - $eventMacro->{Macro_Runner}->last_subcall_interruptible($interruptible); + $eventMacro->{Macro_Runner}{$self->{slot}}->last_subcall_interruptible($interruptible); } if (($checking_status == CHECKING_AUTOMACROS && $interruptible == 1) || ($checking_status == PAUSED_BY_EXCLUSIVE_MACRO && $interruptible == 0)) { @@ -182,11 +188,11 @@ sub validate_automacro_checking_to_interruptible { if ($interruptible == 0) { debug "[eventMacro] Macro '".$self->{name}."' is now stopping automacro checking..\n", "eventMacro", 2; - $eventMacro->set_automacro_checking_status(PAUSED_BY_EXCLUSIVE_MACRO); + $eventMacro->set_automacro_checking_status($self->{slot}, PAUSED_BY_EXCLUSIVE_MACRO); } elsif ($interruptible == 1) { debug "[eventMacro] Macro '".$self->{name}."' is now starting automacro checking..\n", "eventMacro", 2; - $eventMacro->set_automacro_checking_status(CHECKING_AUTOMACROS); + $eventMacro->set_automacro_checking_status($self->{slot}, CHECKING_AUTOMACROS); } } @@ -216,48 +222,103 @@ sub overrideAI { sub validate_AI_queue_to_overrideAI { my ($self, $overrideAI) = @_; - my $is_in_AI_queue = AI::inQueue('eventMacro'); + my $macro_index = AI::findAction('eventMacro'); if (!$self->{submacro}) { $self->last_subcall_overrideAI($overrideAI); } else { - $eventMacro->{Macro_Runner}->last_subcall_overrideAI($overrideAI); - } - - if (($is_in_AI_queue && $overrideAI == 0) || (!$is_in_AI_queue && $overrideAI == 1)) { - debug "[eventMacro] No need to add/clear AI_queue because it already is compatible with this macro.\n", "eventMacro", 2; - return; + $eventMacro->{Macro_Runner}{$self->{slot}}->last_subcall_overrideAI($overrideAI); } - if ($overrideAI == 0) { - $self->register; + # Current macro should not be in AI queue + if ($overrideAI == 1) { - } elsif ($overrideAI == 1) { - $self->unregister; + # There is an eventMacro sequence in AI queue + if (defined $macro_index) { + my $macro_args = AI::args($macro_index); + + # And it contains the current macro + if (exists $macro_args->{$self->{slot}}) { + + # If this is the only macro in the eventMacro sequence remove it from the AI queue + if (keys %{$macro_args} == 1) { + $self->unregister; + + # If there are more macros in the eventMacro sequence only remove this one + } else { + $self->register_remove($macro_args); + } + } else { + debug "[eventMacro] No need to add/clear AI_queue because it already is compatible with this macro.\n", "eventMacro", 2; + return; + } + + } else { + debug "[eventMacro] No need to add/clear AI_queue because it already is compatible with this macro.\n", "eventMacro", 2; + return; + } + + } else { + + if (defined $macro_index) { + my $macro_args = AI::args($macro_index); + + if (exists $macro_args->{$self->{slot}}) { + debug "[eventMacro] No need to add/clear AI_queue because it already is compatible with this macro.\n", "eventMacro", 2; + return; + } else { + $self->register_add($macro_args); + } + + } else { + $self->register_new; + } } } -# Registers to AI queue -sub register { +# Registers new eventMacro sequence to AI queue +sub register_new { my ($self) = @_; - debug "[eventMacro] Macro '".$self->{name}."' is now registering itself to AI queue.\n", "eventMacro", 2; + debug "[eventMacro] Macro '".$self->{name}."' is now adding eventMacro to the AI queue sequence.\n", "eventMacro", 2; if (AI::is("NPC")) { splice(@AI::ai_seq, 1, 0, 'eventMacro'); - splice(@AI::ai_seq_args, 1, 0, {}); + splice(@AI::ai_seq_args, 1, 0, { $self->{slot} => $self->{name} }); } else { - AI::queue('eventMacro'); + AI::queue('eventMacro', { $self->{slot} => $self->{name} }); } $self->{registered} = 1; } -# Unregisters from AI queue +# Unregisters eventMacro sequence from AI queue sub unregister { my ($self) = @_; - debug "[eventMacro] Macro '".$self->{name}."' is now deleting itself from AI queue.\n", "eventMacro", 2; + debug "[eventMacro] Macro '".$self->{name}."' is now deleting eventMacro from the AI queue sequence.\n", "eventMacro", 2; AI::clear('eventMacro'); $self->{registered} = 0; } +# Adds the current macro to the already existent eventMacro sequence in AI queue +sub register_add { + my ($self, $macro_args) = @_; + debug "[eventMacro] Macro '".$self->{name}."' is now adding itself to the eventMacro sequence in the AI queue.\n", "eventMacro", 2; + $macro_args->{$self->{slot}} = $self->{name}; + $self->{registered} = 1; +} + +# Removes the current macro from the eventMacro sequence in AI queue +sub register_remove { + my ($self, $macro_args) = @_; + debug "[eventMacro] Macro '".$self->{name}."' is now deleting itself from the eventMacro sequence in the AI queue.\n", "eventMacro", 2; + delete $macro_args->{$self->{slot}}; + $self->{registered} = 0; +} + +# Returns true if the macro is registered to AI queue +sub registered { + my ($self) = @_; + return $self->{registered}; +} + # Sets/Gets the current orphan method sub orphan { my ($self, $orphan) = @_; @@ -275,7 +336,7 @@ sub orphan { if (!$self->{submacro}) { $self->last_subcall_orphan($orphan); } else { - $eventMacro->{Macro_Runner}->last_subcall_orphan($orphan); + $eventMacro->{Macro_Runner}{$self->{slot}}->last_subcall_orphan($orphan); } } } @@ -300,12 +361,6 @@ sub macro_delay { return $self->{macro_delay}; } -# Returns true if the macro is registered to AI queue -sub registered { - my ($self) = @_; - return $self->{registered}; -} - # Sets/Gets the current repeat count sub repeat { my ($self, $repeat) = @_; @@ -316,6 +371,16 @@ sub repeat { return $self->{repeat}; } +# Sets/Gets the current running slot +sub slot { + my ($self, $slot) = @_; + if (defined $slot) { + debug "[eventMacro] Now macro '".$self->{name}."' will run on slot '".$slot."'.\n", "eventMacro", 2; + $self->{slot} = $slot; + } + return $self->{slot}; +} + # Pauses the macro sub pause { my ($self) = @_; @@ -352,13 +417,13 @@ sub clear_subcall { if (!$self->{submacro}) { $self->last_subcall_orphan($self->orphan); } else { - $eventMacro->{Macro_Runner}->last_subcall_orphan($self->orphan); + $eventMacro->{Macro_Runner}{$self->{slot}}->last_subcall_orphan($self->orphan); } } else { debug "[eventMacro] No need to change orphan method because it already is compatible with this macro.\n", "eventMacro", 2; } if ($self->{submacro}) { - $eventMacro->{Macro_Runner}->last_subcall_name($self->get_name); + $eventMacro->{Macro_Runner}{$self->{slot}}->last_subcall_name($self->get_name); } else { $self->last_subcall_name($self->get_name); } @@ -369,13 +434,31 @@ sub clear_subcall { sub create_subcall { my ($self, $name, $repeat) = @_; debug "[eventMacro] Creating submacro '".$name."' on macro '".$self->{name}."'.\n", "eventMacro", 2; - $self->{subcall} = new eventMacro::Runner($name, $repeat, $self->interruptible, $self->overrideAI, $self->orphan, undef, $self->macro_delay, 1); + $self->{subcall} = new eventMacro::Runner($name, $repeat, $self->{slot}, $self->interruptible, $self->overrideAI, $self->orphan, undef, $self->macro_delay, 1); } # destructor sub DESTROY { my ($self) = @_; - $self->unregister if (AI::inQueue('eventMacro') && !$self->{submacro}); + if (!$self->{submacro}) { + + my $macro_index = AI::findAction('eventMacro'); + + return if (!defined $macro_index); + + my $macro_args = AI::args($macro_index); + + return if (!exists $macro_args->{$self->{slot}}); + + # If this is the only macro in the eventMacro sequence remove it from the AI queue + if (keys %{$macro_args} == 1) { + $self->unregister; + + # If there are more macros in the eventMacro sequence only remove this one + } else { + $self->register_remove($macro_args); + } + } } # TODO: Check this diff --git a/plugins/eventMacro/test/RunnerParseCommandTest.pm b/plugins/eventMacro/test/RunnerParseCommandTest.pm index 2c0542c7d9..bcc1e1feed 100644 --- a/plugins/eventMacro/test/RunnerParseCommandTest.pm +++ b/plugins/eventMacro/test/RunnerParseCommandTest.pm @@ -14,84 +14,87 @@ use eventMacro::Utilities qw(find_variable); sub start { $eventMacro = eventMacro::Core->new( "$RealBin/textfiles/LoadConditionsTest.txt" ); - $eventMacro->{Macro_Runner} = new eventMacro::Runner( - 'testmacro1', - 1, - undef, - undef, - undef, - undef, - undef, - 0 - ); + $eventMacro->{Macro_Runner}{'1'} = new eventMacro::Runner( + 'testmacro1', # name + 1, # repeat + 1, # slot + undef, # exclusive + undef, # overrideAI + undef, # orphan + undef, # delay + undef, # macro_delay + 0 # is_subcall + ); - ok (defined $eventMacro->{Macro_Runner}); + ok (exists $eventMacro->{Macro_Runner}{'1'}); + + ok (defined $eventMacro->{Macro_Runner}{'1'}); subtest 'scalar' => sub { $eventMacro->set_scalar_var('scalar1', 10); - is ($eventMacro->{Macro_Runner}->parse_command( '$scalar1' ), '10'); - is ($eventMacro->{Macro_Runner}->parse_command( '$scalar1 + $scalar1' ), '10 + 10'); - is ($eventMacro->{Macro_Runner}->parse_command( '$scalar1 * $scalar1' ), '10 * 10'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '$scalar1' ), '10'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '$scalar1 + $scalar1' ), '10 + 10'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '$scalar1 * $scalar1' ), '10 * 10'); $eventMacro->set_scalar_var('scalar2', 25); - is ($eventMacro->{Macro_Runner}->parse_command( '$scalar2' ), '25'); - is ($eventMacro->{Macro_Runner}->parse_command( '$scalar1 + $scalar2' ), '10 + 25'); - is ($eventMacro->{Macro_Runner}->parse_command( '$scalar1 * $scalar2' ), '10 * 25'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '$scalar2' ), '25'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '$scalar1 + $scalar2' ), '10 + 25'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '$scalar1 * $scalar2' ), '10 * 25'); - is ($eventMacro->{Macro_Runner}->parse_command( '$scalar3' ), ''); - is ($eventMacro->{Macro_Runner}->parse_command( '$scalar3 + $scalar2' ), ' + 25'); - is ($eventMacro->{Macro_Runner}->parse_command( '$scalar3 * $scalar2' ), ' * 25'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '$scalar3' ), ''); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '$scalar3 + $scalar2' ), ' + 25'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '$scalar3 * $scalar2' ), ' * 25'); }; subtest 'array' => sub { $eventMacro->set_full_array('array1', ['Angeling', 'Deviling', 'Archangeling', 'undef', 'Mastering', 'undef', 'King Poring']); - is ($eventMacro->{Macro_Runner}->parse_command( '@array1' ), '7'); - is ($eventMacro->{Macro_Runner}->parse_command( '@array1 > $scalar1' ), '7 > 10'); - is ($eventMacro->{Macro_Runner}->parse_command( '@array1 - 5' ), '7 - 5'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '@array1' ), '7'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '@array1 > $scalar1' ), '7 > 10'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '@array1 - 5' ), '7 - 5'); $eventMacro->set_full_array('array2', ['Poring', 'undef', 'Drops', 'Magmaring']); - is ($eventMacro->{Macro_Runner}->parse_command( '@array2' ), '4'); - is ($eventMacro->{Macro_Runner}->parse_command( '@array1 + @array2' ), '7 + 4'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '@array2' ), '4'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '@array1 + @array2' ), '7 + 4'); - is ($eventMacro->{Macro_Runner}->parse_command( '$array1[0]' ), 'Angeling'); - is ($eventMacro->{Macro_Runner}->parse_command( '$array1[0] or $array1[1] or maybe $array1[2] or even $array1[3] or if not possible $array1[6]' ), 'Angeling or Deviling or maybe Archangeling or even or if not possible King Poring'); - is ($eventMacro->{Macro_Runner}->parse_command( '$array2[2] is weaker than $array1[0], but stronger then $array2[0]' ), 'Drops is weaker than Angeling, but stronger then Poring'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '$array1[0]' ), 'Angeling'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '$array1[0] or $array1[1] or maybe $array1[2] or even $array1[3] or if not possible $array1[6]' ), 'Angeling or Deviling or maybe Archangeling or even or if not possible King Poring'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '$array2[2] is weaker than $array1[0], but stronger then $array2[0]' ), 'Drops is weaker than Angeling, but stronger then Poring'); - is ($eventMacro->{Macro_Runner}->parse_command( '$array[7] '.$macro_keywords_character.'push(@array1, Another Poring) $array1[7] @array1' ), ' 8 Another Poring 8'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '$array[7] '.$macro_keywords_character.'push(@array1, Another Poring) $array1[7] @array1' ), ' 8 Another Poring 8'); - is ($eventMacro->{Macro_Runner}->parse_command( $macro_keywords_character.'unshift(@array1, Even other poring)' ), '9'); - is ($eventMacro->{Macro_Runner}->parse_command( '@array1' ), '9'); - is ($eventMacro->{Macro_Runner}->parse_command( '$array1[0]' ), 'Even other poring'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( $macro_keywords_character.'unshift(@array1, Even other poring)' ), '9'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '@array1' ), '9'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '$array1[0]' ), 'Even other poring'); - is ($eventMacro->{Macro_Runner}->parse_command( $macro_keywords_character.'pop(@array2)' ), 'Magmaring'); - is ($eventMacro->{Macro_Runner}->parse_command( '@array2' ), '3'); - is ($eventMacro->{Macro_Runner}->parse_command( $macro_keywords_character.'shift(@array2)' ), 'Poring'); - is ($eventMacro->{Macro_Runner}->parse_command( '@array2' ), '2'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( $macro_keywords_character.'pop(@array2)' ), 'Magmaring'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '@array2' ), '3'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( $macro_keywords_character.'shift(@array2)' ), 'Poring'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '@array2' ), '2'); }; subtest 'hash' => sub { $eventMacro->set_full_hash('hash1', {'Poring' => 10, 'Drops' => 25, 'Poporing' => 'undef', 'Magmaring' => 100, 'Angeling' => 'undef'}); - is ($eventMacro->{Macro_Runner}->parse_command( '%hash1' ), '5'); - is ($eventMacro->{Macro_Runner}->parse_command( '%hash1 > $scalar1 == @array2' ), '5 > 10 == 2'); - is ($eventMacro->{Macro_Runner}->parse_command( '%hash1 + %hash1 * %hash1' ), '5 + 5 * 5'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '%hash1' ), '5'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '%hash1 > $scalar1 == @array2' ), '5 > 10 == 2'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '%hash1 + %hash1 * %hash1' ), '5 + 5 * 5'); $eventMacro->set_full_hash('hash2', {'Staff' => 2000, 'Shield' => 'undef', 'Card' => 7000}); - is ($eventMacro->{Macro_Runner}->parse_command( '%hash2' ), '3'); - is ($eventMacro->{Macro_Runner}->parse_command( '%hash2 / %hash2' ), '3 / 3'); - is ($eventMacro->{Macro_Runner}->parse_command( '%hash2 + %hash1' ), '3 + 5'); - - is ($eventMacro->{Macro_Runner}->parse_command( 'The member of key Poring is $hash1{Poring}' ), 'The member of key Poring is 10'); - is ($eventMacro->{Macro_Runner}->parse_command( 'Poporing is $hash1{Poporing}' ), 'Poporing is '); - is ($eventMacro->{Macro_Runner}->parse_command( 'The staff costs $hash2{Staff}' ), 'The staff costs 2000'); - - is ($eventMacro->{Macro_Runner}->parse_command( $macro_keywords_character.'exists($hash1{Poring})' ), '1'); - is ($eventMacro->{Macro_Runner}->parse_command( $macro_keywords_character.'exists($hash1{Poporing})' ), '1'); - is ($eventMacro->{Macro_Runner}->parse_command( $macro_keywords_character.'exists($hash2{Staff})' ), '1'); - is ($eventMacro->{Macro_Runner}->parse_command( $macro_keywords_character.'exists($hash1{Staff})' ), '0'); - is ($eventMacro->{Macro_Runner}->parse_command( $macro_keywords_character.'exists($hash2{Poporing})' ), '0'); - - is ($eventMacro->{Macro_Runner}->parse_command( $macro_keywords_character.'delete($hash1{Magmaring})' ), '100'); - is ($eventMacro->{Macro_Runner}->parse_command( $macro_keywords_character.'delete($hash2{Staff})' ), '2000'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '%hash2' ), '3'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '%hash2 / %hash2' ), '3 / 3'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '%hash2 + %hash1' ), '3 + 5'); + + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( 'The member of key Poring is $hash1{Poring}' ), 'The member of key Poring is 10'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( 'Poporing is $hash1{Poporing}' ), 'Poporing is '); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( 'The staff costs $hash2{Staff}' ), 'The staff costs 2000'); + + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( $macro_keywords_character.'exists($hash1{Poring})' ), '1'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( $macro_keywords_character.'exists($hash1{Poporing})' ), '1'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( $macro_keywords_character.'exists($hash2{Staff})' ), '1'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( $macro_keywords_character.'exists($hash1{Staff})' ), '0'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( $macro_keywords_character.'exists($hash2{Poporing})' ), '0'); + + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( $macro_keywords_character.'delete($hash1{Magmaring})' ), '100'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( $macro_keywords_character.'delete($hash2{Staff})' ), '2000'); }; subtest 'complex vars' => sub { @@ -102,27 +105,27 @@ sub start { $eventMacro->set_scalar_var('scalar1', 0); $eventMacro->set_scalar_var('scalar2', 1); $eventMacro->set_scalar_var('scalar3', 2); - is ($eventMacro->{Macro_Runner}->parse_command( '$hash1{$array1[$scalar1]}' ), '25'); - is ($eventMacro->{Macro_Runner}->parse_command( '$array2[$scalar2]' ), 'Drops'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '$hash1{$array1[$scalar1]}' ), '25'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '$array2[$scalar2]' ), 'Drops'); $eventMacro->set_scalar_var('scalar4', 'Poring'); - is ($eventMacro->{Macro_Runner}->parse_command( '$hash1{$scalar4}' ), '1'); - is ($eventMacro->{Macro_Runner}->parse_command( '$array1[$hash1{$scalar4}]' ), 'Deviling'); - is ($eventMacro->{Macro_Runner}->parse_command( '$hash1{$array1[$hash1{$scalar4}]}' ), '100'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '$hash1{$scalar4}' ), '1'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '$array1[$hash1{$scalar4}]' ), 'Deviling'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '$hash1{$array1[$hash1{$scalar4}]}' ), '100'); $eventMacro->set_full_hash('hash3', {'Poring' => 'Drops', 'Drops' => 'Magmaring', 'Magmaring' => 'Angeling', 'Angeling' => 'Deviling', 'Deviling' => 'victory'}); - is ($eventMacro->{Macro_Runner}->parse_command( '$hash3{$scalar4}' ), 'Drops'); - is ($eventMacro->{Macro_Runner}->parse_command( '$hash3{$hash3{$scalar4}}' ), 'Magmaring'); - is ($eventMacro->{Macro_Runner}->parse_command( '$hash3{$hash3{$hash3{$scalar4}}}' ), 'Angeling'); - is ($eventMacro->{Macro_Runner}->parse_command( '$hash3{$hash3{$hash3{$hash3{$scalar4}}}}' ), 'Deviling'); - is ($eventMacro->{Macro_Runner}->parse_command( '$hash3{$hash3{$hash3{$hash3{$hash3{$scalar4}}}}}' ), 'victory'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '$hash3{$scalar4}' ), 'Drops'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '$hash3{$hash3{$scalar4}}' ), 'Magmaring'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '$hash3{$hash3{$hash3{$scalar4}}}' ), 'Angeling'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '$hash3{$hash3{$hash3{$hash3{$scalar4}}}}' ), 'Deviling'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '$hash3{$hash3{$hash3{$hash3{$hash3{$scalar4}}}}}' ), 'victory'); $eventMacro->set_full_array('array3', [5, 2, 3, 0, 1, 4]); $eventMacro->set_full_array('array4', [2, 5, 3, 4, 'end', 1]); - is ($eventMacro->{Macro_Runner}->parse_command( '$array4[$array3[$array4[$array3[$array4[$array3[$array4[$array3[$array4[$array3[$array4[$array3[$scalar1]]]]]]]]]]]]' ), 'end'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( '$array4[$array3[$array4[$array3[$array4[$array3[$array4[$array3[$array4[$array3[$array4[$array3[$scalar1]]]]]]]]]]]]' ), 'end'); - is ($eventMacro->{Macro_Runner}->parse_command( 'olha que legal esse [{{$hash3{$hash3{$scalar4}}}}]' ), 'olha que legal esse [{{Magmaring}}]'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( 'olha que legal esse [{{$hash3{$hash3{$scalar4}}}}]' ), 'olha que legal esse [{{Magmaring}}]'); }; @@ -130,60 +133,60 @@ sub start { $eventMacro->set_scalar_var('scalar1', 'undef'); $eventMacro->set_scalar_var('scalar2', 15); - is ($eventMacro->{Macro_Runner}->parse_command( 'the value is $scalar1' ), 'the value is '); - is ($eventMacro->{Macro_Runner}->parse_command( 'the value is $scalar2' ), 'the value is 15'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( 'the value is $scalar1' ), 'the value is '); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( 'the value is $scalar2' ), 'the value is 15'); - is ($eventMacro->{Macro_Runner}->parse_command( $macro_keywords_character.'defined($scalar1)' ), 0); - is ($eventMacro->{Macro_Runner}->parse_command( $macro_keywords_character.'defined($scalar2)' ), 1); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( $macro_keywords_character.'defined($scalar1)' ), 0); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( $macro_keywords_character.'defined($scalar2)' ), 1); $eventMacro->set_scalar_var('scalar1', 8); $eventMacro->set_scalar_var('scalar2', 'undef'); - is ($eventMacro->{Macro_Runner}->parse_command( 'the value is $scalar1' ), 'the value is 8'); - is ($eventMacro->{Macro_Runner}->parse_command( 'the value is $scalar2' ), 'the value is '); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( 'the value is $scalar1' ), 'the value is 8'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( 'the value is $scalar2' ), 'the value is '); - is ($eventMacro->{Macro_Runner}->parse_command( $macro_keywords_character.'defined($scalar1)' ), 1); - is ($eventMacro->{Macro_Runner}->parse_command( $macro_keywords_character.'defined($scalar2)' ), 0); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( $macro_keywords_character.'defined($scalar1)' ), 1); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( $macro_keywords_character.'defined($scalar2)' ), 0); $eventMacro->clear_array('array1'); $eventMacro->set_array_var('array1', 0, 'undef'); $eventMacro->set_array_var('array1', 1, 27); - is ($eventMacro->{Macro_Runner}->parse_command( 'the value is $array1[0]' ), 'the value is '); - is ($eventMacro->{Macro_Runner}->parse_command( 'the value is $array1[1]' ), 'the value is 27'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( 'the value is $array1[0]' ), 'the value is '); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( 'the value is $array1[1]' ), 'the value is 27'); - is ($eventMacro->{Macro_Runner}->parse_command( $macro_keywords_character.'defined($array1[0])' ), 0); - is ($eventMacro->{Macro_Runner}->parse_command( $macro_keywords_character.'defined($array1[1])' ), 1); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( $macro_keywords_character.'defined($array1[0])' ), 0); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( $macro_keywords_character.'defined($array1[1])' ), 1); $eventMacro->set_array_var('array1', 0, 35); $eventMacro->set_array_var('array1', 1, 'undef'); - is ($eventMacro->{Macro_Runner}->parse_command( 'the value is $array1[0]' ), 'the value is 35'); - is ($eventMacro->{Macro_Runner}->parse_command( 'the value is $array1[1]' ), 'the value is '); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( 'the value is $array1[0]' ), 'the value is 35'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( 'the value is $array1[1]' ), 'the value is '); - is ($eventMacro->{Macro_Runner}->parse_command( $macro_keywords_character.'defined($array1[0])' ), 1); - is ($eventMacro->{Macro_Runner}->parse_command( $macro_keywords_character.'defined($array1[1])' ), 0); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( $macro_keywords_character.'defined($array1[0])' ), 1); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( $macro_keywords_character.'defined($array1[1])' ), 0); $eventMacro->clear_hash('hash1'); $eventMacro->set_hash_var('hash1', 'key1', 'undef'); $eventMacro->set_hash_var('hash1', 'key2', 12); - is ($eventMacro->{Macro_Runner}->parse_command( 'the value is $hash1{key1}' ), 'the value is '); - is ($eventMacro->{Macro_Runner}->parse_command( 'the value is $hash1{key2}' ), 'the value is 12'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( 'the value is $hash1{key1}' ), 'the value is '); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( 'the value is $hash1{key2}' ), 'the value is 12'); - is ($eventMacro->{Macro_Runner}->parse_command( $macro_keywords_character.'defined($hash1{key1})' ), 0); - is ($eventMacro->{Macro_Runner}->parse_command( $macro_keywords_character.'defined($hash1{key2})' ), 1); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( $macro_keywords_character.'defined($hash1{key1})' ), 0); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( $macro_keywords_character.'defined($hash1{key2})' ), 1); $eventMacro->set_hash_var('hash1', 'key1', 21); $eventMacro->set_hash_var('hash1', 'key2', 'undef'); - is ($eventMacro->{Macro_Runner}->parse_command( 'the value is $hash1{key1}' ), 'the value is 21'); - is ($eventMacro->{Macro_Runner}->parse_command( 'the value is $hash1{key2}' ), 'the value is '); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( 'the value is $hash1{key1}' ), 'the value is 21'); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( 'the value is $hash1{key2}' ), 'the value is '); - is ($eventMacro->{Macro_Runner}->parse_command( $macro_keywords_character.'defined($hash1{key1})' ), 1); - is ($eventMacro->{Macro_Runner}->parse_command( $macro_keywords_character.'defined($hash1{key2})' ), 0); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( $macro_keywords_character.'defined($hash1{key1})' ), 1); + is ($eventMacro->{Macro_Runner}{'1'}->parse_command( $macro_keywords_character.'defined($hash1{key2})' ), 0); } } diff --git a/plugins/eventMacro/test/RunnerStatementTest.pm b/plugins/eventMacro/test/RunnerStatementTest.pm index 9952ebda1f..f8f57a5edc 100644 --- a/plugins/eventMacro/test/RunnerStatementTest.pm +++ b/plugins/eventMacro/test/RunnerStatementTest.pm @@ -14,68 +14,71 @@ use eventMacro::Utilities qw(find_variable); sub start { $eventMacro = eventMacro::Core->new( "$RealBin/textfiles/LoadConditionsTest.txt" ); - $eventMacro->{Macro_Runner} = new eventMacro::Runner( - 'testmacro1', - 1, - undef, - undef, - undef, - undef, - undef, - 0 - ); + $eventMacro->{Macro_Runner}{'1'} = new eventMacro::Runner( + 'testmacro1', # name + 1, # repeat + 1, # slot + undef, # exclusive + undef, # overrideAI + undef, # orphan + undef, # delay + undef, # macro_delay + 0 # is_subcall + ); - ok (defined $eventMacro->{Macro_Runner}); + ok (exists $eventMacro->{Macro_Runner}{'1'}); + + ok (defined $eventMacro->{Macro_Runner}{'1'}); subtest 'math simple' => sub { - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( '1 > 0' ), 1); - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( '5 > 7' ), 0); - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( '2 = 2' ), 1); - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( '2 = 5' ), 0); - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( '10 < 20' ), 1); - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( '70 < 50' ), 0); - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( '5 == 5' ), 1); - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( '5 == 9' ), 0); - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( '5 >= 4' ), 1); - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( '5 >= 5' ), 1); - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( '5 >= 6' ), 0); - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( '3 <= 4' ), 1); - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( '4 <= 4' ), 1); - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( '5 <= 4' ), 0); - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( '6 != 5' ), 1); - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( '6 != 6' ), 0); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(1 > 0)' ))[0], 1); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(5 > 7)' ))[0], 0); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(2 = 2)' ))[0], 1); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(2 = 5)' ))[0], 0); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(10 < 20)' ))[0], 1); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(70 < 50)' ))[0], 0); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(5 == 5)' ))[0], 1); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(5 == 9)' ))[0], 0); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(5 >= 4)' ))[0], 1); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(5 >= 5)' ))[0], 1); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(5 >= 6)' ))[0], 0); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(3 <= 4)' ))[0], 1); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(4 <= 4)' ))[0], 1); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(5 <= 4)' ))[0], 0); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(6 != 5)' ))[0], 1); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(6 != 6)' ))[0], 0); }; subtest 'math range' => sub { - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( '5 == 3..7' ), 1); - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( '9 == 15..20' ), 0); - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( '3 != 5..7' ), 1); - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( '15 != 10..20' ), 0); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(5 == 3..7)' ))[0], 1); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(9 == 15..20)' ))[0], 0); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(3 != 5..7)' ))[0], 1); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(15 != 10..20)' ))[0], 0); - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( '3..7 == 5' ), 1); - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( '15..20 == 9' ), 0); - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( '5..7 != 3' ), 1); - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( '10..20 != 15' ), 0); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(3..7 == 5)' ))[0], 1); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(15..20 == 9)' ))[0], 0); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(5..7 != 3)' ))[0], 1); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(10..20 != 15)' ))[0], 0); }; subtest 'text' => sub { - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( 'Poring == Poring' ), 1); - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( 'Poring == Drops' ), 0); - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( 'Poring != Drops' ), 1); - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( 'Poring != Poring' ), 0); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(Poring == Poring)' ))[0], 1); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(Poring == Drops)' ))[0], 0); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(Poring != Drops)' ))[0], 1); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(Poring != Poring)' ))[0], 0); }; subtest 'list' => sub { - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( 'Poring ~ Drops, Poring, Poporing, Magmaring' ), 1); - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( 'Weapon ~ Shield, Hat, Shoe, Mantle' ), 0); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(Poring ~ Drops, Poring, Poporing, Magmaring)' ))[0], 1); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(Weapon ~ Shield, Hat, Shoe, Mantle)' ))[0], 0); }; subtest 'regex' => sub { - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( 'Poring =~ /Por/'), 1); - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( 'Poring =~ /Por/i'), 1); - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( 'Poring =~ /por/'), 0); - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( 'Poring =~ /por/i'), 1); - is ($eventMacro->{Macro_Runner}->parse_and_check_condition_text( 'Marin =~ /oring/i'), 0); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(Poring =~ /Por/)' ))[0], 1); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(Poring =~ /Por/i)' ))[0], 1); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(Poring =~ /por/)' ))[0], 0); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(Poring =~ /por/i)' ))[0], 1); + is (($eventMacro->{Macro_Runner}{'1'}->parse_and_check_condition_text( '(Marin =~ /oring/i)' ))[0], 0); }; }