kursovik.pas 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496
  1. unit Kursovik;
  2. INTERFACE
  3. type
  4. PSource = ^CSource;
  5. PDevice = ^CDevice;
  6. PBuffer = ^CBuffer;
  7. {-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-}
  8. TReq = record
  9. Birth : real;
  10. Death : real;
  11. FromSource : PSource;
  12. ToDevice : PDevice;
  13. end;
  14. {-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-}
  15. {$R-}
  16. TReqArray = array [0..1000] of TReq;
  17. PReqArray = ^TReqArray;
  18. TSourceArr = array [0..1000] of PSource;
  19. PSourceArr = ^TSourceArr;
  20. PReq = ^TReq;
  21. {-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-}
  22. ESOURCES = (SOURCE_DUMMY,SOURCE_EASIEST,SOURCE_ERLANG); {’¨¯ë ¨áâ®ç­¨ª®¢}
  23. CSource = object
  24. SType : ESOURCES; {Š ª®¢ ­ è ¨áâ®ç­¨ª? }
  25. Name : integer; {€ ª ª ¥£® §®¢ãâ ?}
  26. LastTime : real; {‚à¥¬ï £¥­¥à æ¨¨ ¯®á«¥¤­¥£® § ¯à®á }
  27. LastReq : TReq; {�®á«¥¤­¨© ᣥ­¥à¨à®¢ ­­ë© § ¯à®á}
  28. NewTime : real; {Œ®¬¥­â £¥­¥à æ¨¨ ­®¢®£® § ¯à®á }
  29. Lambda : real;
  30. TotalReq : longInt; {ޡ饥 ç¨á«® § ï¢®ª ®â ¨áâ®ç­¨ª }
  31. DoneReq : longInt; {ç¨á«® ®¡à ¡®â ­­ëå § ï¢®ª ®â ¨áâ®ç­¨ª }
  32. RefusedReq:LongInt; {—¨á«® ®âª«®­¥­­ëå § ï¢®ª}
  33. WaitTime : real; {ޡ饥 ¢à¥¬ï ¯à¥¡ë¢ ­¨ï ¢ á¨á⥬¥}
  34. ProbRefuse:real; {‚¥à®ïâ­®áâì ®âª § }
  35. MatWait : real; {Œ â¥¬ â¨ç¥áª®¥ ®¦¨¤ ­¨¥ ¢ ¡ãä¥à¥}
  36. Constructor Init(aName : Integer;aLambda:real); {Š®­áâàãªâ®à á ¨¬¥­¥¬}
  37. Procedure Reset; {‘¡à®á ¢á¥å áç¥â稪®¢}
  38. Procedure GenNewReq; {ƒ¥­¥à æ¨ï ­®¢®£® § ¯à®á }
  39. Destructor Done;virtual;
  40. end;{CSource}
  41. {-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-}
  42. CDevice = object {Ž¡ê¥ªâ - ¯à®á⥩襥 ãá⮩á⢮ ¬ áᮢ®£® ®¡á«ã¦¨¢ ­¨ï}
  43. LastTime : real; {‚à¥¬ï ¯®á«¥¤­¥£® § ¢¥à襭¨ï ®¡á«ã¦¨¢ ­¨ï}
  44. BegTime : real; {‚à¥¬ï ­ ç «  ®¡á«ã¦¨¢ ­¨ï}
  45. DoneTime : real; {‚६ï, ¢ ª®â®à®¥ § ª®­ç¨âáï ®¡à ¡®âª }
  46. Stoppage : real; {ޡ饥 ¢à¥¬ï ¯à®áâ®ï ¯à¨¡®à }
  47. IsWorking : boolean; {Žáãé¥á⢫ï¥âáï «¨ ®¡á«ã¦¨¢ ­¨¥ ?}
  48. CurWorking : TReq; {’¥ªã騩 ®¡à ¡ â뢠¥¬ë© § ¯à®á}
  49. Lambda : real;
  50. Constructor Init(aLambda:real); {}
  51. Function AddReq(aCurReq : PReq;aCurTime:real):boolean; {� ç «® ®¡à ¡®âª  § ¯à®á }
  52. Procedure Reset; {‘¡à®á ãáâà-¢ }
  53. Function DoneWork:PReq; {‡ ¢¥à襭¨¥ ®¡à ¡®âª¨ ⥪ã饣® § ¯à®á , á ¥£® ¢®§¢à â®¬}
  54. Destructor Done;
  55. end; {CDevice}
  56. {-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-}
  57. EBuffers = (BUFFER_DUMMY, BUFFER_FIFO, BUFFER_LIFO, BUFFER_PRIOR);
  58. CBuffer = object {�ãää¥à § ¯à®á®¢}
  59. BufType : EBuffers; {’¨¯ ¡ãä¥à }
  60. BufferLength : integer; {„«¨­  ¡ãä¥à }
  61. CellCount : integer; {ˆ­¤¥ªá ⥪ã饩 ᢮¡®¤­®© ï祩ª¨}
  62. Data : PReqArray; {‘®¡á⢥­­® á ¬ ¡ãä¥à}
  63. Constructor Init(aBufLen:integer); {ˆ­¨æ¨ «¨§ æ¨ï ¡ãä¥à }
  64. Destructor Done;virtual;{„¥áâàãªâ®à, ®­ ¨ ¥áâì}
  65. Function SetBufferSize(aNewSize:integer):boolean;{ˆ§¬¥­¥­¨¥ à §¬¥à  ¡ãä¥à }
  66. Procedure FreeBuffer; {Žá¢®¡®¦¤¥­¨¥ ¢á¥£® ¡ãä¥à  áà §ã}
  67. Function AddReq(var aNew, rKicked:TReq):boolean; {„®¡ ¢«ï¥âáï § ¯à®á ¢ ¡ãä¥à.
  68. …᫨ ¨§ ¡ãä¥à  ª ª®©-â® § ¯à®á 㤠«¥­, â® ä-æ¨ï ¢®§¢à. false, ¨ ¢ rKicked -
  69. § ¯à®á, ª®â®àë© ®âª«®­¥­}
  70. Function GetReq(var rReq:TReq):boolean;virtual; {‚ëâ é¨âì ¨§ ¡ãä¥à  § ¯à®á,
  71. ¥á«¨ ãᯥ譮 - true}
  72. end; {CBuffer}
  73. {-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-}
  74. CModel = object {� è  ¬®¤¥«ì ‘ŒŽ}
  75. Sources : PSourceArr; {ˆáâ®ç­¨ª¨}
  76. SourceCnt: integer; {—¨á«® ¨áâ®ç­¨ª®¢}
  77. MaxSrc : integer; {� §¬¥à­®áâì ¬ áᨢ  ¨áâ®ç­¨ª®¢}
  78. Buffer : PBuffer; {�ãä¥à}
  79. Device : PDevice; {“áâனá⢮}
  80. CurTime : real; {’¥ªã騩 ¬®¬¥­â ¢à¥¬¥­¨}
  81. Delta : real;
  82. DovInt : real;
  83. NextSource:integer; {Š ª®© ¨§ ¨áâ®ç­¨ª®¢ - ¡ëáâ॥}
  84. RealizSteps:LongInt; {�¥®¡å. ç¨á«® ॠ«¨§ æ¨©}
  85. CurStep : LongInt; {’¥ªã騩 è £}
  86. {}
  87. DoneCount, {—¨á«® ®¡à ¡®â ­­ëå § ï¢®ª}
  88. RefusedCount, {—¨á«® ®âª«®­¥­­ëå § ï¢®ª}
  89. TotalCount : integer; {ޡ饥 ç¨á«® § ï¢®ª}
  90. Working : boolean; {� ¡®â ¥â «¨ ¬®¤¥«ì ?}
  91. WorkReq : TReq;
  92. Constructor Init(aBegSrcCnt:integer;aDev:PDevice;aBuf:PBuffer;
  93. aDel,aDov:Real);
  94. Function SetSourceCount(aNewCnt:integer):boolean; {“áâ ­®¢ª  ­®¢®£® ç¨á« 
  95. ¨áâ®ç­¨ª®¢, á á®åà ­¥­¨¥¬ áâ àëå}
  96. Function AddNewSource(aNewSrc:PSource):boolean; {„®¡ ¢«¥­¨¥ ­®¢®£® ¨áâ®ç­¨ª }
  97. Procedure SetNextSource; {� å®¤¨â NextSource}
  98. Function TestVer:boolean; {}
  99. Function RemoveSource(aName:integer):boolean; {“¤ «¥­¨¥ ¨áâ®ç­¨ª  ¨§ ¬®¤¥«¨}
  100. Procedure Reset; {‘¡à®á ¢á¥å áç¥â稪®¢}
  101. Procedure Start;
  102. Procedure PrintValues;
  103. Function Step:boolean; {Œ®¤¥«¨àã¥â á«¥¤ãî騩 è £, ¥á«¨ ¢ }
  104. Destructor Done;
  105. end;
  106. {-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-}
  107. IMPLEMENTATION
  108. Constructor CSource.Init(aName : Integer;aLambda:real);
  109. Begin
  110. Name := aName;
  111. SType := SOURCE_EASIEST;
  112. Lambda := aLambda;
  113. Reset;
  114. end;{CSource.Init}
  115. {-------------------------------------------------------------------------}
  116. Procedure CSource.Reset;
  117. Begin
  118. LastTime :=0; NewTime:=0;
  119. TotalReq :=0;
  120. DoneReq :=0;
  121. RefusedReq:=0;
  122. WaitTime :=0;
  123. ProbRefuse:=0;
  124. MatWait :=0;
  125. end;{CSource.Reset}
  126. {-------------------------------------------------------------------------}
  127. Procedure CSource.GenNewReq;
  128. Begin
  129. LastTime := NewTime;
  130. NewTime := LastTime - Ln(Random)/Lambda;
  131. Inc(TotalReq);
  132. LastReq.Birth := NewTime;
  133. LastReq.Death := -1.0;
  134. LastReq.FromSource := @Self;
  135. end;{CSource.GenNewReq}
  136. {-------------------------------------------------------------------------}
  137. Destructor CSource.Done;
  138. begin
  139. end;
  140. {-------------------------------------------------------------------------}
  141. { CDevice }
  142. Constructor CDevice.Init(aLambda:real);
  143. begin
  144. Lambda := aLambda;
  145. Reset;
  146. end;{CDevice.Init}
  147. {=========================================}
  148. Procedure CDevice.Reset;
  149. begin
  150. LastTime := 0;
  151. DoneTime := 0;
  152. Stoppage := 0;
  153. IsWorking := false;
  154. end;{CDevice.Reset}
  155. {---------------------------}
  156. Function CDevice.AddReq(aCurReq : PReq;aCurTime:real):boolean; {� ç «® ®¡à ¡®âª  § ¯à®á }
  157. begin
  158. AddReq := false;
  159. if not isWorking then
  160. begin
  161. BegTime := aCurTime;
  162. Stoppage := Stoppage + (BegTime-LastTime);
  163. DoneTime := BegTime - (Ln(Random) + Random)/Lambda;
  164. IsWorking := true;
  165. CurWorking := aCurReq^;
  166. CurWorking.ToDevice := @Self;
  167. AddReq := true;
  168. end;
  169. end;{CDevice.AddReq}
  170. {=========================================}
  171. Function CDevice.DoneWork:PReq;
  172. begin
  173. DoneWork := nil;
  174. if isWorking then
  175. begin
  176. LastTime := DoneTime;
  177. CurWorking.Death := DoneTime;
  178. DoneWork := @CurWorking;
  179. isWorking := false;
  180. end;
  181. end;{CDevice.DoneWork}
  182. {=========================================}
  183. Destructor CDevice.Done;
  184. begin
  185. end;{CDevice.Done}
  186. {=========================================}
  187. { CBuffer }
  188. Constructor CBuffer.Init(aBufLen:integer);
  189. begin
  190. BufType := BUFFER_PRIOR;
  191. BufferLength := aBufLen;
  192. CellCount := 0;
  193. GetMem(Data,Sizeof(TReq)*BufferLength);
  194. FillChar(Data^,Sizeof(TReq)*BufferLength,0);
  195. end;{CBuffer.Init}
  196. {-----------------------}
  197. Destructor CBuffer.Done;
  198. begin
  199. FreeMem(Data,Sizeof(TReq)*BufferLength); {Dispose(data)}
  200. BufferLength:=0;
  201. end;{CBuffer.Done}
  202. {-----------------------}
  203. Function CBuffer.SetBufferSize(aNewSize:integer):boolean;
  204. var
  205. NewBuf : PReqArray;
  206. begin
  207. SetBufferSize := false;
  208. if aNewSize > BufferLength then
  209. begin
  210. GetMem(NewBuf,Sizeof(TReq)*aNewSize);
  211. FillChar(NewBuf^,Sizeof(TReq)*aNewSize,0);
  212. Move(Data^,NewBuf^,Sizeof(TReq)*BufferLength);
  213. FreeMem(Data,Sizeof(TReq)*BufferLength);
  214. Data := NewBuf;
  215. BufferLength := aNewSize;
  216. SetBufferSize := true;
  217. end;
  218. end;{CBuffer.SetBufferSize}
  219. {-----------------------}
  220. Function CBuffer.AddReq(var aNew, rKicked:TReq):boolean;
  221. begin
  222. if CellCount=BufferLength then {�  á ¬®¬ ¤¥«¥, â.ª á 0, â® ¡®«ìè¥}
  223. begin
  224. AddReq := false;
  225. rKicked := aNew;
  226. rKicked.Death := aNew.Birth; {‡ ¯à®á ®âª«®­¥­, ¢ ¬®¬¥­â, ª®£¤  ­®¢ë© ¯à¨¡ë«,
  227. â.¥. ª®£¤  â®â ¡ë« á®§¤ ­}
  228. end
  229. else
  230. begin
  231. AddReq := true;
  232. Data^[CellCount] := aNew;
  233. Inc(CellCount);
  234. end;
  235. end;{CBuffer.AddReq}
  236. {-----------------------}
  237. Function CBuffer.GetReq(var rReq:TReq):boolean;
  238. var
  239. i,n : byte;
  240. begin
  241. GetReq := false;
  242. if CellCount = 0 then Exit;
  243. n := 0;
  244. for i := 0 to CellCount-1 do if Data^[i].FromSource^.Name = 1 then
  245. begin
  246. n := i;
  247. break;
  248. end;
  249. rReq := Data^[n];
  250. Move(Data^[n+1],Data^[n],sizeof(TReq) * (CellCount-n-1));
  251. Dec(CellCount);
  252. GetReq := true;
  253. end;{CBuffer.GetReq}
  254. {---------------------------------------------}
  255. Procedure CBuffer.FreeBuffer;
  256. begin
  257. CellCount := 0;
  258. end;
  259. {-=-==-=-=-=-=-=-=-=-=-=-=-=-=-=-=-}
  260. Constructor CModel.Init(aBegSrcCnt:integer;aDev:PDevice;aBuf:PBuffer;
  261. aDel,aDov:Real);
  262. Begin
  263. MaxSrc := aBegSrcCnt;
  264. GetMem(Sources,Sizeof(PSource)*MaxSrc);
  265. SourceCnt := 0;
  266. RealizSteps := 100;
  267. Buffer := aBuf;
  268. Device := aDev;
  269. Delta := aDel;
  270. DovInt := aDov;
  271. Reset;
  272. end;{CModel.Init}
  273. {---------------------------------------------------------}
  274. Procedure CModel.Reset;
  275. begin
  276. NextSource:=0;
  277. CurTime := 0;
  278. CurStep := 0;
  279. DoneCount := 0;
  280. RefusedCount := 0;
  281. RealizSteps := 100;
  282. TotalCount := 0;
  283. Working := false;
  284. end;{CModel.Reset}
  285. {------------------------------------------------------------------}
  286. Function CModel.SetSourceCount(aNewCnt:integer):boolean;
  287. var
  288. NewBuf : PSourceArr;
  289. Begin
  290. SetSourceCount := false;
  291. if aNewCnt > MaxSrc then
  292. begin
  293. GetMem(NewBuf,Sizeof(PSource)*aNewCnt);
  294. Move(Sources^,NewBuf^,Sizeof(PSource)*MaxSrc);
  295. FreeMem(Sources,Sizeof(PSource)*MaxSrc);
  296. Sources := NewBuf;
  297. MaxSrc := aNewCnt;
  298. SetSourceCount := true;
  299. end;
  300. end;{CModel.SetSourceCount}
  301. {------------------------------------------------------------------}
  302. Function CModel.AddNewSource(aNewSrc:PSource):boolean;
  303. Begin
  304. if SourceCnt >= MaxSrc then AddNewSource := SetSourceCount(MaxSrc+1);
  305. Sources^[SourceCnt] := aNewSrc;
  306. Inc(SourceCnt);
  307. end;{CModel.AddNewSource}
  308. {------------------------------------------------------------------}
  309. Function CModel.RemoveSource(aName:integer):boolean;
  310. var
  311. c : integer;
  312. Begin
  313. RemoveSource := false;
  314. if SourceCnt = 1 then exit;
  315. for c := 0 to SourceCnt-1 do if Sources^[c]^.Name = aName then break;
  316. if c = SourceCnt-1 then exit;
  317. Dispose(Sources^[c],Done);
  318. while c <> SourceCnt-1 do
  319. begin
  320. Sources^[c] := Sources^[c+1];
  321. inc(c);
  322. end;
  323. Dec(SourceCnt);
  324. end;{CModel.RemoveSource}
  325. {------------------------------------------------------------------}
  326. Procedure CModel.SetNextSource; {� å®¤¨â NextSource}
  327. var
  328. c : integer;
  329. begin
  330. NextSource := 0;
  331. for c := 0 to SourceCnt-1 do
  332. begin
  333. if (Sources^[c]^.NewTime < Sources^[NextSource]^.NewTime) then
  334. NextSource := c;
  335. end;
  336. end;{CModel.SetNextSource}
  337. {------------------------------------------------------------------}
  338. Procedure CModel.Start;
  339. var
  340. c,First : integer;
  341. begin
  342. if (Device=nil) or (Buffer=nil) or (SourceCnt=0) then exit;
  343. Reset;
  344. Device^.Reset;
  345. Buffer^.FreeBuffer;
  346. First := 0;
  347. for c := 0 to SourceCnt-1 do
  348. begin
  349. Sources^[c]^.Reset;
  350. Sources^[c]^.GenNewReq;
  351. if (Sources^[c]^.NewTime < Sources^[First]^.NewTime) then
  352. First := c;
  353. end;
  354. WorkReq := Sources^[First]^.LastReq;
  355. Device^.AddReq(@WorkReq,Sources^[First]^.NewTime);
  356. Sources^[First]^.GenNewReq;
  357. SetNextSource;
  358. Working := true;
  359. end;
  360. {------------------------------------------------------------------}
  361. Function CModel.TestVer:boolean;
  362. var
  363. NewV,c,p:real;
  364. i : integer;
  365. begin
  366. NewV:=0;
  367. TestVer:=true;
  368. for i := 0 to SourceCnt-1 do if Sources^[i]^.RefusedReq <> 0 then
  369. begin
  370. p := 1.0 * Sources^[i]^.RefusedReq / Sources^[i]^.TotalReq;
  371. c := (DovInt*(1-p))/(Delta*Delta*p);
  372. if c > NewV then NewV := c;
  373. end;
  374. if NewV > RealizSteps then
  375. begin
  376. RealizSteps := round(NewV);
  377. TestVer := false;
  378. end;
  379. end;{CModel.TextVer}
  380. {------------------------------------------------------------------}
  381. Function CModel.Step:boolean;
  382. var
  383. Kicked : TReq;
  384. i : integer;
  385. ret : boolean;
  386. Begin
  387. Step := false;
  388. if Not Working then exit;
  389. ret := false; {‘ç¨â ¥¬, çâ® ¯à®¤®«¦ âì ­¥ ¡ã¤¥¬}
  390. for i:=0 to SourceCnt-1 do if Sources^[i]^.TotalReq < RealizSteps then
  391. ret:=true;
  392. if not ret then ret := not TestVer;
  393. if Device^.DoneTime < Sources^[NextSource]^.NewTime then
  394. begin
  395. CurTime := Device^.DoneTime;
  396. WorkReq := Device^.DoneWork^;
  397. inc(DoneCount);
  398. inc(TotalCount);
  399. inc(WorkReq.FromSource^.DoneReq);
  400. WorkReq.FromSource^.WaitTime := WorkReq.FromSource^.WaitTime +
  401. WorkReq.Death - WorkReq.Birth;
  402. if Buffer^.GetReq(WorkReq) then
  403. begin {‚ ¡ãä¥à¥ ­ å®¤¨« áì § ï¢ª }
  404. WorkReq.FromSource^.MatWait := WorkReq.FromSource^.MatWait +
  405. CurTime-WorkReq.Birth;
  406. Device^.AddReq(@WorkReq,CurTime);
  407. end
  408. else {Need to gen new req}
  409. begin
  410. Device^.AddReq(@Sources^[NextSource]^.LastReq,Sources^[NextSource]^.LastReq.Birth);
  411. Sources^[NextSource]^.GenNewReq;
  412. SetNextSource;
  413. end;
  414. end
  415. else {�«¨¦ ©è¥¥ ᮡë⨥ - £¥­¥à æ¨ï § ¯à®á }
  416. begin
  417. CurTime := Sources^[NextSource]^.NewTime;
  418. if not Buffer^.AddReq(Sources^[NextSource]^.LastReq,Kicked) then
  419. begin
  420. inc(Kicked.FromSource^.RefusedReq);
  421. {Kicked.FromSource^.WaitTime := Kicked.FromSource^.WaitTime +
  422. Kicked.Death-Kicked.Birth;}
  423. Inc(RefusedCount);
  424. Inc(TotalCount);
  425. end;
  426. Sources^[NextSource]^.GenNewReq;
  427. SetNextSource;
  428. end; {}
  429. inc(CurStep);
  430. Step := ret;
  431. end;{CModel.Step}
  432. {------------------------------------------------------------------}
  433. Procedure CModel.PrintValues;
  434. var
  435. i : integer;
  436. begin
  437. WriteLn('Žâ­. â®ç­®áâì - ',Delta*100:0:0,'%, ¤®¢. ¨­â ¢ ª¢. - ',DovInt:0:2);
  438. WriteLn('• à-ª  ¯®â®ª  ¯à¨¡®à  - ', Device^.Lambda:0:2);
  439. WriteLn('ˆáâ.|‚ᣠ§ ï¢.|Žâª § ï¢.|‚ë¯ § ï¢.|P ®âª. |Œ â. ®¦ | Ž¡é. ¢à.');
  440. for i := 0 to SourceCnt-1 do with Sources^[i]^ do
  441. begin
  442. write(Name:4,' ',TotalReq:9,' ',RefusedReq:9,' ',DoneReq:9,' ',100.0*RefusedReq/TotalReq:6:2,'% ');
  443. if DoneReq <> 0 then Write(MatWait/DoneReq:8:3,' ') else Write(' --- ');
  444. WriteLN(WaitTime:0:2);
  445. end;
  446. WriteLn('Š®íä䍿¨¥­â ¯à®áâ®ï ¯à¨¡®à  - ',100*Device^.Stoppage/CurTime:0:2,'%');
  447. WriteLN('---')
  448. end;{CModel.PrintValues}
  449. {------------------------------------------------------------------}
  450. Destructor CModel.Done;
  451. var
  452. c : integer;
  453. Begin
  454. for c:= 0 to SourceCnt-1 do Dispose(Sources^[c],Done);
  455. FreeMem(Sources,Sizeof(PSource)*MaxSrc);
  456. end;{CModel.Done}
  457. {------------------------------------------------------------------}
  458. END. {EOF}