Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use standard pairs/ipairs implementation #137

Merged
merged 6 commits into from
Oct 23, 2020
Merged

Conversation

actboy168
Copy link
Contributor

This change removes the replacement of ipairs and pairs in the Lua standard library.

For ipairs, the following two pieces of code are equivalent. So we only need to implement __index correctly to make ipairs work correctly. In fact, __ipairs has been removed after Lua5.3. So we no longer need to implement __ipairs.

for i, v in ipairs(t) do
  -- do something
end
local i = 1
while true do
  local v = t[i]
  if v == nil then
    break
  end
  -- do something
  i = i + 1
end

In addition, this change also resolves #95.

@mikke89
Copy link
Owner

mikke89 commented Oct 20, 2020

Thanks a lot for the contribution! I'll take a closer look at it as soon as possible.

I'd like to see some feedback from others who are using the Lua plugin.
@IronicallySerious @JFT90 Are you able to test this and provide some feedback?

@twaritwaikar
Copy link

twaritwaikar commented Oct 20, 2020

@mikke89 I will be able to test this as soon as I get my wifi back :p

However, I will say that in our copy of RmlUi we had commented out the RmlLua code which used to override the ipairs() and pairs() functions. This is because Lua was trying to use the RmlLua provided overrides whenever a third party Lua library or even our engine embedded Lua scripts wanted to iterate on a table, and that was only resulting in Lua type errors. So this is a very welcome change indeed.

@mikke89
Copy link
Owner

mikke89 commented Oct 20, 2020

@IronicallySerious Great, I'll hold on for your comments then :)

@mikke89 mikke89 added the Lua Lua binding issues label Oct 21, 2020
@twaritwaikar
Copy link

This seems to be working well! @mikke89
I am trying this code:

	.
	.
	.
	<head>
		<script>
Demo = Demo or {}

function Demo.toggle(document, enabled)
	for k,v in pairs(document:GetElementById("rootex_button").attributes) do
		print(k .. ": " .. v)
	end
	print("Hi")
end		
		</script>
	</head>
	<body>
		<p id="transition_test"> This is a sample! </p>
		<br />
		<img
			id="rootex_button"
			onmousedown="Demo.toggle(document, true)"
			onmouseup="Demo.toggle(document, false)"
			src="../rootex.png"
			width=100 
			height=100 
		/>
	</body>

The output I get is:

CustomSystemInterface::LogMessage: RmlUi Info: height: 100
CustomSystemInterface::LogMessage: RmlUi Info: id: rootex_button
CustomSystemInterface::LogMessage: RmlUi Info: onmousedown: Demo.toggle(document, true)
CustomSystemInterface::LogMessage: RmlUi Info: onmouseup: Demo.toggle(document, false)
CustomSystemInterface::LogMessage: RmlUi Info: src: ../rootex.png
CustomSystemInterface::LogMessage: RmlUi Info: width: 100
CustomSystemInterface::LogMessage: RmlUi Info: Hi
CustomSystemInterface::LogMessage: RmlUi Info: height: 100
CustomSystemInterface::LogMessage: RmlUi Info: id: rootex_button
CustomSystemInterface::LogMessage: RmlUi Info: onmousedown: Demo.toggle(document, true)
CustomSystemInterface::LogMessage: RmlUi Info: onmouseup: Demo.toggle(document, false)
CustomSystemInterface::LogMessage: RmlUi Info: src: ../rootex.png
CustomSystemInterface::LogMessage: RmlUi Info: width: 100
CustomSystemInterface::LogMessage: RmlUi Info: Hi

@mikke89
Copy link
Owner

mikke89 commented Oct 22, 2020

@IronicallySerious Thanks for testing!

@actboy168 Thanks again for this long needed change. I found a few issues while testing this, which needs to be fixed before I can merge it:


This example is taken from the documentation:

function OnClick()
	local element = g_document:GetElementById('button')
	for i,child in ipairs(element.child_nodes) do
		address = child.tag_name

		if child.id ~= '' then
			address = address .. '#' .. child.id
		end

		for token in string.gmatch(child.class_name, '[%w]+') do
		   address = address .. '.' .. token
		end

		print(i .. address)
	end
end

With the following RML:

<button id="button"><span id="test">Exit</span><p>Hello</p><div test="5">A</div></button>

It's missing the first child element. Ie, now it outputs:

1p
2div

Previously:

0span#test
1p
2div

This also appears to be missing the first option:

function Test(document)
	local element = Element.As.ElementFormControlSelect(document:GetElementById('color'))	
	for i,entry in pairs(element.options) do
		print(i .. ': ' .. entry.value)
	end
end

RML:

<select name="colour" id="color">
	<option value="233,116,81">Burnt Sienna</option>
	<option value="127,255,0">Chartreuse</option>
	<option value="21,96,189">Denim</option>
	<option value="246,74,138">French Rose</option>
	<option value="255,0,255">Fuschia</option>
	<option value="218,165,32">Goldenrod</option>
	<option selected value="255,255,240">Ivory</option>
</select>

Output:

1: 127,255,0
2: 21,96,189
3: 246,74,138
4: 255,0,255
5: 218,165,32
6: 255,255,240

This results in an infinite loop:

for i,context in ipairs(rmlui.contexts) do
	print('Context ' .. i .. ': ' .. context.name)
end

@actboy168
Copy link
Contributor Author

These problems seem to be caused by the difference between the definition of __index and the usage habits of lua.

Unlike C++, Lua's array index starts from 1, but now the array index constructed from rmlui starts from 0. So ipairs will go wrong. I think the behavior of __index should be modified, otherwise element[0] represents the first element which is also a confusing thing for Lua users.

For infinite loops, this is because the context's __index method always returns the last element for indexes larger than the size of the array, which makes ipairs think that this is an infinite array.

@actboy168
Copy link
Contributor Author

@mikke89 If you think it is worth modifying, I will provide a patch.

@cloudwu
Copy link
Contributor

cloudwu commented Oct 23, 2020

I think following the lua practices by RmlLua would be better :) I mean everything in the container is base 1 instead of base 0.

@mikke89
Copy link
Owner

mikke89 commented Oct 23, 2020

I agree with you guys, it seems appropriate to use 1-indexing for the Lua code.

@actboy168 Please feel free to patch this, thanks!

@actboy168
Copy link
Contributor Author

@mikke89 I have updated the patch to solve the above problem.

@mikke89 mikke89 merged commit 551ea37 into mikke89:master Oct 23, 2020
@mikke89
Copy link
Owner

mikke89 commented Oct 23, 2020

Thank you! Looks good to me now.

@twaritwaikar
Copy link

This change is awesome!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Lua Lua binding issues
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Problem with lua bindings overriding global table functions
4 participants