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

Da Gambas-it.org - Wikipedia.
Versione del 17 nov 2016 alle 18:11 di Vuott (Discussione | contributi) (Creata pagina con "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...")

(diff) ← Versione meno recente | Versione attuale (diff) | Versione più recente → (diff)

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, di consentire la trasmissione di dati tra due programmi Gambas.


Mostriamo un esempio pratico, nel quale abbiamo due programmi, che chiameremo "Programma A" e "Programma B". Il "Programma A" farà da Client, ed il "Programma B" farà da Server.

Il "Programma A" invierà al "Programma B" dei dati numerici ed un informazione sul tipo di operazione che dovrà essere compiuta dal programa Server con quei numeri. Il "Programma B", 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 B" invierà il risultato al "Programma A".


Il "Programma A" 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 A" conterrà due Classi. Nella Classe principale, quella del Form, è contenuto il seguente codice:

Private $hDBus As DBusSignal
Private $sApplicationName As String
Private $bNoServer As Boolean


Public Sub Form_Open()
 
 Dim aList As String[]
 Dim i As Integer
 
  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 "Programma A", e che sarà chiamata ad esempio "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


Il "Programma B" 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)
 
  Label2.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 B", e che sarà chiamata ad esempio "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.