Operator << used here to add to a function a generator, another function to supply a stream of values. Also we see the use of Event object.
Stream operator used for arrays to feed each element, but mainly used for what we see here.
We can make some minor changes and we get a simpler version, without TankControl Group (an object in M2000), and with no Event too. Just delete Line "Group TankControl".., line "Event Probe ..", line "Call Event .Probe...", we have to delete the closing curly bracket (for deleted Group definition) before line "Class SpecificClass...", then line "Event TankControl.Probe....", and we have to change the line "For TankControl" with "For This" (so dot before alfa has a meaning This, or we through For { } , but keeping inside all the code, because by default a single dot interpreted as This. Keep in mind that a For { } not only tag what is a dot but also make all definitions inside block for temporary use, but here we don't have that issue)
\\ we have a function to simulate a tank quantity change
\\ alfa arguments are:
\\ current tank quantity, optionally quantity (30 by default) to remove if valve is open,
\\ a flag for printing messages (false by default)
\\ and optionally we can pass as many as we want valve states, true for open, false for closed
\\ we can use the << operator (stream operator) to send valve state
\\ we make a class and a group from that class, named Specific
\\ We can feed Specific with a pattern of valve states (a batch of patterns)
\\ We have 4 options. We can send one pattern as a batch, one time or many (2 options),
\\ or we can send one state at a time for one batch or form many.
\\ We can expand this logic, if we move function's alfa definiton in a group where we put an Event object.
\\ so we can use Event through alfa to stop Specific at some level of tank quantity
LowLevelSet=500
Read ? LowLevelSet \\ read optionally
Group TankControl {
Event Probe { Read tank_quantity, &exitvalue }
Function alfa {
Read tank
Let quantity=30, messages=false
Read ? quantity, messages
exitnow=false
{
Try Stream
If empty or tank=0 Then exit
Call Event .Probe, tank, &exitnow
if exitnow then exit
If number Then tank-=quantity : If messages Then Print "Valve open"
If tank<0 Then tank=0
If messages Then Print format$("Tank quantity={0}", tank)
Loop
}
=tank
}
}
Class SpecificClass {
Private:
Dim A()
myCursor=-1
many=10
once, counter, step_cursor
stepcounter
Public:
Module SpecificClass {
.ReSet
}
Module ReSet {
Read ? .many
Dim .A(.many)=False
.myCursor<=-1
}
Function Feed {
=True
.myCursor++
While .myCursor<.many {
If Empty Then Exit
Read .A(.myCursor)
.myCursor++
}
If Not Empty Then =False : .myCursor<=.many-1
.once<=True
}
Function ReadAllonce {
If not .once Then exit
.once<=False
If .myCursor>0 Then
For i=0 to .myCursor { Data .A(i) }
.counter++
}
Function ReadAllmany {
If .myCursor>0 Then
For i=0 to .myCursor { Data .A(i) }
.counter++
}
Function ReadOneAtime_once {
If not .once Then exit
If .myCursor>0 Then {
If .step_cursor>.myCursor Then {
.once<=False
} Else {
Data .A(.step_cursor)
.stepcounter++
.step_cursor++
}
} Else .once<=False
}
Function ReadOneAtime_many {
If .myCursor>0 Then {
If .step_cursor>.myCursor Then .ResetStep
Data .A(.step_cursor)
.stepcounter++
.step_cursor++
}
}
Module ResetStep {.step_cursor<=0}
Module UnlockOnce {.once<=True : .step_cursor<=0}
Module PrintStepCounter { Print .stepcounter }
}
Specific=SpecificClass()
Function LowLevel {
\\ need same signature for event
Read New TankLevel, &exitvalue
exitvalue=TankLevel<LowLevelSet
}
\\ using Lazy(&LowLevel()) and not LowLevel(), we make the call like the code was in module, so we read LowLevelSet.
\\ and of cource we can tweak the Specific object
Event TankControl.Probe New lazy$(&LowLevel())
Print "Start"
For TankControl {
If Specific.Feed(True, False, False, True,False,False, True,True) Then {
Last=.alfa(1000, 35, True)<<Specific.ReadAllonce()
\\ here we pass manual values
Last=.alfa(Last, 100, True, True, False, False, True)
Specific.UnlockOnce
Last=.alfa(Last, 35, True)<<Specific.ReadAllonce()
Last=.alfa(Last, 35, True)<<Specific.ReadOneAtime_once()
Specific.ResetStep
If Last>0 Then {
If Ask("try to empty tank?", "Tank")=1 Then {
\\ Last=.alfa(last, 35, True)<<Specific.ReadAllmany()
Last=.alfa(last, 35, True)<<Specific.ReadOneAtime_many()
Specific.PrintStepCounter
}
}
}
}
Stream operator used for arrays to feed each element, but mainly used for what we see here.
We can make some minor changes and we get a simpler version, without TankControl Group (an object in M2000), and with no Event too. Just delete Line "Group TankControl".., line "Event Probe ..", line "Call Event .Probe...", we have to delete the closing curly bracket (for deleted Group definition) before line "Class SpecificClass...", then line "Event TankControl.Probe....", and we have to change the line "For TankControl" with "For This" (so dot before alfa has a meaning This, or we through For { } , but keeping inside all the code, because by default a single dot interpreted as This. Keep in mind that a For { } not only tag what is a dot but also make all definitions inside block for temporary use, but here we don't have that issue)
\\ we have a function to simulate a tank quantity change
\\ alfa arguments are:
\\ current tank quantity, optionally quantity (30 by default) to remove if valve is open,
\\ a flag for printing messages (false by default)
\\ and optionally we can pass as many as we want valve states, true for open, false for closed
\\ we can use the << operator (stream operator) to send valve state
\\ we make a class and a group from that class, named Specific
\\ We can feed Specific with a pattern of valve states (a batch of patterns)
\\ We have 4 options. We can send one pattern as a batch, one time or many (2 options),
\\ or we can send one state at a time for one batch or form many.
\\ We can expand this logic, if we move function's alfa definiton in a group where we put an Event object.
\\ so we can use Event through alfa to stop Specific at some level of tank quantity
LowLevelSet=500
Read ? LowLevelSet \\ read optionally
Group TankControl {
Event Probe { Read tank_quantity, &exitvalue }
Function alfa {
Read tank
Let quantity=30, messages=false
Read ? quantity, messages
exitnow=false
{
Try Stream
If empty or tank=0 Then exit
Call Event .Probe, tank, &exitnow
if exitnow then exit
If number Then tank-=quantity : If messages Then Print "Valve open"
If tank<0 Then tank=0
If messages Then Print format$("Tank quantity={0}", tank)
Loop
}
=tank
}
}
Class SpecificClass {
Private:
Dim A()
myCursor=-1
many=10
once, counter, step_cursor
stepcounter
Public:
Module SpecificClass {
.ReSet
}
Module ReSet {
Read ? .many
Dim .A(.many)=False
.myCursor<=-1
}
Function Feed {
=True
.myCursor++
While .myCursor<.many {
If Empty Then Exit
Read .A(.myCursor)
.myCursor++
}
If Not Empty Then =False : .myCursor<=.many-1
.once<=True
}
Function ReadAllonce {
If not .once Then exit
.once<=False
If .myCursor>0 Then
For i=0 to .myCursor { Data .A(i) }
.counter++
}
Function ReadAllmany {
If .myCursor>0 Then
For i=0 to .myCursor { Data .A(i) }
.counter++
}
Function ReadOneAtime_once {
If not .once Then exit
If .myCursor>0 Then {
If .step_cursor>.myCursor Then {
.once<=False
} Else {
Data .A(.step_cursor)
.stepcounter++
.step_cursor++
}
} Else .once<=False
}
Function ReadOneAtime_many {
If .myCursor>0 Then {
If .step_cursor>.myCursor Then .ResetStep
Data .A(.step_cursor)
.stepcounter++
.step_cursor++
}
}
Module ResetStep {.step_cursor<=0}
Module UnlockOnce {.once<=True : .step_cursor<=0}
Module PrintStepCounter { Print .stepcounter }
}
Specific=SpecificClass()
Function LowLevel {
\\ need same signature for event
Read New TankLevel, &exitvalue
exitvalue=TankLevel<LowLevelSet
}
\\ using Lazy(&LowLevel()) and not LowLevel(), we make the call like the code was in module, so we read LowLevelSet.
\\ and of cource we can tweak the Specific object
Event TankControl.Probe New lazy$(&LowLevel())
Print "Start"
For TankControl {
If Specific.Feed(True, False, False, True,False,False, True,True) Then {
Last=.alfa(1000, 35, True)<<Specific.ReadAllonce()
\\ here we pass manual values
Last=.alfa(Last, 100, True, True, False, False, True)
Specific.UnlockOnce
Last=.alfa(Last, 35, True)<<Specific.ReadAllonce()
Last=.alfa(Last, 35, True)<<Specific.ReadOneAtime_once()
Specific.ResetStep
If Last>0 Then {
If Ask("try to empty tank?", "Tank")=1 Then {
\\ Last=.alfa(last, 35, True)<<Specific.ReadAllmany()
Last=.alfa(last, 35, True)<<Specific.ReadOneAtime_many()
Specific.PrintStepCounter
}
}
}
}