8680's Lua Thread

Discussion of Lua and LuaWML support, development, and ideas.

Moderator: Forum Moderators

Post Reply
User avatar
8680
Moderator Emeritus
Posts: 742
Joined: March 20th, 2011, 11:45 pm
Location: The past

8680's Lua Thread

Post by 8680 »

I made/am making tags to replace/improve various macros. So far I have three tags fully written and tested against the old macros:
{FOREACH} > [foreach]
Tag

Code: Select all

-- array : the array to iterate over. Required.
-- i_var : a variable to save the current index to. Default="index".
-- v_var : a variable to save the current value to. Default="value".
-- <ActionWML>
function wml_actions.foreach ( cfg )
    local a_var = cfg.array or helper.wml_error "[foreach] missing required array= attribute"
    local a_len = wesnoth.get_variable ( string.format ( "%s.length", a_var ) ) or
        helper.wml_error "[foreach] array= does not exist"
    local array, i_var, v_var = {}, cfg.i_var or "index", cfg.v_var or "value"
    for i = 1, a_len do
        array[i] = wesnoth.get_variable ( string.format ( "%s[%d]", a_var, i - 1 ) )
    end
    for i, v in ipairs ( array ) do
        wesnoth.set_variable ( i_var, i - 1 )
        wesnoth.set_variable ( v_var, v )
        handle_event_commands ( cfg )
    end
    wesnoth.set_variable ( i_var )
    wesnoth.set_variable ( v_var )
end
New macro

Code: Select all

#define FOREACH ARRAY I_VAR V_VAR ACTION_WML
    [foreach]
        array={ARRAY}
        i_var={I_VAR}
        v_var={V_VAR}
        {ACTION_WML}
    [/foreach]
#enddef
Test

Code: Select all

{VARIABLE a.b[0].c 1}
[loop]
    cycles=999
    {VARIABLE a.b[$cycle|].c "$($cycle|+1)"}
[/loop]
{VARIABLE T 0}
{VARIABLE M 0}
{TIMED_ACTIONS "Time: T" (
    [foreach]
        array,i_var,v_var=a.b,i,v
        {VARIABLE T $v.c|}
    [/foreach]
)}
{TIMED_ACTIONS "Time: M" (
    {FOREACH a.b i}
        {VARIABLE M $a.b[$i].c|}
    {NEXT i}
)}

########## RESULTS ##########
## tag took 57 milliseconds
## macro took 103 milliseconds
{REPEAT} > [loop]
Tag

Code: Select all

-- cycles : how many times to repeat the loop. Required.
-- it_var : a variable to save the current cycle number to. Default="cycle".
-- <ActionWML>
function wml_actions.loop ( cfg )
    local times = tonumber ( cfg.cycles or helper.wml_error "[loop] missing required cycles= attribute" ) or
        helper.wml_error "[loop] has malformed cycles= attribute"
    local i_var = cfg.it_var or "cycle"
    for i = 1, times do
        wesnoth.set_variable ( i_var, i )
        handle_event_commands ( cfg )
    end
    wesnoth.set_variable ( i_var )
end
New macro

Code: Select all

#define LOOP CYCLES ACTION_WML
    [loop]
        cycles={CYCLES}
        {ACTION_WML}
    [/loop]
#enddef
Test

Code: Select all

{VARIABLE T 0}
{VARIABLE M 0}
{TIMED_ACTIONS "Time: T" (
    [loop]
        cycles=1000
        {VARIABLE_OP T add 1}
    [/loop]
)}
{TIMED_ACTIONS "Time: M" (
    {REPEAT 1000 (
        {VARIABLE_OP M add 1}
    )}
)}

########## RESULTS ##########
## tag took 28 milliseconds
## macro took 77 milliseconds
{PUT_TO_RECALL_LIST} > [put_to_recall_list]
Tag

Code: Select all

-- list_side : the side whose recall list the units are to be put to. Defaults to units being put to their own sides' recall lists.
-- <SUF>
function wml_actions.put_to_recall_list ( cfg )
    local ls = cfg.list_side
    if ls then
        ls = tonumber ( ls ) or helper.wml_error "[put_to_recall_list] has malformed list_side= attribute"
        if ls < 1 or ls > 9 then
            helper.wml_error "[put_to_recall_list] has invalid list_side= attribute"
        end
    end
    for i, u in ipairs ( wesnoth.get_units ( cfg ) ) do
        wesnoth.put_recall_unit ( u, ls )
    end
end
New macro

Code: Select all

#define PUT_TO_RECALL_LIST FILTER
    [put_to_recall_list]
        {FILTER}
    [/put_to_recall_list]
#enddef
Test

Code: Select all

[loop]
    cycles=100
    {GENERIC_UNIT 1 "Fog Clearer" 10 10}
[/loop]
{TIMED_ACTIONS "Time: T" (
    [put_to_recall_list]
        type="Fog Clearer"
    [/put_to_recall_list]
)}
{TIMED_ACTIONS "Time: M" (
    {PUT_TO_RECALL_LIST type="Fog Clearer"}
)}

########## RESULTS ##########
## tag took 130 milliseconds
## macro took 2724 milliseconds
I hope this isn't resented or against the rules.
Exasperation
Posts: 462
Joined: June 8th, 2006, 3:25 am

Re: 8680's Lua Thread

Post by Exasperation »

You might find the contents of the following thread interesting: http://forums.wesnoth.org/viewtopic.php?f=58&t=30983. I am especially curious if your foreach tag can handle the use-case I brought up in that thread, where the array itself (not just the individual elements) is being modified inside of the loop.
User avatar
8680
Moderator Emeritus
Posts: 742
Joined: March 20th, 2011, 11:45 pm
Location: The past

Re: 8680's Lua Thread

Post by 8680 »

@Exasperation: I'll look into that. But I'm traveling currently, so it'll take me a while to fully write and test it. I'm thinking an alternate mode (mode="full") that would use while instead of for, and enable an [index] tag that could increment or decrement the index by a specified amount and jump to a specified index. I'd also add this to [loop], and I'll add a [break] tag (maybe with a filter) to both. Phew... this'll require rewriting handle_event_commands().
Anonymissimus
Inactive Developer
Posts: 2461
Joined: August 15th, 2008, 8:46 pm
Location: Germany

Re: 8680's Lua Thread

Post by Anonymissimus »

8680 wrote:this'll require rewriting handle_event_commands().
Don't.
If you want to have any chance to get the patches into core don't modify that function. You could start by the code I posted in that thread Exasperation linked to. I had stopped coding [foreach] due to the severe issues brought up by his post.
IMO it requires writing a lua iterator libary. Sad to say there doesn't seem to be an official one, and wesnoth needs one IMO. Basically the equivalent of what's apparently used in the current C++ array implementation (since such advanced array modifications do work).
projects (BfW 1.12):
A Simple Campaign: campaign draft for wml startersPlan Your Advancements: mp mod
The Earth's Gut: sp campaignSettlers of Wesnoth: mp scenarioWesnoth Lua Pack: lua tags and utils
updated to 1.8 and handed over: A Gryphon's Tale: sp campaign
User avatar
8680
Moderator Emeritus
Posts: 742
Joined: March 20th, 2011, 11:45 pm
Location: The past

Re: 8680's Lua Thread

Post by 8680 »

@Anonymissimus: Er, I meant copying it, not replacing it, though reading that it does sound like I meant replacing it. Is copying it allowed?
Anonymissimus
Inactive Developer
Posts: 2461
Joined: August 15th, 2008, 8:46 pm
Location: Germany

Re: 8680's Lua Thread

Post by Anonymissimus »

8680 wrote:@Anonymissimus: Er, I meant copying it, not replacing it, though reading that it does sound like I meant replacing it. Is copying it allowed?
In my code I had the call wml_actions[tag_name](cfg). Why don't you do that ?
Why would you need to copy it ? Redundant code is always bad.
projects (BfW 1.12):
A Simple Campaign: campaign draft for wml startersPlan Your Advancements: mp mod
The Earth's Gut: sp campaignSettlers of Wesnoth: mp scenarioWesnoth Lua Pack: lua tags and utils
updated to 1.8 and handed over: A Gryphon's Tale: sp campaign
User avatar
8680
Moderator Emeritus
Posts: 742
Joined: March 20th, 2011, 11:45 pm
Location: The past

Re: 8680's Lua Thread

Post by 8680 »

Anonymissimus wrote:In my code I had the call wml_actions[tag_name](cfg). Why don't you do that?
Can that handle [insert_tag]?
Post Reply