Jump to content
  • 0

Update variable that resist in key value of table


nok1a
 Share

Question

I don't know why but my script does not update the value that is assigned to variable structure_count.

function STRU_dataBlockSegments()
  local STRU_structures = {}
  local structure_count = 1 -- value of that needs to be incremented
  local STRU_struct_offset = 1
  local STRU_structureNaming = {
    [1] = "Structure ("..structure_count..") :Unknown: ", 
    [2] = "Structure ("..structure_count..") :Field offset: ", 
    [3] = "Structure ("..structure_count..") :Field amount: "
  }
  local STRU_block = STRU_dataBlockSize()
  for i, v in ipairs(STRU_block) do
    STRU_structures[#STRU_structures + 1] = {address = v.address, flags = gg.TYPE_BYTE, name = STRU_structureNaming[STRU_struct_offset]}
    if STRU_struct_offset == 3 then
      STRU_struct_offset = 1
      structure_count = structure_count + 1 -- Should be incremented by one, however in the table STRU_structureNaming it remains 1.
    else
      STRU_struct_offset = STRU_struct_offset + 1
    end
  end
end
STRU_dataBlockSegments()

How do i access the table STRU_structureNaming and increment the value structure_count when condition is met?

Link to comment
Share on other sites

9 answers to this question

Recommended Posts

  • 0

It looks like you need not a table, but function that returns name for value according to two parameters: structure offset and structure count. Here is an example of such function: 

function getNameForValue(structOffset, structCount)
  local name = "Structure (" .. structCount .. ")"
  if structOffset == 1 then
    name = name .. " :Unknown: "
  elseif structOffset == 2 then
    name = name .. " :Field offset: "
  elseif structOffset == 3 then
    name = name .. " :Field amount: "
  end
  return name
end
Link to comment
Share on other sites

  • 0
9 minutes ago, MAARS said:

if it is not that mean that your condition  if STRU_struct_offset == 3 is never fulfilled 

Condition does get met:

Script ended:
structure_count:  	1
structure_count:  	2
structure_count:  	3
structure_count:  	4

But in table no update.

Link to comment
Share on other sites

  • 0
20 minutes ago, CmP said:

It looks like you need not a table, but function that returns name for value according to two parameters: structure offset and structure count. Here is an example of such function: 

function getNameForValue(structOffset, structCount)
  local name = "Structure (" .. structCount .. ")"
  if structOffset == 1 then
    name = name .. " :Unknown: "
  elseif structOffset == 2 then
    name = name .. " :Field offset: "
  elseif structOffset == 3 then
    name = name .. " :Field amount: "
  end
  return name
end

Thanks, works great.
image.thumb.png.a1437375e8e5e6774f4f8c323064b5c1.png

Do you mind if i use your example in the script? I would attach link to this threat as i did with the range function.
But i do question, if i write it in a separate function the function will be called for each loop. Will this not slow speed down drastically?

Added your function like this:

function STRU_dataBlockSegments()
  local STRU_structures = {}
  local structure_count = 1
  local STRU_struct_offset = 1
  local STRU_block = STRU_dataBlockSize()
  for i, v in ipairs(STRU_block) do
    STRU_structures[#STRU_structures + 1] = {address = v.address, flags = gg.TYPE_BYTE, name = getNameForValue(STRU_struct_offset, structure_count)}
    if STRU_struct_offset == 3 then
      STRU_struct_offset = 1
      structure_count = structure_count + 1
    else
      STRU_struct_offset = STRU_struct_offset + 1
    end
  end
  gg.addListItems(STRU_structures)
end
STRU_dataBlockSegments()

Is it appropriate like that?

Link to comment
Share on other sites

  • 0
13 minutes ago, nok1a said:

Do you mind if i use your example in the script? I would attach link to this threat as i did with the range function.

Feel free to do that. And there is no need for any credits in this case, but you can do however you prefer.

16 minutes ago, nok1a said:

But i do question, if i write it in a separate function the function will be called for each loop. Will this not slow speed down drastically?

No, it shouldn't, but if you have millions of iterations, then the difference between function and lookup table might become noticeable, in which case it may make sense to go with lookup table.

18 minutes ago, nok1a said:

Is it appropriate like that?

Yes, looks correct.

Link to comment
Share on other sites

  • 0
8 minutes ago, CmP said:

Feel free to do that. And there is no need for any credits in this case, but you can do however you prefer.

Ok, will at least put the link to this thread. I do that in any situation. Unless function became drastically modified.
 

9 minutes ago, CmP said:

No, it shouldn't, but if you have millions of iterations, then the difference between function and lookup table might become noticeable, in which case it may make sense to go with lookup table.

I won't have millions of iterations. But perhaps max a 100k, it is possible. In fact i do like to know how i do it if it would be a look up table. Because as you saw the variable in the table key value did not get updated. Can variables in tables that are stored in key value not get updated from outside the table? Perhaps i scripted it wrong. The conditions where met.

Link to comment
Share on other sites

  • 0
43 minutes ago, CmP said:

in which case it may make sense to go with lookup table

This is misunderstanding from my side. Table-only solution isn't an option for this case, because of requirement to have structure number in name. So solutions can be only function-based (table may be used in the function, but there is no gain from it in this case), but there is indeed some room for performance improvement in my example above - by avoiding string concatenation and using "string.format" instead.

Link to comment
Share on other sites

  • 0
20 hours ago, CmP said:

This is misunderstanding from my side. Table-only solution isn't an option for this case, because of requirement to have structure number in name. So solutions can be only function-based (table may be used in the function, but there is no gain from it in this case), but there is indeed some room for performance improvement in my example above - by avoiding string concatenation and using "string.format" instead.

Hmm, i don't exactly understand why string.format over string concatenation, could you perhaps explain?
I applied it like this to the script, This is ok?

-- concatenation test

function getNameForValue(STRU_structOffset, STRU_structCount, addr, val, fieldOff, nam_0, nam_1, nam_2)
  local name = ""
  if STRU_structOffset == 1 then
    name = string.format(nam_0, STRU_structCount, "Unknown")
  elseif STRU_structOffset == 2 then
    addressJump = fieldOff + val*8
    name = string.format(nam_1, STRU_structCount, "Start address field offset: => 0x", string.upper(string.format("%x", fieldOff + val*8)))
  elseif STRU_structOffset == 3 then
    STRU_Field_dataBlockSize(addressJump, val, STRU_structCount)
    name = string.format(nam_2, STRU_structCount, "Field amount: ", val)
  end
  return name
end

function STRU_Field_dataBlockSize(FieldOffsetAddr, b, c)
  local name = "Structure Field Data Block: (%d): Count => %d%s%d"
  local fieldSize = {}
  local loop = 0
  for i = 1, b do
    fieldSize[#fieldSize + 1] = {
      address = FieldOffsetAddr + loop, 
      flags = gg.TYPE_QWORD, 
      name = string.format(name, c, i,"/", b)
    }
    loop = loop + 0x8
  end
  gg.addListItems(fieldSize)
  c = c + 1
end

function STRU_dataBlockSegments()
  local name_0 = "Structure (%d): %s"
  local name_1 = "Structure (%d): %s%s"
  local name_2 = "Structure (%d): %s%d"
  local STRU_structures = {}
  local loop = 0
  local structure_count = 1
  local STRU_struct_offset = 1
  local fieldOffsetCalc = validSignatures[3][4].address + validSignatures[3][2].value + 0xC
  local STRU_block = STRU_dataBlockSize()
  for i, v in ipairs(STRU_block) do
    STRU_structures[#STRU_structures + 1] = {address = v.address, flags = v.flags, value = v.value, name = getNameForValue(STRU_struct_offset, structure_count, v.address, v.value, fieldOffsetCalc, name_0, name_1, name_2)..""}
    if STRU_struct_offset == 3 then
      STRU_struct_offset = 1
      structure_count = structure_count + 1
    else
      STRU_struct_offset = STRU_struct_offset + 1
    end
  end
  gg.addListItems(STRU_structures)
end
STRU_dataBlockSegments()


 

Edited by nok1a
Added relevant functions to which concatenation has been added
Link to comment
Share on other sites

  • 0
22 minutes ago, nok1a said:

Hmm, i don't exactly understand why string.format over string concatenation, could you perhaps explain?

Because string concatenation produces new string and there are multiple usages of it in the code.

29 minutes ago, nok1a said:

I applied it like this to the script, This is ok?

Mostly yes, but format strings don't need to be passed as parameters in this case and instead of separate call to format address, do it in the same one.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.