Dynamic Data structures in Clarion using DynaLib

Ok up till now we havnt had time or the knowledge of runtime data structures in the clarion runtime.

With a quite winter and summer we have had a little time to look at the work of the russian in the early days of clarion 5 and 6 and re compile in clarion 11.

We have a need for this stuff in an up and coming project and i thought let publish a little of this as we go along in the next part of this project.

This is the cleaned up version of creating a queue at runtime using the russian code with some rewriting.

As we get know this code we will post tid bits of hopefully creating file and views and queues…

The statements sent to this method in the library are just simple text declarations of a queue.

This is where the queue is created and you can see the Self.Q is simple an address to a string with some data types of long , pretty simple really…we have put a window in to show the data created just for this example.

RTLQueueCreateClass.QConstruct PROCEDURE

QueHdr               LIKE(TQueueHeader),AUTO
DeclareMem           LONG,AUTO
QueueDeclareBuffer   &STRING
QueueTQueueHeader    &STRING
fld                 any  


Window                          WINDOW('test Runtime Queue - from deep inside russia.'),AT(,,395,224),GRAY,FONT('Segoe UI',9)
                                    BUTTON('&OK'),AT(291,201,41,14),USE(?OkButton),DEFAULT
                                    BUTTON('&Cancel'),AT(340,201,42,14),USE(?CancelButton),STD(STD:Close)
                                    LIST,AT(15,19,357,157),USE(?LIST1),FROM(''),FORMAT('47L(2)|M20L' & |
                                        '(2)|M20L(2)|M')
                                END

  Code
  Clear(QueHdr)
 
  if ~Self.LinkMode = true 
     Self.Q &= Null

      ! Is A Queue created here?   
         
     gSize# = Self.FSize(0,True); if gSize# < 0 then Return;end 
     if ~gSize# then Size# = 1 else Size# = gSize#;end
     DeclareMem = RTL::NewMem(Size#); if ~DeclareMem then Return;end
     QueHdr.BufferPtr = DeclareMem
     QueHdr.BufferSize = gSize#

    ! Is GenerateDeclare   
        
     QueueDeclareBuffer &= Self.GenerateDeclare()
     if QueueDeclareBuffer &= Null then 
        RTL::FreeMem(DeclareMem);
        Return;
     end
        
     QueHdr.FieldsDefPtr = Address(QueueDeclareBuffer)
   End
   if ~Self.LinkMode >= true OR ~(Self.LinkG &= Null)
     if Self.LinkMode >= true
        RefGrp.GRef &= Self.LinkG
        QueHdr.BufferPtr = OvrGrp.GPtr.BufferPtr
        QueHdr.BufferSize = OvrGrp.GPtr.BufferSize
        QueHdr.FieldsDefPtr = OvrGrp.GPtr.FieldsDefPtr
        
        ! set up queue header addresses
                
     End
     QueueTQueueHeader &= New(STRING(Size(TQueueHeader)))
     if QueueTQueueHeader &= Null ! memory allocation failed
        RTL::FreeMem(DeclareMem)
        Dispose(QueueTQueueHeader)
     else ! Set up Queue address 
        QueueTQueueHeader = QueHdr
        Self.Q &= Address(QueueTQueueHeader)
            
        if ~(Self.Q &= Null)
             
            fld &= what(self.q,1)
            fld = 'data'
            add(self.Q)
             
            open(WINDOW)
            ?List1{prop:from} = self.Q
            
            ACCEPT
            END
            
            close(WINDOW)
            
           Free(Self.Q); Clear(Self.Q)
           if Self.Thread then Self._Thread(Self.Thread);end
  ;end  ;end  ;end

  QueueDeclareBuffer &= Null; QueueTQueueHeader &= Null
  if ~(Self.Q &= Null)
     if ~Self.Props.BStrPresent = true
        Self.Props.GrpClear &= NEW(STRING(SIZE(Self.Q)))
        if ~Self.LinkMode = TRUE
           Self.Props.GrpClear = Self.Q
        else
           QueueDeclareBuffer &= _NewStr(Self.Q)
           Clear(Self.Q)
           Self.Props.GrpClear = Self.Q
           Self.Q = QueueDeclareBuffer
           Dispose(QueueDeclareBuffer)
      end  ;end
     Self.Props.Created = True
   end

  Return