Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- unit uReplayAnalyzer;
- interface
- uses
- Winapi.Windows, System.Classes, Data.DB, DBAccess, Uni, UniProvider,
- SQLServerUniProvider, MemDS;
- const
- DENSITY_MATRIX_SIZE = 10000;
- type
- TAnalyzerData = record
- TotalMatches : DWORD;
- GoodGuysWin : DWORD;
- BadGuysWin : DWORD;
- DurationDensity : Array[0..DENSITY_MATRIX_SIZE] of DWORD;
- FirstBloodDensity: Array[0..DENSITY_MATRIX_SIZE] of DWORD;
- TimeDensity : Array[0..DENSITY_MATRIX_SIZE] of DWORD;
- LastTime : DWORD;
- end;
- type
- TReplayAnalyzerProgress = procedure(Sender: TObject; const AProgress: Integer) of object;
- TReplayAnalyzer = class(TThread)
- private
- var
- FRowFrom : DWORD;
- FRowTo : DWORD;
- FReplayProgress: Integer;
- FData : TAnalyzerData;
- FConnection : TUniConnection;
- FQuery : TUniQuery;
- FCurrMatchId : String;
- FStartDate : TDateTime;
- FOnReplayProgress: TReplayAnalyzerProgress;
- FOnAnalyzeDone : TNotifyEvent;
- function Analyze: Boolean;
- procedure syncReplayProgress;
- procedure syncAnalyzeDone;
- procedure QueryAfterExecute(Sender: TObject; Result: Boolean);
- protected
- procedure Execute; override;
- public
- constructor Create(const AConnection: TUniConnection; const ARowFrom, ARowTo: DWORD);
- destructor Destroy; override;
- property OnReplayProgress: TReplayAnalyzerProgress read FOnReplayProgress write FOnReplayProgress;
- property OnAnalyzeDone : TNotifyEvent read FOnAnalyzeDone write FOnAnalyzeDone;
- property Progress : Integer read FReplayProgress;
- property Data : TAnalyzerData read FData;
- end;
- implementation
- uses
- System.SysUtils, System.StrUtils, System.DateUtils,
- uCommon;
- constructor TReplayAnalyzer.Create(const AConnection: TUniConnection; const ARowFrom, ARowTo: DWORD);
- begin
- inherited Create(TRUE);
- FreeOnTerminate := TRUE;
- FConnection := AConnection;
- FRowFrom := ARowFrom;
- FRowTo := ARowTo;
- // FStartDate := EncodeDate(2010, 12, 09);
- FStartDate := EncodeDate(2011, 08, 01);
- end;
- destructor TReplayAnalyzer.Destroy;
- begin
- inherited;
- end;
- function TReplayAnalyzer.Analyze: Boolean;
- var
- f_match_id : String;
- f_fb_time : Int64;
- f_duration : Int64;
- f_datetime : TDateTime;
- days_between: Integer;
- begin
- result := FALSE;
- f_match_id := FQuery.FieldByName('match_id').AsString;
- if FCurrMatchId <> f_match_id then
- begin
- FCurrMatchId := f_match_id;
- if FQuery.FieldByName('good_guys_win').AsBoolean then
- Inc(FData.GoodGuysWin)
- else
- Inc(FData.BadGuysWin);
- f_fb_time := FQuery.FieldByName('first_blood_time').AsLargeInt;
- if f_fb_time > 0 then
- begin
- if f_fb_time > DENSITY_MATRIX_SIZE - 1 then
- Inc(FData.FirstBloodDensity[DENSITY_MATRIX_SIZE])
- else
- Inc(FData.FirstBloodDensity[f_fb_time]);
- end;
- f_duration := FQuery.FieldByName('duration').AsLargeInt;
- if f_duration > 0 then
- begin
- if f_duration > DENSITY_MATRIX_SIZE - 1 then
- Inc(FData.DurationDensity[DENSITY_MATRIX_SIZE])
- else
- Inc(FData.DurationDensity[f_duration]);
- end;
- f_datetime := FQuery.FieldByName('start_time').AsDateTime;
- if f_datetime > FStartDate then
- begin
- days_between := DaysBetween(FStartDate, f_datetime);
- if days_between < DENSITY_MATRIX_SIZE then
- Inc(FData.TimeDensity[days_between]);
- end;
- result := TRUE;
- end;
- end;
- procedure TReplayAnalyzer.Execute;
- begin
- FQuery := TUniQuery.Create(nil);
- FQuery.Connection := FConnection;
- FQuery.UniDirectional := TRUE;
- FQuery.FetchRows := 1000;
- FQuery.SQL.Text := 'SELECT m.match_id, m.duration, m.first_blood_time, m.good_guys_win, m.human_players, m.start_time FROM Matches AS m LEFT JOIN Players AS p ON m.match_id = p.match_id';
- FQuery.SpecificOptions.Clear;
- FQuery.SpecificOptions.Add('SQL Server.FetchAll=False');
- FQuery.AfterExecute := QueryAfterExecute;
- FQuery.ExecSQL;
- while not Terminated do
- Sleep(1);
- FQuery.Free;
- Synchronize(syncAnalyzeDone);
- end;
- procedure TReplayAnalyzer.QueryAfterExecute(Sender: TObject; Result: Boolean);
- var
- currpos: DWORD;
- begin
- if Result then
- begin
- FData.TotalMatches := FRowTo - FRowFrom + 1;
- currpos := 0;
- FQuery.Open;
- FQuery.First;
- while not FQuery.Eof do
- begin
- if Terminated then
- Break;
- if Analyze then
- Inc(currpos);
- if Round(((currpos + 1) / FData.TotalMatches) * 100) <> FReplayProgress then
- begin
- FReplayProgress := Round(((currpos + 1) / FData.TotalMatches) * 100);
- Synchronize(syncReplayProgress);
- end;
- FQuery.Next;
- end;
- FQuery.Close;
- end;
- if not Terminated then
- Terminate;
- end;
- procedure TReplayAnalyzer.syncReplayProgress;
- begin
- if Assigned(FOnReplayProgress) then
- FOnReplayProgress(self, FReplayProgress);
- end;
- procedure TReplayAnalyzer.syncAnalyzeDone;
- begin
- if Assigned(FOnAnalyzeDone) then
- FOnAnalyzeDone(self);
- end;
- end.
Add Comment
Please, Sign In to add comment