@@ -27,8 +27,10 @@ type Instance struct {
2727 namedManifests * namedOutputManager [manifest.Manifest ]
2828 variables variable.System
2929
30+ profiles map [string ]variable.Profile
31+
3032 // TODO: Make this a lock across the entire instance
31- producerLock gsync.Mutex
33+ lock gsync.RWMutex
3234}
3335
3436func New (typeFactory * refutil.TypeFactory ) * Instance {
@@ -127,8 +129,8 @@ func (i *Instance) SetVariableDescription(variablePath, description string) erro
127129}
128130
129131func (i * Instance ) UpdateVariable (variablePath string , data []byte ) (bool , error ) {
130- i .producerLock .Lock ()
131- defer i .producerLock .Unlock ()
132+ i .lock .Lock ()
133+ defer i .lock .Unlock ()
132134
133135 variable , err := i .variables .Variable (variablePath )
134136 if err != nil {
@@ -141,8 +143,8 @@ func (i *Instance) UpdateVariable(variablePath string, data []byte) (bool, error
141143}
142144
143145func (i * Instance ) VariableData (variablePath string ) ([]byte , error ) {
144- i .producerLock .Lock ()
145- defer i .producerLock .Unlock ()
146+ i .lock .Lock ()
147+ defer i .lock .Unlock ()
146148
147149 variable , err := i .variables .Variable (variablePath )
148150 if err != nil {
@@ -153,6 +155,76 @@ func (i *Instance) VariableData(variablePath string) ([]byte, error) {
153155
154156// <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
155157
158+ // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
159+ // Profiles
160+ // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
161+
162+ func (i * Instance ) SaveProfile (profileName string ) {
163+ i .lock .Lock ()
164+ defer i .lock .Unlock ()
165+
166+ i .profiles [profileName ] = i .variables .GetProfile ()
167+ }
168+
169+ func (i * Instance ) LoadProfile (profileName string ) error {
170+ i .lock .Lock ()
171+ defer i .lock .Unlock ()
172+
173+ if profile , ok := i .profiles [profileName ]; ok {
174+ return i .variables .ApplyProfile (profile )
175+ }
176+
177+ return fmt .Errorf ("no profile exists with name %q" , profileName )
178+ }
179+
180+ func (i * Instance ) RenameProfile (profile , newName string ) error {
181+ i .lock .Lock ()
182+ defer i .lock .Unlock ()
183+
184+ if _ , ok := i .profiles [profile ]; ! ok {
185+ return fmt .Errorf ("profile %q does not exist" , profile )
186+ }
187+
188+ if _ , ok := i .profiles [newName ]; ok {
189+ return fmt .Errorf ("profile %q already exists" , profile )
190+ }
191+
192+ i .profiles [newName ] = i .profiles [profile ]
193+
194+ delete (i .profiles , profile )
195+
196+ return nil
197+ }
198+
199+ func (i * Instance ) DeleteProfile (profileName string ) error {
200+ i .lock .Lock ()
201+ defer i .lock .Unlock ()
202+
203+ if _ , ok := i .profiles [profileName ]; ! ok {
204+ return fmt .Errorf ("graph contains no profile named %q" , profileName )
205+ }
206+
207+ delete (i .profiles , profileName )
208+ return nil
209+ }
210+
211+ func (i * Instance ) Profiles () []string {
212+ i .lock .RLock ()
213+ defer i .lock .RUnlock ()
214+
215+ profiles := make ([]string , 0 , len (i .profiles ))
216+
217+ for profile := range i .profiles {
218+ profiles = append (profiles , profile )
219+ }
220+
221+ sort .Strings (profiles )
222+
223+ return profiles
224+ }
225+
226+ // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
227+
156228func (i * Instance ) IsPortNamed (node nodes.Node , portName string ) (string , bool ) {
157229 return i .namedManifests .IsPortNamed (node , portName )
158230}
@@ -316,6 +388,7 @@ func (i *Instance) Reset() {
316388 i .namedManifests = & namedOutputManager [manifest.Manifest ]{
317389 namedPorts : make (map [string ]namedOutputEntry [manifest.Manifest ]),
318390 }
391+ i .profiles = make (map [string ]variable.Profile )
319392}
320393
321394type sortedReference struct {
@@ -397,6 +470,10 @@ func (i *Instance) ApplyAppSchema(jsonPayload []byte) error {
397470 return err
398471 }
399472
473+ for profile , data := range appSchema .Profiles {
474+ i .profiles [profile ] = data .Data
475+ }
476+
400477 createdNodes := make (map [string ]nodes.Node )
401478
402479 // Create the Nodes
@@ -506,6 +583,9 @@ func (i *Instance) ApplyAppSchema(jsonPayload []byte) error {
506583}
507584
508585func (i * Instance ) Schema () schema.GraphInstance {
586+ i .lock .RLock ()
587+ defer i .lock .RUnlock ()
588+
509589 var noteMetadata map [string ]any
510590 if notes := i .metadata .Get ("notes" ); notes != nil {
511591 casted , ok := notes .(map [string ]any )
@@ -523,8 +603,14 @@ func (i *Instance) Schema() schema.GraphInstance {
523603 Producers : make (map [string ]schema.Producer ),
524604 Notes : noteMetadata ,
525605 Variables : variableSchema ,
606+ Profiles : make ([]string , 0 , len (i .profiles )),
526607 }
527608
609+ for profile := range i .profiles {
610+ appSchema .Profiles = append (appSchema .Profiles , profile )
611+ }
612+ sort .Strings (appSchema .Profiles )
613+
528614 appNodeSchema := make (map [string ]schema.NodeInstance )
529615
530616 for node := range i .nodeIDs {
@@ -585,6 +671,15 @@ func (i *Instance) EncodeToAppSchema(appSchema *schema.App, encoder *jbtf.Encode
585671 nodeInstances [id ] = nodeSchema
586672 }
587673
674+ if appSchema .Profiles == nil {
675+ appSchema .Profiles = make (map [string ]schema.AppProfile )
676+ }
677+ for name , data := range i .profiles {
678+ appSchema .Profiles [name ] = schema.AppProfile {
679+ Data : data ,
680+ }
681+ }
682+
588683 if appSchema .Producers == nil {
589684 appSchema .Producers = make (map [string ]schema.Producer )
590685 }
@@ -803,17 +898,17 @@ func (i *Instance) Parameter(nodeId string) Parameter {
803898}
804899
805900func (i * Instance ) UpdateParameter (nodeId string , data []byte ) (bool , error ) {
806- i .producerLock .Lock ()
807- defer i .producerLock .Unlock ()
901+ i .lock .Lock ()
902+ defer i .lock .Unlock ()
808903
809904 r , err := i .Parameter (nodeId ).ApplyMessage (data )
810905 i .incModelVersion ()
811906 return r , err
812907}
813908
814909func (i * Instance ) ParameterData (nodeId string ) []byte {
815- i .producerLock .Lock ()
816- defer i .producerLock .Unlock ()
910+ i .lock .Lock ()
911+ defer i .lock .Unlock ()
817912 return i .Parameter (nodeId ).ToMessage ()
818913}
819914
@@ -954,8 +1049,8 @@ func (i *Instance) Manifest(producerName string) manifest.Manifest {
9541049 panic (fmt .Errorf ("no producer registered for: %s" , producerName ))
9551050 }
9561051
957- i .producerLock .Lock ()
958- defer i .producerLock .Unlock ()
1052+ i .lock .Lock ()
1053+ defer i .lock .Unlock ()
9591054
9601055 return producer .port .Value ()
9611056}
0 commit comments