Skip to content

Commit

Permalink
Introduce class hierarchy to support common Contest behaviors (#125)
Browse files Browse the repository at this point in the history
Implements a common class hierarchy to support contests.
contest-specific behaviors will be implemented in the various derived
contests. See Issue #124 for a UML Class Diagram showing this hierarchy.
This refactoring introduces the base TContest class along with 5 derived
subclasses.
  • Loading branch information
w7sst authored Nov 15, 2022
2 parents a8dd3d4 + df8a98d commit d12954b
Show file tree
Hide file tree
Showing 18 changed files with 501 additions and 181 deletions.
64 changes: 42 additions & 22 deletions ArrlFd.pas
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
interface

uses
Generics.Defaults, Generics.Collections, ARRL,
SysUtils, Classes, {Contnrs,} PerlRegEx, pcre;
Generics.Defaults, Generics.Collections, Contest, DxStn;

type
TFdCallRec = class
Expand All @@ -21,56 +20,57 @@ TFdCallRec = class
class function compareCall(const left, right: TFdCallRec) : integer; static;
end;

TArrlFieldDay = class
TArrlFieldDay = class(TContest)
private
FdCallList: TObjectList<TFdCallRec>;
Comparer: IComparer<TFdCallRec>;

procedure LoadFdHistoryFile;

public
constructor Create;
destructor Destroy; override;
function pickStation(): integer;
//function getcwopsid(): integer;
//function getcwopscall(id:integer): string;
//function getcwopsname(id:integer): string;
//function getcwopsnum(id:integer): integer;
function getCall(id:integer): string; // returns station callsign
function LoadCallHistory(const AUserCallsign : string) : boolean; override;

function PickStation(): integer; override;
procedure DropStation(id : integer); override;
function GetCall(id : integer): string; override; // returns station callsign
procedure GetExchange(id : integer; out station : TDxStation); override;

function getExch1(id:integer): string; // returns station info (e.g. 3A)
function getExch2(id:integer): string; // returns section info (e.g. OR)
function getClass(id:integer): string; // returns station class (e.g. 3A)
function getSection(id:integer): string; // returns section (e.g. OR)
function getUserText(id:integer): string; // returns optional club name
//function IsNum(Num: String): Boolean;
function FindCallRec(out fdrec: TFdCallRec; const ACall: string): Boolean;
function GetStationInfo(const ACallsign: string) : string;
function GetStationInfo(const ACallsign: string) : string; override;
end;

var
gARRLFD: TArrlFieldDay;


implementation

uses
log;
SysUtils, Classes, Log, PerlRegEx, pcre, ARRL;

procedure TArrlFieldDay.LoadFdHistoryFile;
function TArrlFieldDay.LoadCallHistory(const AUserCallsign : string) : boolean;
const
DelimitChar: char = ',';
var
slst, tl: TStringList;
i: integer;
rec: TFdCallRec;
begin
// reload call history iff user's callsign has changed.
Result := not HasUserCallsignChanged(AUserCallsign);
if Result then
Exit;

slst:= TStringList.Create;
tl:= TStringList.Create;
tl.Delimiter := DelimitChar;
tl.StrictDelimiter := True;

try
FdCallList:= TObjectList<TFdCallRec>.Create;
FdCallList.Clear;

slst.LoadFromFile(ParamStr(1) + 'FD_2022-004.TXT');

Expand All @@ -96,6 +96,10 @@ procedure TArrlFieldDay.LoadFdHistoryFile;
end;
end;

// retain user's callsign after successful load
SetUserCallsign(AUserCallsign);
Result := True;

finally
slst.Free;
tl.Free;
Expand All @@ -106,8 +110,8 @@ procedure TArrlFieldDay.LoadFdHistoryFile;
constructor TArrlFieldDay.Create;
begin
inherited Create;
FdCallList:= TObjectList<TFdCallRec>.Create;
Comparer := TComparer<TFdCallRec>.Construct(TFdCallRec.compareCall);
LoadFdHistoryFile;
end;


Expand All @@ -118,12 +122,19 @@ destructor TArrlFieldDay.Destroy;
end;


function TArrlFieldDay.pickStation(): integer;
function TArrlFieldDay.PickStation(): integer;
begin
result := random(FdCallList.Count);
end;


procedure TArrlFieldDay.DropStation(id : integer);
begin
assert(id < FdCallList.Count);
FdCallList.Delete(id);
end;


function TArrlFieldDay.FindCallRec(out fdrec: TFdCallRec; const ACall: string): Boolean;
var
rec: TFdCallRec;
Expand Down Expand Up @@ -163,7 +174,7 @@ function TArrlFieldDay.GetStationInfo(const ACallsign: string) : string;
dxEntity := '';
result:= '';

if gArrlFd.FindCallRec(fdrec, ACallsign) then
if FindCallRec(fdrec, ACallsign) then
begin
userText:= fdrec.UserText;

Expand All @@ -184,12 +195,21 @@ function TArrlFieldDay.GetStationInfo(const ACallsign: string) : string;
end;


function TArrlFieldDay.getCall(id:integer): string; // returns station callsign
// returns station callsign
function TArrlFieldDay.GetCall(id : integer): string;
begin
result := FdCallList.Items[id].Call;
end;


procedure TArrlFieldDay.GetExchange(id : integer; out station : TDxStation);
begin
station.Exch1 := getExch1(id);
station.Exch2 := getExch2(id);
station.UserText := getUserText(id);
end;


function TArrlFieldDay.getExch1(id:integer): string; // returns station info (e.g. 3A)
begin
result := FdCallList.Items[id].StnClass;
Expand Down
65 changes: 50 additions & 15 deletions CWOPS.pas
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
interface

uses
SysUtils, Classes, Contnrs, PerlRegEx, pcre;
Classes, Contest, Contnrs, DxStn;

type
TCWOPSRec= class
Expand All @@ -13,40 +13,50 @@ TCWOPSRec= class
Number: string;
end;

TCWOPS= class
TCWOPS= class(TContest)
private
CWOPSList: TList;
procedure LoadCWOPS;
procedure Delimit(var AStringList: TStringList; const AText: string);

public
constructor Create;
function getcwopsid(): integer;
function getcwopscall(id:integer): string;
destructor Destroy; override;
function LoadCallHistory(const AUserCallsign : string) : boolean; override;

function PickStation(): integer; override;
procedure DropStation(id : integer); override;
function GetCall(id : integer): string; override;
procedure GetExchange(id : integer; out station : TDxStation); override;

function getcwopsname(id:integer): string;
function getcwopsnum(id:integer): integer;
function IsNum(Num: String): Boolean;
end;

var
CWOPSCWT: TCWOPS;
function IsNum(Num: String): Boolean;


implementation

uses
log;
SysUtils, Log;

procedure TCWOPS.LoadCWOPS;
function TCWOPS.LoadCallHistory(const AUserCallsign : string) : boolean;
var
slst, tl: TStringList;
i: integer;
CWO: TCWOPSRec;
begin
// reload call history iff user's callsign has changed.
Result := not HasUserCallsignChanged(AUserCallsign);
if Result then
Exit;

slst:= TStringList.Create;
tl:= TStringList.Create;

try
CWOPSList:= TList.Create;
CWOPSList.Clear;

slst.LoadFromFile(ParamStr(1) + 'CWOPS.LIST');
slst.Sort;

Expand All @@ -70,6 +80,10 @@ procedure TCWOPS.LoadCWOPS;
end;
end;

// retain user's callsign after successful load
SetUserCallsign(AUserCallsign);
Result := True;

finally
slst.Free;
tl.Free;
Expand All @@ -81,21 +95,42 @@ procedure TCWOPS.LoadCWOPS;
constructor TCWOPS.Create;
begin
inherited Create;
LoadCWOPS;
CWOPSList:= TList.Create;
end;

function TCWOPS.getcwopsid(): integer;
destructor TCWOPS.Destroy;
begin
FreeAndNil(CWOPSList);
inherited;
end;


function TCWOPS.PickStation(): integer;
begin
result := random(CWOPSList.Count);
end;


function TCWOPS.getcwopscall(id:integer): string;
procedure TCWOPS.DropStation(id : integer);
begin
assert(id < CWOPSList.Count);
CWOPSList.Delete(id);
end;


function TCWOPS.GetCall(id : integer): string;
begin
result := TCWOPSRec(CWOPSList.Items[id]).Call;
end;


procedure TCWOPS.GetExchange(id : integer; out station : TDxStation);
begin
station.OpName := getcwopsname(id);
station.NR := getcwopsnum(id);
end;


function TCWOPS.getcwopsname(id:integer): string;

begin
Expand All @@ -108,7 +143,7 @@ function TCWOPS.getcwopsnum(id:integer): integer;
result := strtoint(TCWOPSRec(CWOPSList.Items[id]).Number);
end;

function TCWOPS.IsNum(Num: String): Boolean;
function IsNum(Num: String): Boolean;
var
X : Integer;
begin
Expand Down
46 changes: 36 additions & 10 deletions CallLst.pas
Original file line number Diff line number Diff line change
Expand Up @@ -8,22 +8,35 @@
interface

uses
SysUtils, Classes, Ini;

procedure LoadCallList;
function PickCall: string;
Classes;

type
// simple calllist. contains a TStringList of callsigns.
TCallList = class
protected
Calls: TStringList;

public
constructor Create;
destructor Destroy; override;
procedure LoadCallList;
procedure Clear();
function PickCall : string;
end;

var
Calls: TStringList;

implementation

uses
SysUtils, Ini;

function CompareCalls(Item1, Item2: Pointer): Integer;
begin
Result := StrComp(PChar(Item1), PChar(Item2));
end;

procedure LoadCallList;
// reads callsigns from Master.dta file
procedure TCallList.LoadCallList;
const
Chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789/';
CHRCOUNT = Length(Chars);
Expand Down Expand Up @@ -89,7 +102,14 @@ procedure LoadCallList;
end;


function PickCall: string;
procedure TCallList.Clear();
begin
Calls.Clear;
end;


// returns a single callsign
function TCallList.PickCall : string;
var
Idx: integer;
begin
Expand All @@ -106,11 +126,17 @@ function PickCall: string;
end;


initialization
constructor TCallList.Create;
begin
Calls := TStringList.Create;
end;

finalization
destructor TCallList.Destroy;
begin
Calls.Clear;
Calls.Free;
end;


end.

Loading

0 comments on commit d12954b

Please sign in to comment.