haorenhui
2023-10-30 6d6cc10d9e8e242661da7fd655dec155a09d676c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
Quintiq file version 2.0
#parent: #root
Method Subscribe (LibOpt_Snapshot snapshot, String prefix)
{
  TextBody:
  [*
    nvt := NamedValueTreeIO::Export( snapshot );
    
    snapshot_type := snapshot.DefinitionName();
    
    analysis_attributes := snapshot.AnalysisAttributes();
    
    tv := typeofexpression( snapshot ).TypeView();
    attributes := selectset( tv, Attributes, att,
                             not att.IsSystem() );
    
    root := nvt.Root().Child( nvt.GetHandle( snapshot_type ) );
    
    path := prefix + snapshot.Type();
    
    // Iteration
    traverse( snapshot, IterationPart.IterationPartNM.Iteration, iteration )
    {
      this.Subscribe( 'Iteration', path, [Real] iteration.IterationNr(), typeof( Number ), false );
    }
    
    traverse( attributes, Elements, att )
    {
      child := root.Child( nvt.GetHandle( att.Name() ) );
      val := child.GetValue();
      
      if( val.istype( Number ) or val.istype( Real ) or val.istype( Duration ) or val.istype( Boolean ) or val.istype( BinaryValue ) )
      {
        name := child.Name();
    
        to_analyze := exists( analysis_attributes, Elements, a, a.Name() = att.Name() );
        if( val.istype( Real ) )
        {
          this.Subscribe( name, path, val.astype( Real ), typeof( Real ), to_analyze );
        }
        else if( val.istype( Number ) )
        {
          this.Subscribe( name, path, [Real] val.astype( Number ), typeof( Number ), to_analyze );
        }
        else if( val.istype( Duration ) )
        {
          this.Subscribe( name, path, val.astype( Duration ).MinutesAsReal() * 60, typeof( Duration ), to_analyze );
        }
        else if( val.istype( Boolean ) )
        {
          this.Subscribe( name, path, ifexpr( val.astype( Boolean ), 1.0, 0.0 ), typeof( Boolean ), to_analyze );
        }
        else if( val.istype( BinaryValue ) )
        {
          bin_value := val.astype( BinaryValue );
          
          real_vector := guard( RealVector::Construct( bin_value ), null( RealVector, owning ) );
          if( not isnull( real_vector ) )
          {
            for( i := 0; i < real_vector.Size(); i++ )
            {
              this.Subscribe( name + '[' + [String] i + ']', path, real_vector.Get( i ), typeof( RealVector ), to_analyze );
            }
          }
        }
      }
    }
    
    traverse( snapshot, Children, child, not child.istype( LibOpt_SnapshotComponent ) )
    {
      this.Subscribe( child, path + '.' );
    }
  *]
  InterfaceProperties { Accessibility: 'Module' }
}