Club Delphi  
    FTP   CCD     Buscar   Trucos   Trabajo   Foros

Retroceder   Foros Club Delphi > Principal > Varios
Registrarse FAQ Miembros Calendario Guía de estilo Temas de Hoy

Grupo de Teaming del ClubDelphi

Respuesta
 
Herramientas Buscar en Tema Desplegado
  #1  
Antiguo 15-01-2005
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
una ayudita

¡hola foristas!

Si bien muchos están de vacaciones (yo no soy el caso)... necesito una pequeña manito..
Me hice una unidad ListaTema (con 750 líneas de código) que me facilita enormemente el diseño, mantenimiento y edición de una playlist según una estructura definida. Hasta allí todo anda bien...
Pero el problema es que mi reproductor sería "pobre" si no es capaz de entender la estructura que maneja el Winamp para sus playlists.
Se como es dicha estructura:
#EXTM3U // es la cabecera del archivo .m3u
#EXTINF: Duracion,Artista - Tema // estas dos líneas se repiten por cada tema que tiene
Subdirectorio\NombreArchivo // la playlist

El problema es que esta es la estructura de la versión 2.7 Lite, y me he dado cuenta de que si diseño una unidad ListaWinamp que maneje dicha estructura... hay posibilidades de que para versiones posteriores del Winamp sea obsoleta, obligándome a actualizar mi unidad. Y como quiero evitarme escribir otras tantas líneas por cada vez que se le ocurra a NullSoft Inc. cambiarla, me preguntaba si existe alguna unidad o dll que me permita manejar el formato para distintas versiones del Winamp; y así simplificar mis problemas.

Desde ya muchas gracias.
__________________
Delphius
[Guia de estilo][Buscar]

Última edición por Delphius fecha: 15-01-2005 a las 04:50:50.
Responder Con Cita
  #2  
Antiguo 15-01-2005
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
¿Y cómo imaginas que tal unidad o dll (en caso de que exista) va a manejar las distintas versiones? De una u otra forma tendrá que tener código para cada una; así que tu pregunta más bien sería:

¿Existe una unidad o dll que maneje listas de Winamp para no tener yo que programarla?

Es una pregunta válida.

Pero si quieres programarla tú mismo tendrás que manejar la distintas versiones de una u otra forma.

Esto no lo puedes evitar. Pero sí puedes diseñarla de manera que no tengas que alterar el código que ´haga uso de tal unidad.

Para empezar fíjate que la lista como tal la puedes mantener en memoria sin depender del formato en particular. Digamos que cada entrada de la lista la guardas en una clase:

Código Delphi [-]
type
  TWinampItem = class
  public
    property Duration: Double;
    property Artist: String;
    property Theme: String;
  end;

Puedes entonces usar un TObjectList (unidad Contnrs) para almacenar objetos de esta clase.

Entonces lo único que debe preocuparte es cómo leer una lista desde un archivo y como guardarla en un archivo:

Código Delphi [-]
type
  TWinampList = class(TObjectList)
  public
    procedure LoadFromFile(FileName: String); virtual;
    procedure SaveToFile(FileName: String); virtual;
  end;

El declarar los métodos como virtuales te permite diseñar un descendiente de esta clase por cada nueva versión:

Código Delphi [-]
type
  TWinampList27 = class(TWinampList)
    procedure LoadFromFile(FileName: String); override;
    procedure SaveToFile(FileName: String); override;
  end;

  TWinampList31 = class(TWinampList)
    procedure LoadFromFile(FileName: String); override;
    procedure SaveToFile(FileName: String); override;
  end;

  TWinampList56 = class(TWinampList)
    procedure LoadFromFile(FileName: String); override;
    procedure SaveToFile(FileName: String); override;
  end;

Cada descendiente se ocupa del formato en particular para implementar los métodos virtuales. Tu aplicación (o aplicaciones) que requieran usar listas de Winamp lo único que requieren es que se les provea de un objeto TWinampList sin tener que saber exactamente de qué descendiente en particular se trata.

Veamos un ejemplo. Suponte que tu aplicación tiene un botón para cargar una lista de ejecución. Con este botón el usuario escoge un archivo del disco y tu aplicación carga la lista en un ListBox:

Código Delphi [-]
procedure LoadButtonClick(Sender: TObject);
var
  I: Integer;

begin
  if OpenDialog.Execute then
  begin
    WinampList.LoadFromFile(OpenDialog.FileName);

    for I := 0 to WinampList.Count - 1 do
        ListBox.Items.Add(TWinampItem(WinampList[i]).Theme);
  end;
end;

donde WinampList es un objeto de tipo TWinampList (la clase base).

Lo importante aquí es que idependientemente de qué descendiente de TWinampList uses para construir el obejto WinampList, el código de tu botón no cambia, asó como no cambiará cualquier código que deba utilizar WinampList.

Lo que hay que ver entonces es cómo escoges cual descendiente usar:

Código Delphi [-]
WinampList := TWinampList27.Create;
WinampList := TWinampList31.Create;
WinampList := TWinampList56.Create;

sin tener que alterar el código que ya tienes. Lo más simple sería cambiar por la línea adecuada con cada nueva versión y recompilar pero a fin de cuentas no esperarás que todos los usuarios trabajen con la misma versión: quizá quieran leer una lista de un formato distinto al que tienes preparado.

Una opción elegante es usar un fábrica. En la unidad donde declares la clase base, pones una variable global que mantenga una asociación entre la versión y la clase a usar:

Código Delphi [-]
unit WinampList;

interface

uses
  Classes, Contnrs;

type
  TWinampList = class(TObjectList)
  public
    procedure LoadFromFile(FileName: String); virtual; abstract;
    procedure SaveToFile(FileName: String); virtual; abstract;
  end;

  TWinampListClass = class of TWinampList;

var
  Factory: TStringList;

implementation

initialization
  Factory := TStringList.Create;
end.

Factory mantendría la asociación:

'ver27' --> TWinampList27
'ver31' --> TWinampList31
'ver56' --> TWinampList56

etc.

Cada nueva versión la implementas en una unidad distinta y ahí añades la correspondiente asociación:

Código Delphi [-]
unit WinampList27;

interface

uses
  WinampList;

type
  TWinampList27 = class(TWinampList)
    procedure LoadFromFile(FileName: String); override;
    procedure SaveToFile(FileName: String); override;
  end;

implementation

initialization
  Factory.AddObject('ver27', TObject(TWinampList27));
end.

Con esto, lo único que necesitas para construir WinampList adecuadamente es una cadena con el número de versión:

Código Delphi [-]
var
  Version: String; // contiene el número de versión

...

var
  WinampList: TWinampList;
  WinampListClass: TWinampListClass;

begin
  WinampListClass := TWinampListClass(Factory.Objects[Version]);
  WinampList := WinampListClass.Create;
end;

Al requerir sólo el número de versión para construir la clase adecuada logras no tener que incluir la unidad correspondiente en el código de tu aplicación, únicamente tienes que incluir la unidad de la clase base: WinampList. Así tal código no necesita ni siquiera ser recompilado con cada versión nueva que aparezca.

Incluso puedes permitir que el usuario escriba el mismo de qué versión es la lista que va a leer y todo el formulario donde haga esto no cambia en lo absoluto con la aparición de nuevas versiones.

Tomando en cuenta que el código del botón para leer una lista desde el disco es seguramente tan sólo un ejemplo, en balance, aun cuando debes preocuparte por implementar LoadFromFile y SaveToFile para cada versión, ganas bastante al dejar intacto todo el código alrededor.

// Saludos
Responder Con Cita
  #3  
Antiguo 15-01-2005
Avatar de Delphius
[Delphius] Delphius is offline
Miembro Premium
 
Registrado: jul 2004
Ubicación: Salta, Argentina
Posts: 5.582
Poder: 25
Delphius Va camino a la fama
muchisimas gracias roman...

Muchisimas gracias Roman...
Pedí una ayudita y me diste una ayuda enorme... gracias... pondré en práctica lo que me pasaste...
Eso me demuestra que me hace falta leer un poco la Cara Oculta de Delphi y no tenerlo de adorno... no sabía que se podría hacer eso
__________________
Delphius
[Guia de estilo][Buscar]
Responder Con Cita
  #4  
Antiguo 15-01-2005
Avatar de roman
roman roman is offline
Moderador
 
Registrado: may 2003
Ubicación: Ciudad de México
Posts: 20.269
Poder: 10
roman Es un diamante en brutoroman Es un diamante en brutoroman Es un diamante en bruto
Si te vas a poner manos a la obra te recomiendo que leas acerca de las referencias de clase (class references). Variables del tipo TWinampListClass son referencias de clase, es decir variables cuyos valores son un tipo de datos: TWinampList27, TWinampList32, etc. y te permiten construir polimórficamente un objeto. De esto puedes encontrar información en la misma ayuda de Delphi. También deberás agregar un constructor virtual a la clase base TWinampList pues creo que TObjectList no lo tiene y es imprescindible para que funcionen las referencias de clases.

Por último te recomiendo que antes de entrar a los detalles de como manejar un formato en particular hagas pruebas con toda la estructura alrededor (la definición de las clases, la fábrica, etc. para ver que se crean bien los objetos del tipo adecuado. Y hasta que tengas listo eso, te metes con los detalles técnicos de los formatos.

// Saludos
Responder Con Cita
  #5  
Antiguo 16-01-2005
Avatar de Lepe
[Lepe] Lepe is offline
Miembro Premium
 
Registrado: may 2003
Posts: 7.424
Poder: 29
Lepe Va por buen camino
OFFTOPIC:
Nunca he mirado el menú "Puntuar HIlo" y para una vez que lo miro, falta una opción por encima de "Excelente"

Me he quedado alucinado no sólo con la técnica explicada, sino aún más viendo la claridad con la que ha sido expuesta.

Un saludo enorme para Roman
Responder Con Cita
Respuesta



Normas de Publicación
no Puedes crear nuevos temas
no Puedes responder a temas
no Puedes adjuntar archivos
no Puedes editar tus mensajes

El código vB está habilitado
Las caritas están habilitado
Código [IMG] está habilitado
Código HTML está deshabilitado
Saltar a Foro


La franja horaria es GMT +2. Ahora son las 10:33:51.


Powered by vBulletin® Version 3.6.8
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Traducción al castellano por el equipo de moderadores del Club Delphi
Copyright 1996-2007 Club Delphi