unit uActores;

{$MODE Delphi}

interface

uses
  xmatdefs, usimplex, Classes, SysUtils,
  uglobs, ufichasLPD, ucosa,
  ucosaparticipedemercado,
  ufechas, uEstados, uCosaConNombre, uranddispos, uforzamientos;

resourcestring
  rsNombre = 'Nombre';
  rsTipoDeActor = 'Tipo de actor';
  rsInformacioNAdicional = 'Información adicional';

type
  PActor = ^TActor;

  TFichaUnidades = class(TFichaLPD)
  public
    nUnidades: TDAofNInt;
    constructor Create(fecha: TFecha; periodicidad: TPeriodicidad;
      nUnidades_: TDAofNInt);
    procedure Free; override;
    constructor Create_ReadFromText(f: TArchiTexto); override;
    procedure WriteToText(f: TArchiTexto); override;
    function InfoAd_: string; override;
    procedure generarLineaResumen(var archi: TextFile); override;
  end;


  TRotRep_rec = record
    cnt_OK, cnt_Rotas: integer; // cantidad de undiades OK
    FDispo: NReal; // factor de disponibilidad fortuita
    TMRep_h: NReal; // tiempo medi de reparción en horas.
    pRep: NReal; // Probabilidad de reparción dado que estaba Roto
    pRot: NReal; // Porbabilidad e Rotura dado que estaba OK.

    // indica que en estas unidades aplicar sorteo estatico
    // Este parámetro se pone a TRUE si el tiempo de reparción es inferior
    // al tiempo del paso para que en ese caso no considere el modelo con estado
    UsarSorteoEstatico: boolean;
  end;



  TActor = class(TCosaParticipeDeMercado)
  public
    nacimiento, muerte: TFecha;

    lpdUnidades: TFichasLPD;
    paUnidades: TFichaUnidades;
    unidades_RotRep: array of TRotRep_rec;

    lpdForzamientos: TFichasLPD;
    paForzamiento: TFichaForzamientos;

    ivar, ires, ivae: integer;
    ixr, ixd: integer;
    iauxr, iauxd: integer;

    (*
// Guarda el costo incurrido para generar la energía en el último paso.
// En este costo deben ponerse los costos térmicos y no los costos asociados
// a valorizar el agua (o otro recurso guardado en varialbles de estado).
// Este valor se utiliza para calcular el costo de cada paso en la
// optimización dinámica estocástica en base a la cual luego se determinan
// los valores del agua de los diferentes embalses. También se dispone
// de este valor durante la simulación para calcular el costo de la etapa.
// Los actores deben fijar el valor de esta variable durante la lectura de
// los resultados del paso.
  *)
    costoDirectoDelPaso: NReal;

    (* Los actores que tienen función de UTILIDAD pueden completar este valor *)
    utilidadDirectaDelPaso: NReal;

  {$IFDEF CALC_MMEE}
    mmee_cv_paraPrecioSpot: TDAOfNReal;
    mmee_IngresosSpot_USD: TDAOfNReal;
    mmee_CargosAlSeguimientoDeLaDemanda_USD: TDAOfNReal;
  {$ENDIF}

    constructor Create(nombre: string; nacimiento, muerte: TFecha;
      lpdUnidades: TFichasLPD); reintroduce;
    constructor Create_ReadFromText(f: TArchiTexto); override;

    procedure WriteToText(f: TArchiTexto); override;

    //Retorna el valor esperado de la potencia que requiere o entrega el actor
    function PotenciaFirme: NReal; virtual; abstract;

    //function InfoAd: string; override;

    // antes de correr luego de creados y resultas las referencias
    // se llama este proc. para que se preparen (creen los espacios de datos) necesarios.
    procedure PrepararMemoria(globs: TGlobs); override;
    procedure RegistrarParametrosDinamicos; virtual;

    //      procedure Sim_Inicio; virtual;
    procedure Sim_Cronica_Inicio; virtual;

    procedure prepararPaso_as; virtual; // preparación previa a los sorteos.
    procedure SorteosDelPaso(sortear: boolean); virtual;
    //aquí hacer todos los sorteos necesarios
    procedure PrepararPaso_ps; virtual;
    // aquí leer el valor de las variables de estado y
    // del resultado de SorteosDelPaso para calcular lo necesario
    // para jugar en el paso de tiempo que se inicia


    // Procedimientos especificos para la resolucion del despaho en un paso de tiempo

    // (ivar) NUMERO DE VARIABLES DE CONTROL REALES y ENTERAS
    // Almacena el valor de ivar (como el indice donde comienzan las variables de control de este actor )
    // e incrementa ivar en la cantidad de variables que son necesarias para este actor.
    // (ivae) NUMERO DE VARIABLES ENTERAS - (deben ser contabilizadas en ivar también)
    // (ires) NUMERO DE RESTRICCIONES ADICIONALES
    // Almacena el valor de ires (indice donde comienzan las restriccinoes adicionales de este actor)
    // e incrementa ires con la cantidad de restricciones Adicionales que agrega el actor.
    // Las llamamos restricciones adicionales para diferenciarlas de las de CAJA.
    procedure opt_nvers(var ivar, ivae, ires: integer); virtual;

    // Carga el aporte del actor a la matriz del Simplex.
    procedure opt_cargue(s: TSimplex); virtual;
    procedure opt_fijarRestriccionesDeCaja(s: TSimplex); virtual;
    procedure opt_leerSolucion(s: TSimplex); virtual;

    // para pasar datos al Flucar.
    procedure opt_WriteToFlucarStatusFile(var f: textfile); virtual;

    // X:= Xs ; se corre luego de aceptada la solución de un paso
    procedure EvolucionarEstado; virtual;

    procedure Sim_Paso_Fin; virtual;
    procedure Sim_Cronica_Fin; virtual;
    //      procedure Sim_Fin; virtual;




(*+doc NecesitaIterar
  Esta función la llamamos luego de leer los resultados del paso para darle la
  oportunidad a los Actores de solicitar que se corra nuevamente este paso.
 El resultado est TRUE si el Actor estima que requiere iterar para ajustar su
 modelo en la resolución del paso (o etapa).
 El parámetro kIteracion es el número de iteración, y se pasa e 1 para la primer
 llamada de la función. El actor debe calcular un error relativo de ajuste de
 su modelo de acuerdo con los resultados leídos al final de la etapa y retornarlo
 en errRelativo, para que el algoritomo que contrala las iteraciones pueda
 tomar en cuenta la necesidad de iterar del actor. -doc*)
    function opt_necesitoIterar(kIteracion: integer; var errRelativo: NReal): boolean;
      virtual; abstract;

    // Estre procedimiento es llamado al inicio de cada paso durante el proceso de
    // optimización dinámica para que cada actor se posicione de acuerdo con la Estrellita
    // que representa el estado global del sistema al inicio del paso que se optimizará.
    // Este procedimento es el primero a llamar como preparación de un paso para que
    // cualquier cálculo que realicen los actores lo hagan conociendo su estado de inicio.
    procedure PosicionarseEnEstrellita; virtual;

    // Este procedimiento es llamado al inicio de cada paso durante el proceso de simulación
    // para que cada actor actualice su estado en el estado global del sistema.
    // Esto se hace al inicio del paso, antes de realizar los sorteos para que todo lo que calculen los
    // actores como preparación del paso lo puedan hacer con conocimiento del estado global
    // al inicio del paso.
    procedure ActualizarEstadoGlobal; virtual;

    // Si el actor tiene variables auxiliares debe usar este método para cargar
    // en el FRAME_1 de auxiliares el valor resultado de la optimización.
    procedure SetAux1; virtual;
    // Si el actor tiene variables auxiliares debe usar este método para acumular
    // el resultado de la optimización multiplicado por peso en el FRAME1 de
    //variables auxiliares.
    procedure AcumAux1(peso: NReal); virtual;

    // NUMERO DE VARIABLES DE ESTADO CONTINUAS DISCRETAS, auxiliares CONTINUAS, auxiliares DISCRETAS
    // Almacena el valor de ixr (indice dónde comienzan las variables de estado
    // del actor en el vector de variables de estado continuas e incrementa
    // el valor de ixr en la cantidad de variables de estado continuas que necesita
    // el actor.
    // En ixd almacena donde comienza la discreta.
    // ------ Variables auxiliares ----
    // Son para almacenar un valor asociado a que el Actor se encuentre en un determinado estado.
    // esto se hace así para facilitar la optimización. Por ejemplo, si para el cálculo de la pérdida de
    // salto se quiere utilizar el caudal erogado en la etapa antes calculada, hay que guardar el caudal erogado
    // en una variable auxiliar para luego usar el de la etapa anterior, que corresponde a la misma estrella
    // en el espacio de estados. En la simulación se tomará simplemente el caudal erogado en el paso anterior
    // pues se supone que hay cierta continuidad en la trayectoria del estado.
    // En iauxNReal almacenamos el índice de las auxiliaers continuas el actor debe incrementar este valor en
    // el número de variables que requiere almacenar.
    // En iauxInt almacena el índice de las auxileares enteras. El actor debe incrementar este valor en el número
    // de variables enteras que requiere que se almacenen.
    procedure optx_nvxs(var ixr, ixd, iauxNReal, iauxInt: integer); virtual;

    // Registra las variables en el administrador de variables de estado
    procedure optx_RegistrarVariablesDeEstado(adminEstados: TAdminEstados); virtual;

{$IFDEF SPXCONLOG}
    //Asigna nombre a las restricciones y variables que aporta el actor al simplex
    procedure spx_NombrarVariables(s: TSimplex); virtual; abstract;
{$ENDIF}

    function getNombreVar(ivar: integer; var nombre: string): boolean; virtual;
    function getNombreRes(ires: integer; var nombre: string): boolean; virtual;

    procedure entrarEnMantenimientoTotal; virtual; abstract;
    procedure Free; override;


    // Escribe en fsal los encabezados de printResumenSim
    class procedure printEncabezadoResumenSim(var fsal: TextFile);

    // Escribe en fsal una linea con Clase, nombre, e infoAd
    procedure printResumenSim(var fsal: TextFile);

    // procedimiento usado para salvar resultados al fin del cálculo del costo de cada
    // estrellita durante la optimización.
    // ATENCION NO USAR WRITELN, usar write( #9, valor [, #9, valor..] )
    // Los resultados de optimización se salvan en un archivo separado para cada
    // actor.
    procedure opt_PrintResultados_Encab(var fsal: textfile); virtual; abstract;
    procedure opt_PrintResultados(var fsal: textfile); virtual; abstract;

    //Si hay un problema resolviendo el simplex, la sala llama este procedimiento sobre
    //todos los actores para que escriban los valores de sus variables al momento de romperse
    procedure dump_Variables(var f: TextFile; charIndentacion: char); virtual;


    // llamar este procedimiento si hay cambio del factor de disponibilidad de las
    // unidades del actor para que se actuailcen las probabilidades de transición
    procedure ActualizarProbabilidadesReparacionYRotura(
      Nuevo_FDisp, Nuevo_TMRep: NReal; kTipoUnidad: integer = 0);

    // retorna la cantidad de máquinas disponibles
    function Sorteos_RepRotUnidades: integer;
    function Sorteos_RepRotUnidades_k(kTipoUnidad: integer): integer;

    class function CreateDefaultLPDUnidades_(cuantasUnidadesDiferentes: integer):
      TFichasLPD;
    class function CreateDefaultLPDForzamientos_(
      cuantasVariablesDiferentes: integer): TFichasLPD;

    function hayForzamientos: boolean;
  end;


  TClaseDeActor = class of TActor;

procedure AlInicio;
procedure AlFinal;

//procedure gestionarCambioMantenimiento(actor : TCosa);

var
  //En cada implementación de actor al llamar al inherited registrarParametrosDinamicos
  //hay que asignar en este puntero el procedimiento que se quiere usar al cambiar
  //la ficha de unidades de ese actor en particular.
  //Si se le asigna un valor, luego de la llamada al inherited registrarParametrosDinamicos
  //se debe setear en nil
  procCambioFichaUnidades: TProcCalculosAdicionales;
  procCambioFichaForzamientos: TProcCalculosAdicionales;


// función para order listas de actores.
function Sort_Actores_By_DT_DESC(a1, a2: TActor): integer;

implementation



function Sort_Actores_By_DT_DESC(a1, a2: TActor): integer;
begin
  if a1.nacimiento.dt < a2.nacimiento.dt then
    Result := 1
  else if a1.nacimiento.dt > a2.nacimiento.dt then
    Result := -1
  else
    Result := 0;
end;


//-------------------------
//Metodos de TFichaUnidades
//=========================
constructor TFichaUnidades.Create(fecha: TFecha; periodicidad: TPeriodicidad;
  nUnidades_: TDAofNInt);
begin
  inherited Create(fecha, periodicidad);
  self.nUnidades := copy(nUnidades_);
end;

procedure TFichaUnidades.Free;
begin
  setlength(nUnidades, 0);
  inherited Free;
end;


constructor TFichaUnidades.Create_ReadFromText(f: TArchiTexto);
begin
  inherited Create_ReadFromText(f);
  f.IniciarLecturaRetrasada;

  if f.Version <= 50 then
  begin
    SetLength(nUnidades, 1);
    f.rd('nUnidades', nUnidades[0]);
  end
  else
    f.rd('nUnidades', nUnidades);

  f.EjecutarLectura;
end;

procedure TFichaUnidades.WriteToText(f: TArchiTexto);
begin
  inherited WriteToText(f);
  f.wr('nUnidades', nUnidades);
end;

function TFichaUnidades.infoAd_: string;
begin
  Result := inherited infoAd_ + DAOfNIntToStr(self.nUnidades, ';');
end;

procedure TFichaUnidades.generarLineaResumen(var archi: TextFile);
begin
  Write(archi, nUnidades[0], #9);  //NUnidades
end;



//------------------
// Métodos de TActor
//==================
constructor TActor.Create(nombre: string; nacimiento, muerte: TFecha;
  lpdUnidades: TFichasLPD);
begin
  inherited Create(nombre);
  Self.globs := nil; // lo carga en prepararse
  Self.nacimiento := TFecha.Create_Clone(nacimiento);
  Self.muerte := TFecha.Create_Clone(muerte);
  self.lpdUnidades := lpdUnidades;
  if self.lpdUnidades <> nil then
    self.lpdUnidades.Propietario := self;
  self.lpdForzamientos := TFichasLPD.Create('lpdForzamientos', self, TFichaForzamientos);
end;

constructor TActor.Create_ReadFromText(f: TArchiTexto);
var
  cantUnidades: TDAofNInt;
  u_Forzadas: TDAOfNReal;
  k: integer;

begin
  inherited Create_ReadFromText(f);
  f.IniciarLecturaRetrasada;
  f.rd('nacimiento', nacimiento);
  f.rd('muerte', muerte);
  f.rd('lpdUnidades', TCosa(lpdUnidades));
  if f.Version >= 86 then
    f.rd('lpdForzamientos', TCosa(lpdForzamientos))
  else
    lpdForzamientos := TFichasLPD.Create('lpdForzamientos', self,
      TFichaForzamientos);


  f.EjecutarLectura;




  // sin no hay fichas de unidades, por defecto supongo que se trata de un actor
  // con un solo tipo de unidades y que inicia con una unidad disponible desde
  // el inicio de los tiempos.
  lpdUnidades.Propietario := self;
  if lpdUnidades.Count = 0 then
  begin
    SetLength(cantUnidades, 1);
    cantUnidades[0] := 1;
    lpdUnidades.Add(TFichaUnidades.Create(TFecha.Create_Str('0'), nil, cantUnidades));
  end;

  paForzamiento := nil;
  lpdForzamientos.Propietario := self;
  setlength(u_Forzadas, 1);
  u_Forzadas[0] := 0;
  if lpdForzamientos.Count = 0 then
    lpdForzamientos.add(TFichaForzamientos.Create(
      TFecha.Create_Str('0'), nil, False, u_Forzadas))
  else
  begin
    // ojo corrigo error de la version 86 q
    if TFichaLPD(lpdForzamientos.items[0]).ClassType = TFichaUnidades then
    begin
      for k := 0 to lpdForzamientos.Count - 1 do
        TFichaLPD(lpdForzamientos.items[0]).Free;
      lpdForzamientos.Clear;
      lpdForzamientos.add(TFichaForzamientos.Create(
        TFecha.Create_Str('0'), nil, False, u_Forzadas));
    end;
  end;
end;


function TActor.hayForzamientos: boolean;
begin
  Result := (globs.EstadoDeLaSala = CES_SIMULANDO) and (paForzamiento <> nil) and
    paForzamiento.activar_forzamiento;
end;

{function TActor.infoAd: string;
var
  cadena: string;
begin
  cadena := inherited infoAd;
  if cadena <> '' then
    cadena := cadena + ', ';
  cadena := cadena + nacimiento.AsStr + ', ' + muerte.AsStr;
  Result := cadena;
end;}

procedure TActor.WriteToText(f: TArchiTexto);
begin
  inherited WriteToText(f);
  f.wr('nacimiento', nacimiento);
  f.wr('muerte', muerte);
  f.wr('lpdUnidades', TCosa(lpdUnidades));
  f.wr('lpdForzamientos', TCosa(lpdForzamientos));
end;

procedure TActor.prepararMemoria(globs: TGlobs);
begin
  inherited PrepararMemoria(globs);
  setlength(self.unidades_RotRep, length(
    TFichaUnidades(self.lpdUnidades.items[0]).nUnidades));
  {$IFDEF CALC_MMEE}
  setlength(mmee_cv_paraPrecioSpot, globs.NPostes);
  setlength(mmee_IngresosSpot_USD, globs.NPostes);
  setlength(mmee_CargosAlSeguimientoDeLaDemanda_USD, globs.NPostes);
  {$ENDIF}
  CostoDirectoDelPaso := 0;
  UtilidadDirectaDelPaso := 0;
end;

procedure TActor.registrarParametrosDinamicos;
//Hice este cambio porque en delphi 2010 da un error raro.
//Si haces build te dice que no hay una versión sobrecargada de RegistrarFichasAActualizar
//que pueda ser llamada con los parámetros que habían, pero si le das compilar compila bien
//y corre, ahora cambie esto y no se me quejó al hacer build. El comportamiento es el mismo
var
  procCambioFicha: TProcCalculosAdicionales;
begin
  procCambioFicha := @procCambioFichaUnidades;
  lpdUnidades.expandirFichas(globs);
  lpdUnidades.RegistrarFichasAActualizar(Self, globs.ActualizadorLPD,
    @paUnidades, nil, procCambioFicha);


  paForzamiento := nil;
  if lpdForzamientos <> nil then
  begin
    procCambioFicha := @procCambioFichaForzamientos;
    lpdForzamientos.expandirFichas(globs);
    lpdForzamientos.RegistrarFichasAActualizar(Self, globs.ActualizadorLPD,
      @paForzamiento, nil, procCambioFicha);
  end;
end;

(*
function TActor.CostoDirectoDelPaso: NReal;
begin
  result:= 0;
end;
  *)

class procedure TActor.printEncabezadoResumenSim(var fsal: TextFile);
begin
  writeln(fsal, rsNombre, #9, rsTipoDeActor, #9, rsInformacionAdicional);
end;

procedure TActor.printResumenSim(var fsal: TextFile);
begin
  writeln(fsal, nombre, #9, ClassName, #9, InfoAd_);
end;

procedure TActor.dump_Variables(var f: TextFile; charIndentacion: char);
begin
  writeln(f, self.claseNombre);
end;

procedure TActor.Free;
begin
  {$IFDEF CALC_MMEE}
  setlength(mmee_cv_paraPrecioSpot, 0);
  setlength(mmee_IngresosSpot_USD, 0);
  setlength(mmee_CargosAlSeguimientoDeLaDemanda_USD, 0);
  {$ENDIF}

  nacimiento.Free;
  muerte.Free;
  if lpdUnidades <> nil then
    lpdUnidades.Free;
  setlength(unidades_RotRep, 0);
  inherited Free;
end;

procedure TActor.Sim_Cronica_Inicio;
var
  k: integer;
begin
  // Inicializamos el estado de unidades disponibles
  // Por defecto suponemos que todas las que no están en mantenimiento
  // programado como operativas

  for k := 0 to high(paUnidades.nUnidades) do
  begin
    self.unidades_RotRep[k].cnt_OK := paUnidades.nUnidades[k];
    self.unidades_RotRep[k].cnt_Rotas := 0;
  end;
end;

procedure TActor.SorteosDelPaso(sortear: boolean);
begin

end;

procedure TActor.prepararPaso_as;
begin
end;

procedure TActor.prepararPaso_ps;
begin
end;


procedure TActor.Sim_Paso_Fin;
begin
end;

procedure TActor.EvolucionarEstado;
begin
end;

procedure TActor.Sim_Cronica_Fin;
begin
end;

procedure TActor.opt_nvers(var ivar, ivae, ires: integer);
begin
  // nada;
end;

// Carga el aporte del actor a la matriz del Simplex.
procedure TActor.opt_cargue(s: TSimplex);
begin
  // nada;
end;

procedure TActor.opt_fijarRestriccionesDeCaja(s: TSimplex);
begin
  // nada;
end;

procedure TActor.opt_leerSolucion(s: TSimplex);
begin
  // nada;
end;


procedure TActor.opt_WriteToFlucarStatusFile(var f: textfile);
begin
  // nada;
end;


procedure TActor.PosicionarseEnEstrellita;
begin
  // nada;
end;

procedure TActor.ActualizarEstadoGlobal;
begin
  // nada;
end;

// Si el actor tiene variables auxiliares debe usar este método para cargar
// en el FRAME_1 de auxiliares el valor resultado de la optimización.
procedure TActor.SetAux1;
begin
end;

// Si el actor tiene variables auxiliares debe usar este método para acumular
// el resultado de la optimización en el FRAME1 de variables auxiliares.
procedure TActor.AcumAux1(peso: NReal);
begin
end;

procedure TActor.optx_nvxs(var ixr, ixd, iauxNReal, iauxInt: integer);
begin
  // nada;
end;

procedure TActor.optx_RegistrarVariablesDeEstado(adminEstados: TAdminEstados);
begin
  //nada;
end;


procedure TActor.ActualizarProbabilidadesReparacionYRotura(
  Nuevo_FDisp, Nuevo_TMRep: NReal; kTipoUnidad: integer);
begin
  unidades_RotRep[kTipoUnidad].FDispo := Nuevo_FDisp;
  unidades_RotRep[kTipoUnidad].TMRep_h := Nuevo_TMRep;

  urandDispos.Calc_pRep_pRot(
    unidades_RotRep[kTipoUnidad].UsarSorteoEstatico,
    unidades_RotRep[kTipoUnidad].pRep, unidades_RotRep[kTipoUnidad].pRot,
    Nuevo_FDisp, Nuevo_TMRep, globs.HorasDelPaso);
end;


function TActor.Sorteos_RepRotUnidades: integer;
begin
  Result := Sorteos_RepRotUnidades_k(0);
  Result := unidades_RotRep[0].cnt_OK;
end;


function TActor.Sorteos_RepRotUnidades_k(kTipoUnidad: integer): integer;
var
  pu: TRotRep_rec;
begin
  pu := unidades_RotRep[kTipoUnidad];
  if (globs.EstadoDeLaSala = CES_OPTIMIZANDO) or pu.UsarSorteoEstatico then
    rndDispoNMaquinas_fd(pu.FDispo, pu.cnt_OK, pu.cnt_Rotas, sorteadorUniforme)
  else
    rndDispoNMaquinas_RotRep(pu.cnt_OK, pu.cnt_Rotas, pu.pRep,
      pu.pRot, sorteadorUniforme);
  Result := pu.cnt_OK;
end;


class function TActor.CreateDefaultLPDUnidades_(cuantasUnidadesDiferentes:
  integer): TFichasLPD;
var
  res: TFichasLPD;
  cantUnidades: TDAofNInt;
  i: integer;
begin
  SetLength(cantUnidades, cuantasUnidadesDiferentes);

  for i := 0 to cuantasUnidadesDiferentes - 1 do
    cantUnidades[i] := 1;

  res := TFichasLPD.Create('lpdUnidades', nil, TFichaUnidades);
  res.Add(TFichaUnidades.Create(TFecha.Create_Str('0'), nil, cantUnidades));
  Result := res;
end;

class function TActor.CreateDefaultLPDForzamientos_(
  cuantasVariablesDiferentes: integer): TFichasLPD;
var
  res: TFichasLPD;
  Forzamientos: TDAofNReal;
  i: integer;
begin
  SetLength(Forzamientos, cuantasVariablesDiferentes);
  for i := 0 to cuantasVariablesDiferentes - 1 do
    Forzamientos[i] := 0.0;
  res := TFichasLPD.Create('lpdFrorzamientos', nil, TFichaForzamientos);
  res.Add(TFichaForzamientos.Create(TFecha.Create_Str('0'), nil, False, Forzamientos));
  Result := res;
end;


function TActor.getNombreVar(ivar: integer; var nombre: string): boolean;
begin
  Result := False;
end;

function TActor.getNombreRes(ires: integer; var nombre: string): boolean;
begin
  Result := False;
end;


procedure AlInicio;
begin
  //  registrarClaseDeCosa( TActor.ClassName, TActor );
  registrarClaseDeCosa(TFichaUnidades.ClassName, TFichaUnidades);
end;

procedure AlFinal;
begin
end;

end.
