I'm not expecting any action on following, I'm just curious about the reasoning behind it and perhaps I have overlooked a detail...nextId' was the last object created before the deletion.
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 '
Is there a reason this field is not reset ?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.
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
best regards
Shaun
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
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.
Arjen Wrote
Could an alternative approach be to update the canvas items themselves? Or to store unique tags for each item?
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]
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.
new canvas object to adjust the ID's (and tags).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
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
"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.
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.
Sysop: | Keyop |
---|---|
Location: | Huddersfield, West Yorkshire, UK |
Users: | 463 |
Nodes: | 16 (2 / 14) |
Uptime: | 156:54:17 |
Calls: | 9,384 |
Calls today: | 4 |
Files: | 13,561 |
Messages: | 6,095,919 |