Inviare dati da un programma Gambas ad un altro mediante le risorse del Componente DBus

Da Gambas-it.org - Wikipedia.

Come è noto, DBus è un "sistema bus di messaggi", cioè un programma che può passare diversi tipi di messaggi tra le applicazioni. Il sistema DBus è supportato in Gambas 3, dal Componente gb.dbus. Tale Componente consente, pertanto, la trasmissione di dati tra due programmi Gambas.
Va precisato che DBus (Desktop Bus) lavora con i programmi attivi sullo stesso desktop.


Mostriamo un esempio pratico [ nota 1 ], nel quale abbiamo due programmi, che chiameremo esattamente (rispettando maiuscole e minuscole): "dBus-cli " e "dbus-srv ".
Il programma "dBus-cli " farà da Client, ed il programma "dbus-srv " farà da Server.

Il programma "dBus-cli " invierà al programma "dbus-srv " dei dati numerici ed un informazione sul tipo di operazione che dovrà essere compiuta dal programa Server con quei numeri. Il programma "dbus-srv ", intercettati detti dati numerici e l'informazione predetta, compirà il tipo di operazione richiesta dal Client attraverso l'informazione ricevuta insieme coi dati numerici. Effettuata l'operazione matematica dovuta, il programma "dbus-srv " invierà il risultato al programma "dBus-cli ".

Per vederne il funzionamento occorre prima lanciare il programma Server, poi quindi il programma Client.


Codice delle Classi costituenti il programma "dBus-cli"

Il programma "dBus-cli " conterrà sul proprio Form:

  • 3 ValueBox: nel 1° e nel 2° ValueBox sono impostati rispettivamente il primo ed il secondo valore numerico da inviare;
  • 1 ComboBox: con il quale si sceglierà il tipo di operazione aritmetica da compiere (moltiplicazione, divisione, addizione, sottrazione)
  • 1 Button: serve per inviare i dati al programma Server.

Inoltre il programma "dBus-cli " conterrà due Classi. Nella Classe principale, quella del Form, è contenuto il seguente codice:

Private $sApplicationName As String
Private $bNoServer As Boolean


Public Sub Form_Open()

 Dim aList As String[]
 Dim i As Integer
 
  ValueBox1.Value = 5 ' Operando 1
  ValueBox2.Value = 6 ' Operando 2
  ValueBox3.Value = 1 ' Tempo
  With ComboBox1
    .Add("moltiplica")
    .Add("dividi")
    .Add("somma")
    .Add("sottrai")
  End With
  Button1.Text = "Calcola"
  aList = DBus.Session.Applications.Sort(gb.Descent)
  
  For i = 0 To aList.Max
    If aList[i] Begins "org.gambas.dbus-srv-" Then
      $sApplicationName = aList[i]
      Print $sApplicationName
    Endif    
  Next
  If IsNull($sApplicationName) Then
    Message.Error("Impossibile contattare il server", "OK")    
    $bNoServer = True
    Me.Close
    Return
  Endif
  Object.Attach(DbusRisp, Me, "Risp")
  DBus.Session.Register(DbusRisp, "/DbusRisp")
  
End


Public Sub Form_Close()

  If $bNoServer = False Then DBus.Session.Unregister(DbusRisp)  
  
End


Public Sub Risp_Sblocco()
 
  Button1.Enabled = True
  
End


Public Sub Button1_Click()
 
  Select Case LCase$(ComboBox1.Text)
    Case "moltiplica"
      DBus[$sApplicationName]["/Calcoli"].Moltiplica(ValueBox1.Value, ValueBox2.Value, ValueBox3.Value)
    Case "dividi"
      DBus[$sApplicationName]["/Calcoli"].Dividi(ValueBox1.Value, ValueBox2.Value, ValueBox3.Value)
    Case "somma"
      DBus[$sApplicationName]["/Calcoli"].Somma(ValueBox1.Value, ValueBox2.Value, ValueBox3.Value)
    Case "sottrai"
      DBus[$sApplicationName]["/Calcoli"].Sottrai(ValueBox1.Value, ValueBox2.Value, ValueBox3.Value)
  End Select
  
  Button1.Enabled = False
  
  Catch
    Message.Error("Evidentementi lo schiavo non è attivo...")
  
  Button1.Enabled = True
  
End


Il codice della seconda Classe, contenuta nel programa "dBus-cli " e che sarà chiamata in questo caso esattamente "DBusRisp.class ", sarà il seguente:

Inherits DBusObject

Create Static

Event Sblocco


Public Function Risposta(Evento As String, Operazione As Integer, Valore1 As Float, Valore2 As Float, Risultato As Float) As Boolean

 Dim sSymbol As String[]
 
  sSymbol = ["*", "/", "+", "-"]
  If Evento = "Risultato" Then
    Message.Info(Subst$("Comunicazione dello schiavo:\n&1 &2 &3 = &4", Valore1, sSymbol[Operazione], Valore2, Risultato))
    Raise Sblocco
  End If
  
  Return True
  
End


Codice delle Classi costituenti il programma "dbus-srv"

Il programma "dbus-srv " che fa da Server, e che - come già detto - deve compiere l'operazione aritmetica richiesta, avrà sul proprio Form Semplicemente una Label.

Anche questo programma avrà due Classi. Nella Classe principale, quella del Form, sarà contenuto il seguente codice:

Private $bNoServer As Boolean


Public Sub Form_Open()
 
  DBus.Session.Register(Calcoli, "/Calcoli")
  Object.Attach(Calcoli, Me, "c")
 
End


Public Sub c_Messaggi(Testo As String)
 
  Label1.Text = Testo
  
End


Public Sub Form_Close()
 
  If $bNoServer = False Then DBus.Session.Unregister(Calcoli)
  
End


Public Function NomeClient() As String
 
 Dim aList As String[]
 Dim i As Integer
 Dim s As String
 
  aList = DBus.Session.Applications.Sort(gb.Descent)
  
  For i = 0 To aList.Max
    ' Print aList[i]
    If aList[i] Begins "org.gambas.dBus-cli-" Then
      s = aList[i]
      Print s
      Return s
    Endif    
  Next
  If IsNull(s) Then
    Message.Error("Impossibile contattare il client", "OK")    
    $bNoServer = True
    FMain.Close
    Return
  Endif
  
End


Il codice della seconda Classe, contenuta nel programma "dbus-srv " e che sarà chiamata in questo caso esattamente "Calcoli.class ", sarà il seguente:

Inherits DBusObject

Create Static

Private t As New Timer As "t"
Private $fRisult As Float
Private $iV1 As Float
Private $iV2 As Float
Private $iOp As Integer

Event Messaggi(Testo As String)


Public Function Moltiplica(Valore1 As Float, Valore2 As Float, Tempo As Integer) As Float
 
  $fRisult = Valore1 * Valore2
  $iV1 = Valore1
  $iV2 = Valore2
  $iOp = 0
  t.Delay = Tempo * 1000
  t.Start()
  Raise Messaggi(Subst("Mi richiedono di fare una moltiplicazione \n La eseguirò tra &1 second&2.", Tempo, IIf(Tempo / 1000 = 1, "o", "i")))
  
End


Public Function Dividi(Valore1 As Float, Valore2 As Float, Tempo As Integer) As Float
  
  $fRisult = Valore1 / Valore2
  $iV1 = Valore1
  $iV2 = Valore2
  $iOp = 1
  t.Delay = Tempo * 1000
  t.Start()
  Raise Messaggi(Subst("Mi richiedono di fare una divisione \n La eseguirò tra &1 second&2.", Tempo, IIf(Tempo = 1, "o", "i")))
  
End


Public Function Somma(Valore1 As Float, Valore2 As Float, Tempo As Integer) As Float
 
  $fRisult = Valore1 + Valore2
  $iV1 = Valore1
  $iV2 = Valore2
  $iOp = 2
  t.Delay = Tempo * 1000
  t.Start()
  Raise Messaggi(Subst("Mi richiedono di fare una somma \n La eseguirò tra &1 second&2.", Tempo, IIf(Tempo = 1, "o", "i")))
  
End


Public Function Sottrai(Valore1 As Float, Valore2 As Float, Tempo As Integer) As Float  
 
  $fRisult = Valore1 - Valore2
  $iV1 = Valore1
  $iV2 = Valore2
  $iOp = 3
  t.Delay = Tempo * 1000
  t.Start()
  Raise Messaggi(Subst("Mi richiedono di fare una sottrazione \nLa eseguirò tra &1 second&2.", Tempo, IIf(Tempo = 1, "o", "i")))
  
End


Public Sub t_Timer()
 
 Dim s As String
 
  s = FMain.NomeClient()
  t.Stop()
  Raise Messaggi("Ho ritornato il valore al mio padrone.")
  DBus[s]["/dbusrisp"].Risposta("Risultato", $iOp, $iV1, $iV2, $fRisult)
  Raise Messaggi("E lui ha confermato.")
  
  Catch
    Message.Error("Evidentemente il mio padrone è assente... ")
  
End



Note

[1] I seguenti codici sono stati scritti dal membro milio del forum gambas-it.org, e revisionati, per essere adattati ai recenti aggiornamenti del Componente DBus, dal membro Gianluigi.