• Reset of canvas ID's

    From Shaun Deacon@21:1/5 to All on Thu Sep 1 15:39:39 2022
    I'm not expecting any action on following, I'm just curious about the reasoning behind it and perhaps I have overlooked a detail...

    When an object is created on a canvas, the canvas ID is returned.

    Looking at the C code, this seems to be stored in "canvasPtr->nextId" which is initialized to 1 on creation of the widget and incremented each time an object is created.

    However, the value is never reset.

    Assuming I have a canvas object $c, I would expect "$c delete all" to reset the 'nextId' value to 1 internally because all items are deleted. Currently, a new object created on the canvas (after the delete) returns an ID which is 'nextId++' where 'nextId'
    was the last object created before the deletion.

    Is there a reason this field is not reset ?

    In one of my applications I have a "replay" function which saves the current display by saving serialized canvas data. When the user wants to replay, the current canvas display is deleted and recreated from the serialized data. Unfortunately, I have
    other data that is stored which relies on the original canvas ID's - this has to be adjusted when the new canvas objects are created. If the initial canvas ID were reset, this would be simplified for me.

    best regards
    Shaun

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Arjen Markus@21:1/5 to Shaun Deacon on Fri Sep 2 00:18:29 2022
    On Friday, September 2, 2022 at 12:39:42 AM UTC+2, Shaun Deacon wrote:
    I'm not expecting any action on following, I'm just curious about the reasoning behind it and perhaps I have overlooked a detail...

    When an object is created on a canvas, the canvas ID is returned.

    Looking at the C code, this seems to be stored in "canvasPtr->nextId" which is initialized to 1 on creation of the widget and incremented each time an object is created.

    However, the value is never reset.

    Assuming I have a canvas object $c, I would expect "$c delete all" to reset the 'nextId' value to 1 internally because all items are deleted. Currently, a new object created on the canvas (after the delete) returns an ID which is 'nextId++' where '
    nextId' was the last object created before the deletion.

    Is there a reason this field is not reset ?

    In one of my applications I have a "replay" function which saves the current display by saving serialized canvas data. When the user wants to replay, the current canvas display is deleted and recreated from the serialized data. Unfortunately, I have
    other data that is stored which relies on the original canvas ID's - this has to be adjusted when the new canvas objects are created. If the initial canvas ID were reset, this would be simplified for me.

    best regards
    Shaun

    Could an alternative approach be to update the canvas items themselves? Or to store unique tags for each item?

    Regards

    Arjen

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robert Heller@21:1/5 to Shaun Deacon on Fri Sep 2 12:24:55 2022
    At Thu, 1 Sep 2022 15:39:39 -0700 (PDT) Shaun Deacon <shaun.deacon@us.socionext.com> wrote:

    In one of my applications I have a "replay" function which saves the current display by saving serialized canvas data. When the user wants to replay, the current canvas display is deleted and recreated from the serialized data. Unfortunately, I have other data that is stored which relies on the original canvas ID's - this has to be adjusted when the new canvas objects are created. If the initial canvas ID were reset, this would be simplified for me.

    It is probably bad practice to depend on something like the *internally generated* canvas IDs, over which you don't have control. If you need unique and *repeatable* IDs, you should generate them yourself in a way that is known and controlled by your program.


    best regards
    Shaun




    --
    Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
    Deepwoods Software -- Custom Software Services
    http://www.deepsoft.com/ -- Linux Administration Services
    heller@deepsoft.com -- Webhosting Services

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Ralf Fassel@21:1/5 to All on Fri Sep 2 14:57:50 2022
    * Shaun Deacon <shaun.deacon@us.socionext.com>
    | In one of my applications I have a "replay" function which saves the
    | current display by saving serialized canvas data. When the user wants
    | to replay, the current canvas display is deleted and recreated from
    | the serialized data. Unfortunately, I have other data that is stored
    | which relies on the original canvas ID's - this has to be adjusted
    | when the new canvas objects are created. If the initial canvas ID were
    | reset, this would be simplified for me.

    Check the -tags option when creating the items. If you reset the tag
    number in your code when you delete the canvas, you can recreate the
    items with the same -tags as before, and use the tag instead of the id
    to adress individual items.

    $canvas create ... -tags t[incr mycounter]
    ...
    # now address objects by t1 t2 etc instead of the id returned by [canvas create]

    # reset
    set mycounter 0
    # recreate
    $canvas create ... -tags t[incr mycounter]

    man canvas(n)
    When specifying items in canvas widget commands, if the specifier
    is an integer then it is assumed to refer to the single item with
    that id. If the specifier is not an integer, then it is assumed
    to refer to all of the items in the canvas that have a tag
    matching the specifier. The symbol tagOrId is used below to
    indicate that an argument specifies either an id that selects a
    single item or a tag that selects zero or more items.

    HTH
    R'

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Shaun Deacon@21:1/5 to All on Fri Sep 2 12:27:07 2022
    Thank you all for your suggestions.

    Robert wrote
    It is probably bad practice to depend on something like the *internally generated* canvas IDs, over which you don't have control. If you need unique and *repeatable* IDs, you should generate them yourself in a way that is known
    and controlled by your program.

    I take your point, and your key emphasis is *repeatable*. In most cases, I still think it is completely reasonable to use the returned ID from 'canvas create', otherwise what is the purpose of returning an ID at all if it shouldn't be used ?
    BTW, From my original post, without knowing what is going on under the hood, intuitively one would still expect "canvas delete all' to reset the ID counter because all objects have been deleted.

    Arjen Wrote
    Could an alternative approach be to update the canvas items themselves? Or to store unique tags for each item?

    Actually, when my <serialized> canvas data is reloaded this is kind of what I am doing - I use a map which I create by looking at the tags for each object (eg. set obj(<old>,id) <new>) when it is created. The map is then applied accordingly to each new
    canvas object to adjust the ID's (and tags).
    BTW, I like the <serialize>/<deserialize> approach because it's a fast way to do a complete re-display even with my post creation adjustment.

    Ralf wrote
    Check the -tags option when creating the items. If you reset the tag
    number in your code when you delete the canvas, you can recreate the
    items with the same -tags as before, and use the tag instead of the id
    to adress individual items.
    $canvas create ... -tags t[incr mycounter]
    now address objects by t1 t2 etc instead of the id returned by [canvas create]
    # reset
    set mycounter 0
    # recreate
    $canvas create ... -tags t[incr mycounter]

    Yes, I understand the approach and actually I use tags extensively to reference objects. However, I currently use the generated ID as a key for many tags - for example "C<id>" for cells, "P<id>" for ports, "N<id>" for nets etc...
    I could do as you suggested, and maintain unique counters for different objects which would remove the dependence on the generated canvas ID's. However, of course this would mean more work internally for my application.

    I'm still interested in why the ID counter is not reset internally when all objects are deleted (just from an understanding POV)...

    BTW, even if the ID counter was reset, in my case I would still need to make adjustments to the new canvas objects because any objects that were individually deleted would still affect the new ID values when the objects are recreated.

    best regards,
    Shaun

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Robert Heller@21:1/5 to Shaun Deacon on Fri Sep 2 20:46:45 2022
    At Fri, 2 Sep 2022 12:27:07 -0700 (PDT) Shaun Deacon <shaun.deacon@us.socionext.com> wrote:


    Thank you all for your suggestions.

    Robert wrote
    It is probably bad practice to depend on something like the *internally generated* canvas IDs, over which you don't have control. If you need unique
    and *repeatable* IDs, you should generate them yourself in a way that is known
    and controlled by your program.

    I take your point, and your key emphasis is *repeatable*. In most cases, I still think it is completely reasonable to use the returned ID from 'canvas create', otherwise what is the purpose of returning an ID at all if it shouldn't be used ?

    They are like process IDs and like process IDs, they have no persistent lifetime. They do have a "transient" lifetime, so can be used as such -- as long as the item still exists, but when the item is gone (eg deleted), the ID it *had* is no longer valid and never will be used again for this canvas
    widget incarnation.

    BTW, From my original post, without knowing what is going on under the hood, intuitively one would still expect "canvas delete all' to reset the ID counter because all objects have been deleted.

    "canvas delete all" is NOT anything special and is not really any different than "canvas delete footag" where footag is just a tag shared by some random set of canvas items. In other words, the "canvas delete <mumble>" command has no way of knowing that all items will be deleted and thus all ids are now up for grabs. It has to be coded such that there may be some ids still in use
    and thus can't assume that all possible ids are available for re-use. So the canvas code never recycles canvas IDs and the IDs are always monotonically increasing until the canvas widget is destroyed.


    Arjen Wrote
    Could an alternative approach be to update the canvas items themselves? Or to store unique tags for each item?

    Actually, when my <serialized> canvas data is reloaded this is kind of what I am doing - I use a map which I create by looking at the tags for each object (eg. set obj(<old>,id) <new>) when it is created. The map is then applied accordingly to each
    new canvas object to adjust the ID's (and tags).
    BTW, I like the <serialize>/<deserialize> approach because it's a fast way to do a complete re-display even with my post creation adjustment.

    Ralf wrote
    Check the -tags option when creating the items. If you reset the tag
    number in your code when you delete the canvas, you can recreate the
    items with the same -tags as before, and use the tag instead of the id
    to adress individual items.
    $canvas create ... -tags t[incr mycounter]
    now address objects by t1 t2 etc instead of the id returned by [canvas create]
    # reset
    set mycounter 0
    # recreate
    $canvas create ... -tags t[incr mycounter]

    Yes, I understand the approach and actually I use tags extensively to reference objects. However, I currently use the generated ID as a key for many tags - for example "C<id>" for cells, "P<id>" for ports, "N<id>" for nets etc...
    I could do as you suggested, and maintain unique counters for different objects which would remove the dependence on the generated canvas ID's. However, of course this would mean more work internally for my application.

    I'm still interested in why the ID counter is not reset internally when all objects are deleted (just from an understanding POV)...

    BTW, even if the ID counter was reset, in my case I would still need to make adjustments to the new canvas objects because any objects that were individually deleted would still affect the new ID values when the objects are recreated.

    best regards,
    Shaun




    --
    Robert Heller -- Cell: 413-658-7953 GV: 978-633-5364
    Deepwoods Software -- Custom Software Services
    http://www.deepsoft.com/ -- Linux Administration Services
    heller@deepsoft.com -- Webhosting Services

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Shaun Deacon@21:1/5 to Robert Heller on Fri Sep 2 15:13:04 2022
    On Friday, September 2, 2022 at 1:46:55 PM UTC-7, Robert Heller wrote:
    "canvas delete all" is NOT anything special and is not really any different than "canvas delete footag" where footag is just a tag shared by some random set of canvas items. In other words, the "canvas delete <mumble>" command has
    no way of knowing that all items will be deleted and thus all ids are now up for grabs. It has to be coded such that there may be some ids still in use and thus can't assume that all possible ids are available for re-use. So the canvas code never recycles canvas IDs and the IDs are always monotonically increasing until the canvas widget is destroyed.

    Your explanation makes perfect sense, thank-you.

    Technically, the 'canvasPtr->nextId' field could be reset when the tag/object search list is empty (everything has been deleted)
    However, on reflection, this doesn't really have that much merit.

    Actually I have an analogous situation in my application (which is an EDA tool). For some cases, I need to create "logical nets" that are given generic names with a counter value ('ID") appended to make them unique. When a net is deleted, I don't re-use
    the ID because the name is not that important (it only needs to be unique) - keeping track of reusable ID's would only add unnecessary complexity.

    Thanks for taking the time to explain.

    best regards,
    Shaun

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)
  • From Rich@21:1/5 to Shaun Deacon on Sat Sep 3 00:47:32 2022
    Shaun Deacon <shaun.deacon@us.socionext.com> wrote:
    BTW, From my original post, without knowing what is going on under
    the hood, intuitively one would still expect "canvas delete all' to
    reset the ID counter because all objects have been deleted.

    No one should not expect such, the current behavior of id's is
    documented:

    man canvas:

    ...
    The id of an item never changes and id numbers are never re-used
    within the lifetime of a canvas widget.
    ...

    Note the clause after "and".

    --- SoupGate-Win32 v1.05
    * Origin: fsxNet Usenet Gateway (21:1/5)