How to protect an object content during manipulation in spread

Actually on my project i have many object layers, and i m facing since a long time a bug :
when moving up or down in my spread of layers the moved layers may take some proprieties of “jumped” layers.
Some inner data of the layer are just simply mixed like a salata.

I presume this is a conflict between refreshment of all my project (ensure value of animations etc), and the action of moving my layer itself. As we cant have any feedback from SetValue or Ensure Value (tracing the operation in the rX system).

i dont see any other thing than trying to protect my layer from modifications or external actions during this process of moving it up or down in my layer spread.

So, how can i do this ?
Thank you for your help !

I suspect you have a dispose problem.

Basically your cure is ManageProcess region.

The one illustration of this problem would be an If and some disposable class inside:

This dispose would never happen, e.g. you would expect, that there is new class instance when you change condition from false to true, but actually you are holding the class inside. The solution to have this inside ManageProcess:

Like this you would see that class actually disposed and recreated when u change condition.

disposables.vl (14.8 KB)

Now, why would that affect you case, the Channel is an Observable, when you have channel attached to something (like widget) the widget there is subscription created and it lives until the subscription is Disposed. So basically when you move something in the graph, you need to make sure that subscriber (runtime) actually disposed, and recreated, since you move it in the model, the runtime still has old subscription, so likely you need to manage recreation of runtime.

P.S. I think that IF should have additional pins, or this behavior should be heighted somehow

1 Like

Merci @antokhio i think you are right pointing the problem. i will try this approach ( will need a lot of thinking).

hi @antokhio the example is very very abstract.
i m not understanding from it how to insert this logic in my flow. (touching all my limits there)

@karistouf it’s really hard to tell how to apply this based on just abstract description the point is if you have something in the model object before you started to “move” this object was connected to some widget… when you move it in a graph you need to make sure that:

  • Old widget was disposed (otherwise subscription would still point to moved reference)
  • New widget was created

How to apply it to your graph… Well easiest would be mark whole runtime inside manage process and dispose whatever move action is triggered… This way you will make sure it’s the culprit at list…

hum, i will build this small dummy project, its will be a good starting point from there i think we can have a productiv exchange :-P
thxs @antokhio

ok @anthokio, here is the beginning of a dummy project to be on concrete bases.

I hope this dummy model and the discussion we will have with it will help anybody with the following goals:

  • creating a basic project model - here a SceneModel
  • manipulating it with channels
  • dealing with spreads in the model (im gui and logics actions / runtime job)

It tooked me some time as i have a strange, very strange behaviour with the select by path that i dont have on my big project. ( idont have any pads or delay in this simple sample)

I m refreshing a random seed that is part of the Scene Model with setvalue and select by path. The select value is activated on each change of cycle.
And it kills any Play or Record state of my movement recorder.

To reproduce it :

  • add balls
  • click " record a move ", the checkbox will be red
  • at each lfo cycle the value will be called

i think this may be a good start for me :-P as it is pointing a terrible mistake somehow…
DummyProject.vl (224.4 KB)

@karistouf Based on your description, it’s not entirely clear what the problem is. What is the issue? I ran the example and don’t understand what you’re referring to.

And does the original issue described in the thread relate to the example where you’re having a problem with the state?

As for the patches, my advice would be to use IndexOf and pass the object rather than the index. And don’t set the selected ‘ball’ as the index.

@karistouf

The problem with the state is that you’ve connected to a value rather than a channel. In this case, Select still works, but obviously not as expected.

thank you @yar its not the first time i m making this error ! tireness or end of the day…
do you know why i can connect the select by path to a non channel type ? is there any reason to enable this human error ?

You can set up this connection in such a way that you don’t have to create endless, clunky structures in place every time. Ultimately, local conversion helps feed values into channels and leaves it to the machine to handle, rather than taking it upon yourself to do it manually. Doing it manually is prone to errors and various inefficiencies. For example, there is the Optional type, which requires manual conversion and connection, but in my view, this could also be automated. Yes, it does require more attention.

I must admit, I have no clue what’s you are trying to setup in there… Curranty it seemed to me a manifest of “I wouldn’t do this way” from a brief look. As for SelectBy path question, it’s more a vl limitation then a desired behavior, like on widget you have a Channel Boolean for instance, if you constraint this, you would not be able to connect IOBox Boolean anymore.

Hi @yar !

I’m not sure I fully understand your reply :

“You can set up this connection in such a way that you don’t have to create endless, clunky structures in place every time.”

Are you suggesting creating dedicated processes that handle the full access path into the model’s channel once and for all — so that other parts of the patch can just plug in cleanly? Or is there yet another dimension of vvvv gamma that I’ve missed?

What would the correct solution look like here?

@antokhio

Curranty it seemed to me a manifest of “I wouldn’t do this way” from a brief look.

Thats Excellent ! we will at one moment arrive to Dispose question, but not right now. :-P
I need some basic concrete example understanding. Then, except the indexSelected (integer) thing (yes i know you prefer objects and if you want i can tell you WHY i have gone back to indexes), please explain me !!!

To answer you here is the first trouble i have in my little comprehension of writting with gamma the instanciation of a blank object, and on open this :

As there is no [0] object, the only way i see is to use ANY in im gui.
Is there an other way to do things ? surely a part of manifest ?

Other thing, i cant reproduce how i use in my big project the Sequencer. It tooked me some time i remember, and its working finally but i suffered a lot to make it work. Here its coming back here in this basic patch i dont understand why the update is on one frame.
should i put somewhere a pad ? its like i m writting the sequencer each frame ?

DummyProject updated :

DummyProject.vl (233.6 KB)

I’m not suggesting anything

You asked WHY, and I replied: the reason you can pass a value rather than a channel into a channel is to avoid explicit conversion constructs.

@yar (and i asked to Claude translation :-P ).

but on the user side, why, if it may create troubles and errors ?
i mean in gamma we are very type restricted…
yours :)

Let’s start from separation of concerns:

Model - is something that is considered serializable by nature, basically it’s used to establish API contract between software’s, that’s why doing this:

Considered as bad practice e.g. adding business logic to a model:

Adding business logic to a model is often discouraged because it violates the Single Responsibility Principle (SRP). When a model handles both data structure and complex rules, it becomes a “God Object”—too large, hard to read, and difficult to maintain.

You have to think about model as something you should keep a description of stuff you want to build from it.

Let’s move on:

You are seeding random in the model, but WHY? And from why I mean its kind of anti-purpose of model. Like you create a runtime that seeds random to model, instead your business logic should look for a seeder (that is something in runtime) and get current seed from it.

The model is something like a repository, you don’t want to send real-time changes to it, instead you want a cleanly separated series of commits - undo/redo.

E.g.:

Let’s imagine we have a slider, user moves slider in real-time what would you want to send to model?

  • A real-time value
  • A result of slider movement (e.g. the slider position when user released the slide)

You see what i’ve seen in your patch is some general misconceptions:

  • Model entries - describe structure
  • Runtime entries - something running in background e.g. texture sources, generators (correct me if i’m wrong)
  • UI - kind off model representation that should operate on scopes, e.g fetch data from model hold real-time update call business logic
  • Business logic - something that should glue this all together

The application normally has few states, like a immediate state, is where all the widgets are and a deferred one where the model is… The immediate state is a composition of a lot of smaller slices, where each slice responsible for some part of the state, where the deferred keeps whole structure, and based on deferred state the immediate should be created…

Idk i’ve checked this model runtime stuff by dottore it didn’t gave me the clear view in terms of separation of concerns. Maybe you can describe whole thing as some sort of user flow scenario so we can start from that? Or i do miss something here…

Like I want user to draw a circle, we want drawn circle to receive a seed from runtime, or we want for circle to have something updated in runtime what happens next…

thank you so much @antokhio this is a VERY CLEAR feedback.

It helps really me to have a clearer view of how to proceed, especially by creating a class Model Manager that will do all the stuff at all levels on my records.

I really appreciate it because your analyze is very concrete, and helps me really to make enter in my head this idea that models should be nothing else that data type definitions.
I will come back to you with thr dummyproject modified.

About its actual goals:
create objects that contains different sequencers for recorded live animations ( the wanderer simulate it).

Actually my all project works (teaser) but with lot of dirties of mine.
so making it clear with this dummy helps me to specify what need to be restructured and rewritten.

@karistouf There is a family of patterns specific to C# (and, incidentally, to a lesser extent specific to other languages, but frequently encountered on the web)

MVP, MVC and MVVM (and there are probably others)

They are very similar in nature — separating responsibilities and creating abstractions. Let me remind you that there are several key concepts in OOP: encapsulation (hidden and public object APIs), polymorphism, abstraction and inheritance. VVVV Gamma doesn’t get on well with all of these concepts, but abstraction and encapsulation are of fundamental importance when building what you want.

Please study these design patterns online (and with the help of Claude). It will be of great help to you.

I would add that understanding the areas of responsibility of the different parts of such a pattern and being able to choose the right one from the family of patterns is extremely important. Although design patterns are always a means to an end, not the end itself, and it is important not to over-engineer the ‘design’.

1 Like

@antokhio , i have restructured the DummyProject but i m quite puzzled if i need to encapsulate somehow the scene inside the manager
I m not happy from that pad inserted. Should i get only an input in my manager ?
thought i will have 2 inputs in my UI : te scene entry and the manager entry.

here i tried to encapsulate the entry all at once, but the pad breaks the liasion to the model. what would be best approach ?

in my idea i would only have access to the manager by the UI. The updating of the manager to the model being done in the runtime ?

DummyProject.vl (253.6 KB)