-
Notifications
You must be signed in to change notification settings - Fork 48
/
BaseConflict.Api.Shared.pas
231 lines (195 loc) · 6.31 KB
/
BaseConflict.Api.Shared.pas
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
unit BaseConflict.Api.Shared;
interface
/// ////////////////////////////////////////////////////////////////////////////
/// ///////////////////// ABOUT ////////////////////////////////////////////////
/// ////////////////////////////////////////////////////////////////////////////
/// This unit contains all types or methods that are used by other api units.
/// The main target is to avoid crossreferences, so it is totaly forbidden to
/// add any .api unit (except types and first level .api) to the uses clausel.
/// ////////////////////////////////////////////////////////////////////////////
uses
// System
System.SysUtils,
// Engine
Engine.Helferlein,
Engine.DataQuery,
Engine.Helferlein.DataStructures,
Engine.Helferlein.Threads,
Engine.Helferlein.Windows,
Engine.Network.RPC,
// Game
BaseConflict.Constants.Cards,
BaseConflict.Constants.Client,
BaseConflict.Api,
BaseConflict.Api.Types;
type
{$RTTI EXPLICIT METHODS([vcPublished, vcPublic, vcPrivate]) FIELDS([vcPublic, vcProtected]) PROPERTIES([vcPublic, vcPublished])}
/// <summary> Describes an unique currency like gold or a premium currency like broken points.</summary>
TCurrency = class
private
FUID : string;
FServerName : string;
function GetName : string;
public
property UID : string read FUID;
property name : string read GetName;
property ServerName : string read FServerName;
function Icon : string;
constructor Create(Data : RCurrency);
end;
TCurrencyManager = class
private
FCurrencies : TUltimateObjectList<TCurrency>;
procedure LoadCurrencies(const Data : ARCurrency);
public
property Currencies : TUltimateObjectList<TCurrency> read FCurrencies;
/// <summary> Returns a currency by his uid. Will raise exception if currency not found.
/// CAUTION! Never free the currency returned. The reference is managed by manager and used in whole
/// app, so freeing them will cause access violations.</summary>
function GetCurrencyByUID(CurrencyUID : string) : TCurrency;
function TryGetCurrencyByUID(const CurrencyUID : string; out Currency : TCurrency) : boolean;
constructor Create();
destructor Destroy; override;
end;
/// <summary> Describes on cost for an itemoffer.</summary>
RCost = record
Amount : integer;
Currency : TCurrency;
constructor Create(Amount : integer; Currency : TCurrency);
end;
[AQCriticalAction]
TCurrencyManagerLoadCurrencies = class(TPromiseAction)
private
FCurrencyManager : TCurrencyManager;
public
property CurrencyManager : TCurrencyManager read FCurrencyManager;
constructor Create(CurrencyManager : TCurrencyManager);
function Execute : boolean; override;
procedure Rollback; override;
end;
TVersionedItem = class(TInterfacedObject)
private
FClientVersion, FServerVersion : integer;
public
/// <summary> Should be called if backchannel notify change. </summary>
procedure IncFromServer;
/// <summary> Should be called if client emulate change. </summary>
procedure IncFromClient;
/// <summary> Should be called if client rollback change. </summary>
procedure DecFromClient;
/// <summary> Returns whether there are pending changes on the server. </summary>
function IsClientAhead : boolean;
/// <summary> Returns whether there are pending changes on the client. </summary>
function IsServerAhead : boolean;
end;
{$RTTI EXPLICIT METHODS([vcPublic, vcPublished]) PROPERTIES([vcPublic, vcPublished]) FIELDS([vcPrivate, vcProtected, vcPublic])}
var
CurrencyManager : TCurrencyManager;
implementation
{ RCost }
constructor RCost.Create(Amount : integer; Currency : TCurrency);
begin
self.Amount := Amount;
self.Currency := Currency;
end;
{ TCurrency }
constructor TCurrency.Create(Data : RCurrency);
begin
FUID := Data.UID;
FServerName := Data.name;
end;
function TCurrency.GetName : string;
begin
Result := _('§shop_currency_name_' + FUID);
end;
function TCurrency.Icon : string;
begin
Result := HClient.CurrencyIcon(FUID);
end;
{ TCurrencyManagerLoadCurrencies }
constructor TCurrencyManagerLoadCurrencies.Create(CurrencyManager : TCurrencyManager);
begin
inherited Create();
FCurrencyManager := CurrencyManager;
end;
function TCurrencyManagerLoadCurrencies.Execute : boolean;
var
promise : TPromise<ARCurrency>;
begin
promise := ShopApi.GetCurrencies;
promise.WaitForData;
if promise.WasSuccessful then
begin
DoSynchronized(
procedure()
begin
CurrencyManager.LoadCurrencies(promise.Value);
end);
end
else
HandlePromiseError(promise);
Result := promise.WasSuccessful;
promise.Free;
end;
procedure TCurrencyManagerLoadCurrencies.Rollback;
begin
CurrencyManager.Currencies.Clear;
end;
{ TCurrencyManager }
constructor TCurrencyManager.Create;
begin
FCurrencies := TUltimateObjectList<TCurrency>.Create();
MainActionQueue.DoAction(TCurrencyManagerLoadCurrencies.Create(self));
end;
destructor TCurrencyManager.Destroy;
begin
FCurrencies.Free;
inherited;
end;
function TCurrencyManager.GetCurrencyByUID(CurrencyUID : string) : TCurrency;
begin
if not TryGetCurrencyByUID(CurrencyUID, Result) then
raise ENotFoundException.Create('TCurrencyManager.GetCurrencyByUID: Could not found currency with uid ' + CurrencyUID + '!');
end;
procedure TCurrencyManager.LoadCurrencies(const Data : ARCurrency);
var
currency_data : RCurrency;
begin
for currency_data in Data do
FCurrencies.Add(TCurrency.Create(currency_data));
end;
function TCurrencyManager.TryGetCurrencyByUID(const CurrencyUID : string; out Currency : TCurrency) : boolean;
var
CurrencyTemp : TCurrency;
begin
CurrencyTemp := Currencies.Query.Get(F('UID') = CurrencyUID, True);
if assigned(CurrencyTemp) then
begin
Result := True;
Currency := CurrencyTemp;
end
else
Result := False;
end;
{ TVersionedItem }
procedure TVersionedItem.DecFromClient;
begin
dec(FClientVersion);
end;
procedure TVersionedItem.IncFromClient;
begin
inc(FClientVersion);
end;
procedure TVersionedItem.IncFromServer;
begin
inc(FServerVersion);
end;
function TVersionedItem.IsClientAhead : boolean;
begin
Result := FClientVersion > FServerVersion;
end;
function TVersionedItem.IsServerAhead : boolean;
begin
Result := FClientVersion < FServerVersion;
end;
end.