Il semble que les cookies ne soient pas activés dans votre navigateur. Veuillez activer les cookies pour garantir une expérience du site optimale.
Affichage des résultats 1 à 3 sur 3
  1. #1
    Date d'inscription
    mars 2007
    Messages
    1 171

    ListBox:Sort() causes index errors

    Using the ListBox:Sort() method causes issues with the listbox's internal indexes for its elements so that other methods like RemoveItemAt() and ClearItems() no longer function properly. I first noticed this when, after sorting a listbox control, I called ClearItems and would sometimes have items still displayed in the listbox even though GetItemCount() returned 0 and the items were no longer controllable. I did a bit of research and realized that even using RemoveItemAt() would leave ghost items because it seemed to be leaving a gap in the internal list of indexes so that calling GetItem() for that index returned nil and one of the legitimate items became unaccessible.

    An example of this can be seen with the following code segments:
    Code:
    local index;
    local items={"duidei","dfaho","oubo","avoaleb","coabfe","dubso","oaiubd","aldfhu","fsouhde"}
    itemList=Turbine.UI.ListBox()
    for index=1,#items do
     local tmpItem=Turbine.UI.Label()
     local tmpVal=items[index]
     tmpItem:SetParent(itemList)
     tmpItem:SetSize(100,20)
     tmpItem:SetText("val="..tostring(tmpVal).." orig_index="..tostring(index) )
     tmpItem.index=index
     itemList:AddItem(tmpItem)
    end
    Turbine.Shell.WriteLine("before removal")
    for index=1,itemList:GetItemCount() do
      if itemList:GetItem(index) == nil then
         Turbine.Shell.WriteLine("item at:"..tostring(index).." is nil")
      else
         Turbine.Shell.WriteLine("item at:"..tostring(index).." orig_index="..tostring(itemList:GetItem(index).index))
      end
    end
    itemList:RemoveItemAt(5)
    Turbine.Shell.WriteLine("after removal")
    for index=1,itemList:GetItemCount() do
      if itemList:GetItem(index) == nil then
         Turbine.Shell.WriteLine("item at:"..tostring(index).." is nil")
      else
         Turbine.Shell.WriteLine("item at:"..tostring(index).." orig_index="..tostring(itemList:GetItem(index).index))
      end
    end
    Using this code works correctly, the entry at index 5 is removed.
    But, by adding a sort and removing the item at index 5:
    Code:
    local index;
    local items={"duidei","dfaho","oubo","avoaleb","coabfe","dubso","oaiubd","aldfhu","fsouhde"}
    itemList=Turbine.UI.ListBox()
    for index=1,#items do
     local tmpItem=Turbine.UI.Label()
     local tmpVal=items[index]
     tmpItem:SetParent(itemList)
     tmpItem:SetSize(100,20)
     tmpItem:SetText("val="..tostring(tmpVal).." orig_index="..tostring(index) )
     tmpItem.index=index
     itemList:AddItem(tmpItem)
    end
    Turbine.Shell.WriteLine("before sort")
    for index=1,itemList:GetItemCount() do
      if itemList:GetItem(index) == nil then
         Turbine.Shell.WriteLine("item at:"..tostring(index).." is nil")
      else
         Turbine.Shell.WriteLine("item at:"..tostring(index).." orig_index="..tostring(itemList:GetItem(index).index))
      end
    end
    itemList:Sort(function(elem1,elem2) if elem1:GetText()<elem2:GetText() then return true end end)
    Turbine.Shell.WriteLine("before removal")
    for index=1,itemList:GetItemCount() do
      if itemList:GetItem(index) == nil then
         Turbine.Shell.WriteLine("item at:"..tostring(index).." is nil")
      else
         Turbine.Shell.WriteLine("item at:"..tostring(index).." orig_index="..tostring(itemList:GetItem(index).index))
      end
    end
    itemList:RemoveItemAt(5)
    Turbine.Shell.WriteLine("after removal")
    for index=1,itemList:GetItemCount() do
      if itemList:GetItem(index) == nil then
         Turbine.Shell.WriteLine("item at:"..tostring(index).." is nil")
      else
         Turbine.Shell.WriteLine("item at:"..tostring(index).." orig_index="..tostring(itemList:GetItem(index).index))
      end
    end
    we get a nil item at index 3 which contained the entry that was ORIGINALLY (before the sort) at index 5. Somehow, the sort is not updating the internal index of the entry so the wrong entry is getting removed and is leaving an inaccessible entry.

  2. #2
    Date d'inscription
    mai 2009
    Messages
    176
    Citation Envoyé par Garan Voir le message
    Using the ListBox:Sort() method causes issues with the listbox's internal indexes for its elements so that other methods like RemoveItemAt() and ClearItems() no longer function properly. I first noticed this when, after sorting a listbox control, I called ClearItems and would sometimes have items still displayed in the listbox even though GetItemCount() returned 0 and the items were no longer controllable. I did a bit of research and realized that even using RemoveItemAt() would leave ghost items because it seemed to be leaving a gap in the internal list of indexes so that calling GetItem() for that index returned nil and one of the legitimate items became unaccessible.

    An example of this can be seen with the following code segments:
    Code:
    local index;
    local items={"duidei","dfaho","oubo","avoaleb","coabfe","dubso","oaiubd","aldfhu","fsouhde"}
    itemList=Turbine.UI.ListBox()
    for index=1,#items do
     local tmpItem=Turbine.UI.Label()
     local tmpVal=items[index]
     tmpItem:SetParent(itemList)
     tmpItem:SetSize(100,20)
     tmpItem:SetText("val="..tostring(tmpVal).." orig_index="..tostring(index) )
     tmpItem.index=index
     itemList:AddItem(tmpItem)
    end
    Turbine.Shell.WriteLine("before removal")
    for index=1,itemList:GetItemCount() do
      if itemList:GetItem(index) == nil then
         Turbine.Shell.WriteLine("item at:"..tostring(index).." is nil")
      else
         Turbine.Shell.WriteLine("item at:"..tostring(index).." orig_index="..tostring(itemList:GetItem(index).index))
      end
    end
    itemList:RemoveItemAt(5)
    Turbine.Shell.WriteLine("after removal")
    for index=1,itemList:GetItemCount() do
      if itemList:GetItem(index) == nil then
         Turbine.Shell.WriteLine("item at:"..tostring(index).." is nil")
      else
         Turbine.Shell.WriteLine("item at:"..tostring(index).." orig_index="..tostring(itemList:GetItem(index).index))
      end
    end
    Using this code works correctly, the entry at index 5 is removed.
    But, by adding a sort and removing the item at index 5:
    Code:
    local index;
    local items={"duidei","dfaho","oubo","avoaleb","coabfe","dubso","oaiubd","aldfhu","fsouhde"}
    itemList=Turbine.UI.ListBox()
    for index=1,#items do
     local tmpItem=Turbine.UI.Label()
     local tmpVal=items[index]
     tmpItem:SetParent(itemList)
     tmpItem:SetSize(100,20)
     tmpItem:SetText("val="..tostring(tmpVal).." orig_index="..tostring(index) )
     tmpItem.index=index
     itemList:AddItem(tmpItem)
    end
    Turbine.Shell.WriteLine("before sort")
    for index=1,itemList:GetItemCount() do
      if itemList:GetItem(index) == nil then
         Turbine.Shell.WriteLine("item at:"..tostring(index).." is nil")
      else
         Turbine.Shell.WriteLine("item at:"..tostring(index).." orig_index="..tostring(itemList:GetItem(index).index))
      end
    end
    itemList:Sort(function(elem1,elem2) if elem1:GetText()<elem2:GetText() then return true end end)
    Turbine.Shell.WriteLine("before removal")
    for index=1,itemList:GetItemCount() do
      if itemList:GetItem(index) == nil then
         Turbine.Shell.WriteLine("item at:"..tostring(index).." is nil")
      else
         Turbine.Shell.WriteLine("item at:"..tostring(index).." orig_index="..tostring(itemList:GetItem(index).index))
      end
    end
    itemList:RemoveItemAt(5)
    Turbine.Shell.WriteLine("after removal")
    for index=1,itemList:GetItemCount() do
      if itemList:GetItem(index) == nil then
         Turbine.Shell.WriteLine("item at:"..tostring(index).." is nil")
      else
         Turbine.Shell.WriteLine("item at:"..tostring(index).." orig_index="..tostring(itemList:GetItem(index).index))
      end
    end
    we get a nil item at index 3 which contained the entry that was ORIGINALLY (before the sort) at index 5. Somehow, the sort is not updating the internal index of the entry so the wrong entry is getting removed and is leaving an inaccessible entry.
    Just checked in a change that should hopefully fix this.

  3. #3
    Date d'inscription
    juin 2011
    Messages
    681
    Thurallor, Warden of Landroval

 

 

Règles de messages

  • Vous ne pouvez pas créer de nouvelles discussions
  • Vous ne pouvez pas envoyer des réponses
  • Vous ne pouvez pas envoyer des pièces jointes
  • Vous ne pouvez pas modifier vos messages
  •  

La session de ce formulaire a expiré. Vous devez recharger la page.

Recharger