unit uRobotEscritorOptimizadorMulticore;

{$IFDEF FPC}
  {$MODE Delphi}
{$ENDIF}

interface

uses
{$IFDEF WIN32}
  ipcthrd,
{$ELSE}
  uEmuladorWinIPC, uKeyDir,
{$ENDIF}
  ugestorsalasmh_OLD,
  xMatDefs, classes, SysUtils, uSalasDeJuego;

const
  toSpinlocks = 1000;  

type
  TRobotEscritorOptimizadorMultiCore = class(TThread)
    public
      gestorSala: TGestorSalaMH;
      pasoAEscribir: Integer;
      Constructor Create(gestorSala: TGestorSalaMH; const costoFuturo: TMatOfNReal);
      procedure Execute; override;
  end;

var
  ultimoPasoCalculado: Integer;
  abortar_calculo: boolean;
  //nomSemPasoEscritura,
  nomEvPasoCompletoEscritor: String;

implementation

Constructor TRobotEscritorOptimizadorMultiCore.Create(
  gestorSala: TGestorSalaMH; const costoFuturo: TMatOfNReal);
begin
  inherited Create(true);
  //cargarSala se debe hacer secuencial
  self.gestorSala:= TGestorSalaMH.Create( nil );
  self.gestorSala.cargarSala(gestorSala.sala.archiSala, gestorSala.sala.EscenarioActivo.nombre, true);
  self.gestorSala.sala.idHilo:= 1000;

  self.gestorSala.copiarVarsTiempoEjecucion(gestorSala);

  self.gestorSala.sala.estabilizarInicio:= false;
  self.gestorSala.nHilos:= gestorSala.nHilos;
  self.gestorSala.sala.inicializarOptimizacion( gestorSala.sala, costoFuturo);
  self.Start;
end;

procedure TRobotEscritorOptimizadorMultiCore.Execute;
var
//  semPasoEscritura: TMutex;
{$IFDEF WIN32}
  evPasoCompletoEscritorRx: TEvent;
{$ELSE}
  evPasoCompletoEscritorRx: TEventRX;
{$ENDIF}
  fsal: TextFile;
  fsalopt: TDAOfTextFile;
  fsalopen: boolean;
begin
  self.Priority:= tpLowest; //Menos prioridad, que no interrumpa los calculos
{$IFDEF WIN32}
//  semPasoEscritura:= TMutex.Create(nomSemPasoEscritura);
  evPasoCompletoEscritorRx:= TEvent.Create(nomEvPasoCompletoEscritor, false);
{$ELSE}
//  semPasoEscritura:= TMutex.Create(nomSemPasoEscritura, 1);
  evPasoCompletoEscritorRx:= TEventRx.Create(nomEvPasoCompletoEscritor, 1);
{$ENDIF}
  gestorSala.sala.inicializarArchisOptRes(fsal, fsalopt, fsalopen);

{  if not semPasoEscritura.Get(toSpinlocks) then
  begin
    writeln('TRobotEscritorOptimizadorMultiCore.Execute: No obtuve semPasoEscritura 1');
  end
  else
  begin}
    pasoAEscribir:= gestorSala.sala.globs.NPasos;
    while (pasoAEscribir > 0) and not Terminated do
    begin
      if not Terminated and not evPasoCompletoEscritorRx.Wait(60000) then
      begin
        writeln('TRobotEscritorOptimizadorMultiCore.Execute: No me despertaron de evPasoCompletoEscritorRx 2');
        Terminate;
      end;
      while (pasoAEscribir >= ultimoPasoCalculado) and not Terminated do
      begin
//        semPasoEscritura.Release;
        gestorSala.sala.escribirPasoOptRes(fsal, fsalopt);
        gestorSala.darPaso;
{        if not semPasoEscritura.Get(toSpinlocks) then
        begin
          writeln('TRobotEscritorOptimizadorMultiCore.Execute: No obtuve semPasoEscritura 2');
          Terminate;
        end;}
        pasoAEscribir:= pasoAEscribir - 1;
      end;
//      semPasoEscritura.Release;
    end;
 // end;

  gestorSala.sala.cerrarArchisOptRes(fsal, fsalopt, fsalopen);

  //semPasoEscritura.Free;
  evPasoCompletoEscritorRx.Free;
  self.gestorSala.Free;
writeln('Fin Escritor');  
end;

initialization
{$IFDEF WIN32}
//  nomSemPasoEscritura:= 'nomSemPasoEscritura';
  nomEvPasoCompletoEscritor:= 'nomEvPasoCompletoEscritor';
{$ELSE}
//  nomSemPasoEscritura:= uKeyDir.keyBaseDir + '/nomSemPasoEscritura';
  nomEvPasoCompletoEscritor:= uKeyDir.keyBaseDir + '/nomEvPasoCompletoEscritor';
{$ENDIF}

end.
