Páginas (2): 1 2   
tincho   01-06-2021, 10:37
#1
[Imagen: nnwUBmA.jpg]
Hola amigos.
Deseo presentarles un método para gestionar la configuración de  un programa, que a mi me parece interesante.
En conjunto con TercoIDE preparamos este ejemplo en el cual en una clase existen todos los parámetros de un programa y con gran flexibilidad pueden agregarse mas. Luego en cualquier otra parte del programa se pueden leer y escribir esas variables.
Finalmente existe un método (Save) que recorre los simbolos de la clase y los guarda en un archivo de texto en formato json para futuros usos recuperando estos datos con el método "Load".
Por favor siéntanse en libertad de opinar, comentar o mejorar este programa.
Config.class
Código:
' Gambas class file
Create Static
Export
Private Const ConfigFile As String = ".app/config.json"
''Configuration variables to be saved, add as needed below
Public CurrentColor As Byte = 1
Public CurrentWidth As Byte = 1
Public CurrentLType As Byte = 1
Public OtherParameter1 As String = "gambas-es.org"
Public OtherParameter2 As String = "gambas.one"
Public OtherParameter3 As String = "gambas-club.de"
Public OtherParameter4 As String = "gambas-it.org"

Public Sub Load(Optional sFile As String)

  Dim jConfig As Collection
  Dim i As Integer
  Dim sSymbol As String
  Dim obj As Object = Me
  Dim MyClass As Class = Object.Class(obj)

  If sFile = "" Then
    sFile = User.Home &/ ConfigFile
  Endif

  If Exist(sFile) Then
    jConfig = JSON.FromString(File.Load(sFile))
    For Each sSymbol In myClass.Symbols
      If jConfig.Exist(sSymbol) Then
        Object.SetProperty(obj, sSymbol, jConfig[sSymbol])
      Endif
    Next
  Endif
End

Static Public Sub Save(Optional sFile As String)
  Dim i As Integer
  Dim jConfig As New JSONCollection
  Dim obj As Object = Me
  Dim MyClass As Class = Object.Class(obj)
  Dim Var As String
  Dim Valor As Variant
  If sFile = "" Then
    sFile = User.Home &/ ConfigFile
  Endif
  For Each Var In myClass.Symbols
    '' Verifying that it is a property or a variable.
    If (MyClass[var].kind = Class.Variable) Or (MyClass[var].kind = Class.Property) Then
      valor = Object.GetProperty(obj, var)
      jConfig.Add(Valor, var)
    End If
  Next
  If Not Exist(File.Dir(sFile)) Then
    Shell "mkdir -p " & File.Dir(sFile) Wait
  Endif
  File.Save(sFile, JSON.Encode(jConfig))
End

Por ejemplo en un formulario...
Código:
Public Sub Form_Open()
  Config.Load()
  Print "Color saved", Config.CurrentColor
  Config.CurrentColor = Rand(0, 255)
  Print "Color to save", Config.CurrentColor
  Config.Save()
End

Agregado  - 2021.08.20
Este método extiende la clase JSON y lo que hace es codificar el texto Json en una forma mas legible para humanos. Para usarla tienen que crear una clase en su proyecto que se llame JSON (con mayúsculas) y luego poner este código (Encode2) listo luego en vez de usar JSON.Encode en sus proyectos usen JSON.Encode2 y listo.
Código:
' Gambas class file

'
' Copyright (C) GauchoCAD Team
'
' This program is free software; you can redistribute it and/or modify
' it under the terms of the GNU General Public License as published by
' the Free Software Foundation; either version 2 of the License, or
' (at your option) any later version.

Export

'' Encode in JSON format in a human readable way. Based on a Laurent tool

Static Public Function Encode2(vData As Variant) As String
 
  Dim sInput As String
  Dim sOutput As String
  Dim iStream As Stream
 
  Dim $sReadChar As String
  Dim $iTab As Integer
  Dim $bQuote, $bBracket As Boolean
 
  sInput = JSON.Encode(vData)
 
  iStream = Open String sInput For Read
 
  While (Not Eof(iStream))
    $sReadChar = Read #iStream, 1
    If ($sReadChar = "{" And Not $bQuote) Then
      $iTab += 1
      $sReadChar &= "\n" & Space$($iTab * 2)
    Else If ($sReadChar = "}" And Not $bQuote) Then
      $iTab -= 1
      $sReadChar = "\n" & Space$($iTab * 2) & $sReadChar
    Else If ($sReadChar = "\"") Then
      $bQuote = Not $bQuote
    Else If ($sReadChar = "[") Then
      $bBracket = True
    Else If ($sReadChar = "]") Then
      $bBracket = False
    Else If ($sReadChar = ":" And Not $bQuote) Then
      $sReadChar &= " "
    Else If ($sReadChar = "," And Not $bQuote) Then
      If (Not $bBracket) Then
        $sReadChar &= "\n" & Space$($iTab * 2)
      Else
        $sReadChar &= " "
      Endif
    Endif
    sOutput &= $sReadChar
  Wend
 
  Close iStream
  ' replace null with ""
  sOutput = Replace(sOutput, " null", " \"\"")
 
  Return sOutput
 
End

Agregado  - 2023.05.04 - Proyecto de estudio que utiliza la clase Config. Hay un nuevo control, una clase llamada ListMaker, que permite la edición de lista de datos.

Saludos.
Archivos adjuntos
.gz
json-config-0.0.3.tar.gz (Tamaño: 44.64 KB Descargas: 5)
Última modificación: 05-05-2023, 00:32 por tincho.

1 Saludo.
tercoide   01-06-2021, 16:48
#2
La principal ventaja con respecto a settings es que a medida que el programa se expande , simplemente agregamos variables Public que luego tenemos a mano escribiendo en cualquier parte del codigo Config y el punto. Asi, no tenemos q estar recordandolas. Y si tenemos diversas configuraciones, simplemente copiamos y renombramos la clase: Config, WindowPositions, UserOptions , etc .
Lo cómico es que la clase pueda inspeccionarse a si misma en busca de variables.

"Es mejor saber todo de muy poco que muy poco de todo" - anonimo
Shordi   01-06-2021, 17:04
#3
Está chulo. Supera la clase settings, que es lo que yo ahora uso.

No podemos regresar
tincho   01-06-2021, 19:27
#4
(01-06-2021, 17:04)Shordi escribió: Supera la clase settings

Settings esta bien para unas pocas variables pero tiene dos problemas, uno es que si alguna variable se guarda como, 0, cadena vacía o Null se pierde del archivo de texto, simplemente desaparece, el otro es que la forma de recuperar o escribir datos es  Settings["El_asunto", "default"]  y Settings["El_asunto"] = "123456" y en este sistema hay que recordar el texto exacto, no es posible usar el operador .
Saludos.

1 Saludo.
jguardon   01-06-2021, 20:25
#5
Me ha gustado mucho el detalle de la "introspección", algo muy usual en Python.

La base del funcionamiento son los propios objetos declarados dentro de la clase Config, sin embargo sería genial que no hiciera falta hacerlo y que se creasen dinámicamente a partir del fichero que guardamos. Pero eso ya es otro cantar...

Enhorabuena, me ha gustado mucho!

Por favor, usa el corrector ortográfico antes de pulsar el botón 'Enviar'
tincho   01-06-2021, 21:12
#6
(01-06-2021, 20:25)jguardon escribió: ...sería genial ... que se creasen dinámicamente a partir del fichero que guardamos. Pero eso ya es otro cantar...

Al así como hConfic.AddSymbol .... ? pero aunque se pudiese hacer, creo que es mejor mantenerlo como esta porque el archivo de configuracion no existe la primera vez que se usa el programa.
Saludos.

1 Saludo.
tincho   20-08-2021, 13:30
#7
Hola Amigos.
Hice una actualización, concretamente una clase que Extiende JSON para mejorar la codificación y hacerla mas legible por humanos.
Puse todo al pincipio.
Saludos.

1 Saludo.
tercoide   18-10-2022, 21:18
#8
Estaria bueno extender esta clase pueda guardar otras clases clases que tenga metidas (y tambien arrays de ellas):
Código:
'Clase1.Class
Public var2 as Integer
Public flxData as Float[]
Código:
 
'Clase2.Class
Public Const d1 as Integer = 7
Public inxData as Integer[]  


 
Código:
'Config.Class
Public var1 as Integer
Public arrClass1 as Clase1[]
Public c2 as Clase2

Lo he intentado sin exito. Confused

"Es mejor saber todo de muy poco que muy poco de todo" - anonimo
tincho   18-10-2022, 23:15
#9
(18-10-2022, 21:18)tercoide escribió: Lo he intentado sin exito. Confused

Creo que el problema radica en que vos querés guardar una clase, y me parece que lo que se puede guardar es la instancia de una clase que no es lo mismo.

1 Saludo.
tincho   05-05-2023, 00:29
#10
Retomado el tema.
Vengo usando esta clase desde hace alrededor de dos años ya pero estaba faltando un formulario que edite el archivo .json de forma amena.
Hace un tiempo hice un formulario para editar la configuración pero abordaba las listas y las colecciones con un TextArea lo que no era adecuado.
Actualmente estoy usando un control llamado ListMaker basado en el control de Shordi para editar listas pero que permite editar colecciones simples [1] también, lo que deja a este control en posición de editar casi cualquier tipo de lista.
Dejo el programa en el primer post por si alguien desea echar un vistazo y ayudar a resolver:
  1. Crear un evento "Change" del control (ListMaker) que sea lanzado cuando el evento "Save" del TableView (en FListMaker) ocurra ya que en el formulario FConfig en  el método llamado xData_Change() se pueda actuar para guardar los datos, según el Tag del control, en la coleccion .json.

La idea es que cuando la lista de valores del control cambie que salte un evento Change para que el formulario se "entere" de que la lista cambio.

[1] Son la colecciones en las que el tipo de dato de un ítem nunca es un objeto.

1 Saludo.
Páginas (2): 1 2   
  
Usuarios navegando en este tema: 3 invitado(s)
Powered By MyBB, © 2002-2024 MyBB Group.
Made with by Curves UI.