Uniqueness question

I’m not too good with Renoise lua and such, so excuse me if I’ve missed something (obvious?). But could I just ask:

If I have two tracks in the Renoise song (Track 1 and Track 2 each sitting at renoise.song().tracks[1] and renoise.song().tracks[2]) and I want to apply operations on say Track 2 I can do this by accessing renoise.song().tracks[2]. I save renoise.song().tracks[2] userdata ‘object’ to a variable. Now if the user swaps/moves Track 1 and Track 2 via say the mouse, maybe it isn’t too much of a problem because we have rawequal. I can compare via rawequal rs.tracks[1] and rs.tracks[2] with saved variable and find that now rs.tracks[1] returns true, so I now know that my Track 2 sits (from the API POV) at rs.tracks[1].

I want to keep a reference to Track 2 though at all times. Even when the user has saved/loaded the song, and (even when my tool isn’t running) the user can move (behind my back) Track 2 around. Where is maybe a unique reference id to these dynamically allocated objects? I can’t really use the name field string (and write a searcher that finds my Track 2) as an identifier because then the user could have two or more tracks that have the same name (or no name at all on tracks), that would only really work if the user has unique track names.

There is no unique ID like that. I think the least obtrusive solution would be to insert some dummy pattern effect as an “ID”.

(Also: do you really need it, or are you going about things the ‘wrong way’? Maybe there’s an alternate solution?)

There is no unique ID like that.

Why not have a unique ID field? I thought of the ‘dummy pattern effect as ID’ thing joule, but what happens if the user deletes that ‘marker’ in the meantime? Even if there is a workaround or some other way, would it not be helpful having a unique ID? IDK (without going into technical stuff) something like:

track2id = renoise.song().tracks[2].id
..User saves/loads, deletes, moves track etc....
track2 = renoise.song().get_track_from_id(track2id)
..return either nil (if deleted/not found) or object of Track 2..

To me joule, it just seems a bit… :unsure:

4Tey, I do not really understand what you want to do.Maybe you can check the index of the track and the name of the track, or the color, both.

renoise.song():track(2) and

renoise.song():track(2).name and


If the user first adds a new track (for example, in position 1), the index of track 2 will change to 3, the name will change, and the color will change. Maybe with this you can do checks directly. Except for a duplication, you will rarely have matches.

track2id = renoise.song().tracks[2].id

As I see it, id could not go after track [2], because the index of the track is variable. id would be another property that would change if you change the number 2, its index.The issue is that the index of the track is its identifier, only that it is variable.

Maybe it should be programmed in another way:





The identifier will always be the same for each track, and the index will remain variable. This would involve tracking the identifiers, so that they never use an identifier already used previously.Maybe this problem also has to do with performance. When you add a new track, all the tracks that come behind change the index. The same happens with the 255 slots in the instrument box.

Would not there be some way to optimize that so that, adding a new instrument does not influence the data of the pattern editor?

What I want to say is that it should be programmed in such a way that, if the user adds or deletes another element, that does not force to change anything of other elements that already exist of the same type, nor anything that depends on them.

Why not have a unique ID field?
To me joule, it just seems a bit… :unsure:

Oh, it was a feature suggestion? I agree and think it’s a good idea :slight_smile: I thought the question was how to solve it right now.

PS. I’m not sure of the exact problem/implementation you’ve stumbled upon, but from my experience, I’ve always found it possible and sufficient for a tool to internally keep track of the tracks. My gut feeling is that anything is still possible, unless you’re afraid that someone will hack the actual song XML when Renoise is not running, thereby breaking everything.

The worst solutions are when you have to resort to song comments for storing custom data :stuck_out_tongue: You could probably do that here, for storing/updating ID’s, as well…

Except for a duplication, you will rarely have matches.

Exactly Raul, even if you check on name and color, there is still a chance (slim but still there) of not obtaining the desired track from your searcher.

Maybe I’m old skool Raul and I like some things to have some static (rather than completely dynamic and floating) state with a bit more guarantee :slight_smile:

Thinking quickly out loud…

If I have 3 patterns (0,1,2), and the user grabs and moves pattern 2 to say before pattern 0 and we have the ‘keep sequence sorted’ option on. How do I know that that is what the user has done? Marking patterns? Why does ‘pattern_sequence_observable’ also get fired multiple times, may as well consolidate into one call?

Answering quickly…

The event table tells you all you need to know (“swap”, “insert” or “remove”). The reason to why it fires multiple times is because you drag a pattern further than one step, which requires multiple swaps. If it wouldn’t show you the multiple swaps, it wouldn’t tell you the whole truth to what happened with the list.

The event table tells you all you need to know (“swap”, “insert” or “delete”).

Yeah, that was it joule, thanks. I forgot about that! :slight_smile:

[Edit:] Whilst on the subject of ‘remove’/‘insert’ parameter with the ‘pattern_sequence_observable’ worth mentioning that the pattern table sequence list doesn’t reflect the operation that is internally done (afaict). For quick example: if I have 5 patterns (0,1,2,3,4) and I move pattern 4 to the beginning of pattern 0, you get two calls to your observable. First call is to remove pattern 4, check. Second call is to insert at 0, check. You’d think that if you read the pattern sequence table between the two calls it would momentarily have one less pattern (i.e. removed pattern 4), but it hasn’t. In fact afaict the operation the user has performed has already been reflected in the pattern sequence list before the first call to our observable.

You seem to be correct. I haven’t noticed that.

It’s a slight inconsistency in the API. Tracks uses swaps, as seen with tracks_observable.

I guess this could become a problem in some special cases, but so far noone complained, so maybe the simplification doesn’t matter that much :slight_smile:

EDIT: Thinking about it, I think this should be fixed. As you pointed out, what happens in the list doesn’t reflect the actual content of the song all the time. An example where this would be a problem: If you want to faithfully ‘mirror’ the sequence list in your own internal list, you’re out of luck. You would need to re-create your own internal list on any change to the pattern sequence (saving any custom attached data to some buffer and using rawequal to restore it). Nah… very inconsistent. Maybe taktik was taking a shortcut due to otherwise having to mess with any sequence sections, or something. speculation

1 Like