Page 1 of 3

To Game-Devs: The "n" entry in array-like tables was removed

Posted: 21 Jun 2011, 20:55
by hoijui
what was done
All array-like Lua tables that are created/filled by the engine, got the "n" member removed, which contained the arrays size. This is as of now in current spring master, and will be in the next release.

necessary changes
Instead of reading the "n" member of tables to get their size, you have to use the # operator now.
This change is backwards compatible; if you apply it to your Lua, it will also work in current release.
-> do it asap! ;-)
example:

Code: Select all

-      for i=1,ud.weapons.n do
+      for i=1,#ud.weapons do
reasoning
Your Lua code will be a bit cleaner, and more portable, and in theory it would be a bit faster (unnoticeable in practice).

how to test
windows installer: http://springrts.com/dl/buildbot/defaul ... 6b01f8.exe
linux: git clone git://github.com/hoijui/spring.git

related commits
https://github.com/spring/spring/commit ... 9779c9f7a9
https://github.com/spring/spring/commit ... a810fa9336
https://github.com/spring/spring/commit ... 9c5c883d60
https://github.com/spring/spring/commit ... 014b9209f7

affected Lua stuff
No guarantee for completeness:

Code: Select all

LayoutButtons
CommandFallback
AllowCommand
GetUnitPieceList
GetUnitPieceInfo
UnitDef.buildOptions
UnitDef.weapons
UnitDef.sounds.* =>
UnitDef.sounds.select
UnitDef.sounds.ok
UnitDef.sounds.arrived
UnitDef.sounds.build
UnitDef.sounds.repair
UnitDef.sounds.working
UnitDef.sounds.underattack
UnitDef.sounds.cant
UnitDef.sounds.activate
UnitDef.sounds.deactivate
GetSelectedUnits
GetActiveCmdDescs
GetConsoleBuffer
GetKeyBindings
GetActionHotKeys
GetGroupUnits
GetGroupUnitsSorted
GetGroupUnitsCounts
GetUnitCmdDescs
UnpackU8
UnpackU16
UnpackU32
UnpackS8
UnpackS16
UnpackS32
UnpackF32
WeaponDef.hitSound
WeaponDef.fireSound
GetPlayerRoster
GetPressedKeys
GetGlobalTexNames
DirList
SubDirs
GetAllyTeamList
GetTeamList
GetPlayerList
GetTeamStatsHistory
GetAllUnits
GetTeamUnits
GetTeamUnitsSorted
GetTeamUnitsByDefs
GetUnitsInRectangle
GetUnitsInBox
GetUnitsInCylinder
GetUnitsInSphere
GetUnitsInPlanes
GetUnitIsTransporting
GetUnitCommands
GetFactoryCommands
GetCommandQueue
edit:
added:
GetAllyTeamList
GetTeamList
GetPlayerList
GetTeamStatsHistory
GetAllUnits
GetTeamUnits
GetTeamUnitsSorted
GetTeamUnitsByDefs
GetUnitsInRectangle
GetUnitsInBox
GetUnitsInCylinder
GetUnitsInSphere
GetUnitsInPlanes
GetUnitIsTransporting
GetUnitCommands
GetFactoryCommands
GetCommandQueue
removed:
GetSelectedUnitsSorted
GetSelectedUnitsCounts

Re: To Game-Devs: The "n" entry in array-like tables was removed

Posted: 21 Jun 2011, 21:03
by FLOZi
Can a mod/admin turn this into an announcement or at least sticky it? 8)

Thanks for the heads up.

Re: To Game-Devs: The "n" entry in array-like tables was removed

Posted: 21 Jun 2011, 22:09
by MidKnight
Yay, cleaner code! :mrgreen:

Re: To Game-Devs: The "n" entry in array-like tables was removed

Posted: 21 Jun 2011, 23:10
by hoijui
Kloot made an other related commit, removing more n's (and re-adding two falsely removed ones). first post is updated.

Re: To Game-Devs: The "n" entry in array-like tables was removed

Posted: 21 Jun 2011, 23:11
by knorke
can you please give the link to a (win32) .exe with those changes?

Re: To Game-Devs: The "n" entry in array-like tables was removed

Posted: 21 Jun 2011, 23:25
by Pako
Good, probably 100 hidden bugs fixed.

I haven't about never remembered this 'n' entry and few times had to learn the hard way.

Re: To Game-Devs: The "n" entry in array-like tables was removed

Posted: 21 Jun 2011, 23:51
by smoth
How long until release? Why is this being done so suddenly? It may break a good deal of projects

Re: To Game-Devs: The "n" entry in array-like tables was removed

Posted: 22 Jun 2011, 00:24
by knorke
base\springcontent.sdz\LuaGadgets\Gadgets\unit_script.lua
this file uses weapons.n in two places
->lua unit scripts do not work on units with a weapon

http://springrts.com/mantis/view.php?id=2492

Re: To Game-Devs: The "n" entry in array-like tables was removed

Posted: 22 Jun 2011, 09:08
by sunspot
Good change, I personally found it weird anyhow asking array.getn() and not getting the real amount of elements if there is a small gap somewhere.

Re: To Game-Devs: The "n" entry in array-like tables was removed

Posted: 22 Jun 2011, 11:07
by Licho
Note you cannot use # array size in keyed tables.
For those, you must enumerate and count all elements in lula.

Re: To Game-Devs: The "n" entry in array-like tables was removed

Posted: 22 Jun 2011, 17:35
by FLOZi
Licho wrote:Note you cannot use # array size in keyed tables.
For those, you must enumerate and count all elements in lula.
Also note that if those are returned by the engine, they should still contain the .n

Re: To Game-Devs: The "n" entry in array-like tables was removed

Posted: 22 Jun 2011, 20:27
by Licho
I still see it as pretty big flaw of lua internals. .. i bet its not hard to maintiain simple counter for keyeyd entries :(
Lua itself shoudl support #

Re: To Game-Devs: The "n" entry in array-like tables was removed

Posted: 23 Jun 2011, 04:46
by abma
@knorke:

hoijui fixed it:

https://github.com/spring/spring/commit ... b12b55daa5

(maybe if others want to see how to fix it...)

Re: To Game-Devs: The "n" entry in array-like tables was removed

Posted: 23 Jun 2011, 08:59
by Beherith
What if:

Code: Select all

unitCounts.n = nil  
?

Re: To Game-Devs: The "n" entry in array-like tables was removed

Posted: 23 Jun 2011, 16:46
by FLOZi
Any widgets / gadgets counting entries and assigning n themselves should be left alone, if that is what you're asking?

Re: To Game-Devs: The "n" entry in array-like tables was removed

Posted: 24 Jun 2011, 03:24
by Google_Frog

Code: Select all

unitCounts.n = nil  
I came across this too. It seems to be a workaround to remove the n element from the table so pairs can be used without checking for n. It could be removed with 0.83 or you could rewrite the use of pairs to use #table because it seems stupid to use pairs on an iterable table.

Re: To Game-Devs: The "n" entry in array-like tables was removed

Posted: 24 Jun 2011, 19:07
by zwzsg
Or use the ipairs that was made just for that.

Re: To Game-Devs: The "n" entry in array-like tables was removed

Posted: 25 Jun 2011, 06:54
by Google_Frog
Iirc jk's lua page says ipairs is slower than "for i=1, #table do". I haven't come across a table where the #table approach fails to be equivalent to ipairs.

Re: To Game-Devs: The "n" entry in array-like tables was removed

Posted: 05 Jul 2011, 17:12
by quantum
#t is 1.0406504065041 times slower than t.n for an array of size 100
#t is 2.0826446280992 times slower than t.n for an array of size 1000
#t is 2.8423236514523 times slower than t.n for an array of size 10000
#t is 4.6935483870968 times slower than t.n for an array of size 100000
#t is 5.2921810699588 times slower than t.n for an array of size 1000000
Imo, we don't have to worry about performance, since the API usually returns small arrays.

Code: Select all

function test(size)
  local iterations = 10000000
  local t = {}
  t.n = size
  for i=1, t.n do
    t[i] = 2
  end
  local t1 = os.clock()
  for i=1, iterations do
    local _ = #t
  end
  local t2 = os.clock()
  local lengthOperatorTime = t2 - t1


  local t1 = os.clock()
  for i=1, iterations do
    local _ = t.n
  end
  local t2 = os.clock()
  local dotNTime = t2 - t1
  
  print("#t is "..lengthOperatorTime/dotNTime.." times slower than t.n for an array of size "..size)
end

test(100)
test(1000)
test(10000)
test(100000)
test(1000000)

Re: To Game-Devs: The "n" entry in array-like tables was removed

Posted: 06 Jul 2011, 06:56
by Forboding Angel
hoijui wrote:necessary changes
Instead of reading the "n" member of tables to get their size, you have to use the # operator now.
This change is backwards compatible; if you apply it to your Lua, it will also work in current release.
-> do it asap! ;-)
This is as clear as fresh horseshit.

so this: arg.n
becomes: arg
or: arg.#
or:#arg
or...

How about some proper explanations. Also, was this really freaking necessary? Perhaps just one freaking release without you guys breaking lua for no damn good reason.