Returning a WML tag table with .while

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

Moderator: Forum Moderators

Post Reply
User avatar
Pentarctagon
Project Manager
Posts: 5564
Joined: March 22nd, 2009, 10:50 pm
Location: Earth (occasionally)

Returning a WML tag table with .while

Post by Pentarctagon »

I'm trying to return a WML table of tags from a lua function, the idea being that it's similar to splitting WML between files and then including them in a main file via:

Code: Select all

{~add-ons/Addon/folder/file.cfg}
In my preload event I've defined the following:

Code: Select all

helper = wesnoth.require "lua/helper.lua"
tag = helper.set_wml_tag_metatable{}
action = helper.set_wml_action_metatable{}

wesnoth.dofile "~add-ons/Music/macros/_test.lua"
However the following code in _test.lua:

Code: Select all

function test()
  return tag.option
  {
    message = "&" .. "ball-green.png" .. "=" .. "Message",
    
    tag.command
    {
      tag.while
      {
        tag.variable
        {
          name = "music_repeating1",
          value = 1
        },
        
        tag.do
        {
          tag.message
          {
            speaker = "narrator",
            message = "",
            
            tag.option
            {
              message = "&" .. "ball-red.png" .. "=" .. "Message",
              
              tag.command
              {
                tag.set_variable
                {
                  name = "music_repeating1",
                  value = "$empty"
                }
              }
            }
          }
        }
      }
    }
  }
end
gives the error:

Code: Select all

_test.lua:8: <name> expected near 'while'
What is it expecting near tag.while?
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
User avatar
iceiceice
Posts: 1056
Joined: August 23rd, 2013, 2:10 am

Re: Returning a WML tag table with .while

Post by iceiceice »

I fooled around with this in the lua interpreter in 1.13.
Spoiler:
I think that the problem is that you cannot use while or do as the names of table entries in lua, because they are reserved words. It seems like it is just failing to parse the way you want it to. Maybe there is some workaround you can use, like using the table insert function with string arguments or something. Probably not worth it though.
User avatar
Elvish_Hunter
Posts: 1575
Joined: September 4th, 2009, 2:39 pm
Location: Lintanir Forest...

Re: Returning a WML tag table with .while

Post by Elvish_Hunter »

iceiceice wrote:What is it expecting near tag.while?
Exactly as iceiceice said, while, do, if and else are reserved keywords in Lua, and as such cannot be used as function names. This is the same problem that I faced when refactoring the [if] tag to implement [elseif]: instead of writing

Code: Select all

wml_actions.if( cfg )
I had to access the table with the square brackets operator and assign an anonymous function:

Code: Select all

wml_actions["if"] = function( cfg )
In you case, the only possible workaround that comes to my mind is to write the while tag as a regular WML table, with all the brackets (and related mistakes :annoyed: ) that this solution requires.
Current maintainer of these add-ons, all on 1.16:
The Sojournings of Grog, Children of Dragons, A Rough Life, Wesnoth Lua Pack, The White Troll (co-author)
gfgtdf
Developer
Posts: 1432
Joined: February 10th, 2013, 2:25 pm

Re: Returning a WML tag table with .while

Post by gfgtdf »

It is possible to do the same in his case:

Code: Select all

    function test()
      return tag.option
      {
        message = "&" .. "ball-green.png" .. "=" .. "Message",
       
        tag.command
        {
          tag["while"]
          {
            tag.variable
            {
              name = "music_repeating1",
              value = 1
            },
           
            tag["do"]
            {
              tag.message
              {
                speaker = "narrator",
                message = "",
               
                tag.option
                {
                  message = "&" .. "ball-red.png" .. "=" .. "Message",
                 
                  tag.command
                  {
                    tag.set_variable
                    {
                      name = "music_repeating1",
                      value = "$empty"
                    }
                  }
                }
              }
            }
          }
        }
      }
    end

Scenario with Robots SP scenario (1.11/1.12), allows you to build your units with components, PYR No preperation turn 1.12 mp-mod that allows you to select your units immideately after the game begins.
User avatar
Pentarctagon
Project Manager
Posts: 5564
Joined: March 22nd, 2009, 10:50 pm
Location: Earth (occasionally)

Re: Returning a WML tag table with .while

Post by Pentarctagon »

gfgtdf wrote:It is possible to do the same in his case:
That worked, thanks.

A related question now that that's solved: Is there any kind of performance difference one way or the other compared to straight WML if I were to make something semi-complex this way?
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
gfgtdf
Developer
Posts: 1432
Joined: February 10th, 2013, 2:25 pm

Re: Returning a WML tag table with .while

Post by gfgtdf »

For most wml action like [message] or similar the time to execute the action is bigger than the time to parse the wml in lua or in wml, so that doesn't really matter. Otherwie local lua variables are much faster for calculating than wml varaibles. But this also only matters if you do a lot variable stuff.

But why do you want to use action.message with options? wesnoth.show_dialog is much cooler :).
Scenario with Robots SP scenario (1.11/1.12), allows you to build your units with components, PYR No preperation turn 1.12 mp-mod that allows you to select your units immideately after the game begins.
User avatar
Pentarctagon
Project Manager
Posts: 5564
Joined: March 22nd, 2009, 10:50 pm
Location: Earth (occasionally)

Re: Returning a WML tag table with .while

Post by Pentarctagon »

Currently 99% of the add-on is in WML, and the current extent of my lua knowledge is limited to basic string manipulation that WML can't do. So I figured it would be best to do this first to learn what's going on since it's really similar, then mess with moving stuff to show_dialog etc afterwards. I didn't want to trudge through something completely new and different only find out halfway through that it isn't actually possible due to something like tag.while (if there wasn't a workaround).
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
gfgtdf
Developer
Posts: 1432
Joined: February 10th, 2013, 2:25 pm

Re: Returning a WML tag table with .while

Post by gfgtdf »

Im quite sure that you can write everything that is possible in wml also with lua without a single [event] just with [lua].


Why do you want to port your code to lua?
Scenario with Robots SP scenario (1.11/1.12), allows you to build your units with components, PYR No preperation turn 1.12 mp-mod that allows you to select your units immideately after the game begins.
User avatar
Pentarctagon
Project Manager
Posts: 5564
Joined: March 22nd, 2009, 10:50 pm
Location: Earth (occasionally)

Re: Returning a WML tag table with .while

Post by Pentarctagon »

gfgtdf wrote:Why do you want to port your code to lua?
It will hopefully be easier to desynchronize variables and certain actions if everything is in lua rather than trying to make some frankenstein mishmash of WML with embedded lua everywhere.
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
User avatar
Pentarctagon
Project Manager
Posts: 5564
Joined: March 22nd, 2009, 10:50 pm
Location: Earth (occasionally)

Re: Returning a WML tag table with .while

Post by Pentarctagon »

I started experimenting with show_dialog and I have a question about button ids:

What is a valid id? I have the following code:

Code: Select all

function test_menu()
  dialog =
  {
    tag.tooltip
    {
      id = "tooltip_large"
    },
    tag.helptip
    {
      id = "tooltip_large"
    },
    tag.grid
    {
      tag.row
      {
        tag.column
        {
          tag.button
          {
            id = "ok",
            label = "Exit",
            return_value = 0
          }
        }
      },
      tag.row
      {
        tag.column
        {
          tag.button
          {
            id = "cancel",
            label = "Mute",
            return_value = 1
          }
        }
      }
    }
  }
  
  return dialog
end
And then a loop for it elsewhere:

Code: Select all

        doTest = 1
        while doTest == 1 
        do
          doTest = wesnoth.show_dialog(test_menu())
        end
If the id of the first button's id is "ok" then I can exit the menu, but if I change the button's id to anything else like "exit" or "asdasda" then I can't.
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
gfgtdf
Developer
Posts: 1432
Joined: February 10th, 2013, 2:25 pm

Re: Returning a WML tag table with .while

Post by gfgtdf »

Any id is valid but some ids (like "ok") have some special meaning like 'close dialog on click'.

If you want to make a button that closed the dialog on click, another option is to add a value return_value=<integer> attribute to the button which then results in this integer beeing returned by show_dialog if the button was clicked.


EDIT: i just saw that you do have return_value, will look at the c++ code why it doesnt work.

EDIT2: ok it seems like '0' is th default value for return_value, so the cpp code cannot make a difference between 0 and not specifying return_value, just not using '0' as a return_value should fix the problem.
Scenario with Robots SP scenario (1.11/1.12), allows you to build your units with components, PYR No preperation turn 1.12 mp-mod that allows you to select your units immideately after the game begins.
User avatar
Pentarctagon
Project Manager
Posts: 5564
Joined: March 22nd, 2009, 10:50 pm
Location: Earth (occasionally)

Re: Returning a WML tag table with .while

Post by Pentarctagon »

What worked:

Code: Select all

          tag.button
          {
            id = "exit",
            label = "Exit",
            return_value = 2
          }
What didn't work:

Code: Select all

          tag.button
          {
            id = "exit",
            label = "Exit",
            return_value = 0
          }
and

Code: Select all

          tag.button
          {
            id = "exit",
            label = "Exit"
          }
So it works if I return anything but the default value.
99 little bugs in the code, 99 little bugs
take one down, patch it around
-2,147,483,648 little bugs in the code
Post Reply