Starfinder Playlist
  1. #1
    phantomwhale's Avatar
    Join Date
    Aug 2007
    Location
    Melbourne, Australia
    Posts
    1,370

    Ordered window lists

    Had a bit of a ramble in a different thread, but today has bought me to a core understanding that I think was lost on me - is it true to say we don't have ordered window lists ?

    I understand we can set the onSortCompare() function, and maybe that's what I need here, but I want a list that will just be implicitly ordered. So every newly added entry is always the "last" entry.

    Right now this is not the case. If you create a three entry list (id-0001, id-0002 and id-0003) and delete the middle entry, then the next entry you create will be id-0002. It will appear on the bottom of the window list, but once the window is closed and reopened, it then appears in the middle of the list.

    So one thought is I need to override window creation to ensure the generated id number is always the latest one (e.g. don't reuse missing sequence numbers) - and then the default sorting works for me. Or maybe I need to add a hidden "order" number on the elements and the list itself to facilitate this ? The advantage of that is I could later add buttons to resort the list later on, and changing node values is easier and less client side-effect prone that changing database node names.

    Has anyone already done something like this ? Most window lists seem to be sorted on name in the rulesets I've looked at, but I need a list of grouped enemies, and I don't want the order changing randomly - plus I want to be able to figure out who is the leader from the database nodes alone, as I have a problem using the library functions to access windowlists within windowlists on the client side (they appear as blank, even though the data has been sent over).

    -PW-
    Former SW ruleset / Deadlands extension author. Now I just wanna play a few games. And maybe hack. A little.

  2. #2
    I'd use a hidden 'order' field on the window entries and sort on those. You'd need some code to work out what the next value should be: for short lists, you could iterate over the list once, retrieve the current highest value, and then add 1 to it. Unfortunately you can't just take the size of the list (#entries) and add 1, if items can be deleted from the middle of it.

    Stuart

  3. #3
    The other option is that you could create the database records under the windowlist data node explicitly using any valid XML name, instead of the default window creation logic. The id-XXXXX format is just the default format for windowlist creation.

    The other thing to mention is that the sorting is not stable within FG unless your onSortCompare function has a unique value to filter on. (i.e. list elements will constantly reshuffle) This is why I added the w1.getDatabaseNode().getName() < w2.getDatabaseNode().getName() as the last line in all of the onSortCompare functions in the 3.5E ruleset revision.

    Regards,
    JPG

  4. #4
    phantomwhale's Avatar
    Join Date
    Aug 2007
    Location
    Melbourne, Australia
    Posts
    1,370
    Yeah, I had just noticed that the "default" sorting sometimes fails too ! (although the first element is always the same, so that was all I really needed).

    Will add the "sort by node name" function to lists as the default, but may go for a hidden ordering flag to allow me to reorder elements within a list by changing a single node value, rather than changing a node name (which would technically need to be an add and delete, I think, as nodes cannot be programatically renamed, probably for a good reason too !)

    Thanks for pitching in guys, starting to see some light at the end of the tunnel on this one.
    Former SW ruleset / Deadlands extension author. Now I just wanna play a few games. And maybe hack. A little.

  5. #5
    phantomwhale's Avatar
    Join Date
    Aug 2007
    Location
    Melbourne, Australia
    Posts
    1,370
    First cut at this - have hit a problem with the super variable though.

    Firstly, I created a nice ordered list template:

    Code:
    <template name="orderedlist">
      <windowlist>
        <script file="scripts/template_orderedlist.lua" />
      </windowlist>
    </template>
    And then the code as follows:

    Code:
    local lastIndex = 1
    local orderingNode = "order"
    
    function onInit()
      for _,node in pairs(getDatabaseNode().getChildren()) do
        lastIndex = math.max(lastIndex, node.getChild(orderingNode) and node.getChild(orderingNode).getValue() or 1)
      end
      lastIndex = lastIndex + 1
      
      -- tried to create window here (see notes)
    end
    
    -- override creating windows to set the order field
    function createWindow(...)
      Util.debug("Creating ordered window")
      win = super.createWindow(...)
      if not NodeManager.get(win.getDatabaseNode(), orderingNode) then
        local ordernode = NodeManager.createChild(win.getDatabaseNode(), orderingNode, "number")
        ordernode.setValue(lastIndex)
        lastIndex = lastIndex + 1
      end
      return win
    end
    
    -- Sort by order index value - maintains list order
    function onSortCompare(w1, w2)
      if not w1.getDatabaseNode().getChild(orderingNode) then 
        return false
      elseif not w2.getDatabaseNode().getChild(orderingNode) then
        return true
      else
        return w1.getDatabaseNode().getChild(orderingNode).getValue() > w2.getDatabaseNode().getChild(orderingNode).getValue()
      end
    end
    What I noted was the debug line never got called, and the ordering nodes were not being set.

    How odd, I thought. so looked around the code for a while, and then tried adding in two different commands in the onInit() method. Firstly I added self.createWindow() as the last line. The effect of this were all new lists had an extra blank window entry - but still no calls to the debug method ?

    Secondly, I tried super.createWindow() and was told I had a Script Error trying to index global 'super'. So it seems that in my template that wraps the windowlist object, I don't have a super environment variable to refer back to the original createWindow() method ? Furthermore, attempts to call createWindow(), even using the self variable (which should call the overloading method, always use the in built method that I am unable to access ?

    So my conclusion is that createWindow() is impossible to overload ? (I think getDatabaseNode() also behaves like this). I am confused here, as I'm sure that I've overridden this method successfully before in other coding experiments, but admittedly can't be positive of that.

    Moon_wizard - any chance of confirming this ?

    I guess I can try subscribing to the best "event" I've got as a different strategy, which is probably onChildAdded() on the database node. But wanted to see if this solution works first, as it seems more elegant right now !
    Former SW ruleset / Deadlands extension author. Now I just wanna play a few games. And maybe hack. A little.

  6. #6
    phantomwhale's Avatar
    Join Date
    Aug 2007
    Location
    Melbourne, Australia
    Posts
    1,370
    Ok, popped a getDatabaseNode().onChildAdded = onWindowCreated event handler into the onInit() method and added the following to replace the createWindow(...) overload :

    Code:
    function onWindowCreated(source, child)
    	if not NodeManager.get(child, orderingNode) then
    		local ordernode = NodeManager.createChild(child, orderingNode, "number")
    		ordernode.setValue(lastIndex)
    		lastIndex = lastIndex + 1
    	end
    end
    Looks pretty good now. Still interested in the use of super to refer to "core engine" methods though.
    Former SW ruleset / Deadlands extension author. Now I just wanna play a few games. And maybe hack. A little.

  7. #7
    I'm pretty sure that you can not overload the default function names for FG objects. However, you can override the function names from derived objects (i.e. templates).

    This means that you want to avoid using the same function names as the ones FG provides. It also means that you can not override the FG internal functions, which is good since the internal functions are not called through LUA and would not see the overloads anyways.

    Regards,
    JPG

Thread Information

Users Browsing this Thread

There are currently 1 users browsing this thread. (0 members and 1 guests)

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
5E Product Walkthrough Playlist

Log in

Log in