You can not select more than 25 topics Topics must start with a chinese character,a letter or number, can include dashes ('-') and can be up to 35 characters long.

InTheRange.cs 29 kB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996
  1. using System;
  2. using System.Threading;
  3. namespace Preparation.Utility
  4. {
  5. //其对应属性不应当有set访问器,避免不安全的=赋值
  6. public class InTheVariableRange
  7. {
  8. protected readonly object vLock = new();
  9. public object VLock => vLock;
  10. private static int numOfClass = 0;
  11. public static int NumOfClass => numOfClass;
  12. public readonly int idInClass;
  13. public int IdInClass => idInClass;
  14. public InTheVariableRange()
  15. {
  16. idInClass = Interlocked.Increment(ref numOfClass);
  17. }
  18. }
  19. /// <summary>
  20. /// 一个保证在[0,maxValue]的可变int,支持可变的maxValue(请确保大于0)
  21. /// </summary>
  22. public class IntInTheVariableRange : InTheVariableRange
  23. {
  24. protected int v;
  25. protected int maxV;
  26. #region 构造与读取
  27. public IntInTheVariableRange(int value, int maxValue) : base()
  28. {
  29. if (maxValue < 0)
  30. {
  31. Debugger.Output("Warning:Try to set IntInTheVariableRange.maxValue to " + maxValue.ToString() + ".");
  32. maxValue = 0;
  33. }
  34. v = value < maxValue ? value : maxValue;
  35. this.maxV = maxValue;
  36. }
  37. /// <summary>
  38. /// 默认使Value=maxValue
  39. /// </summary>
  40. public IntInTheVariableRange(int maxValue) : base()
  41. {
  42. if (maxValue < 0)
  43. {
  44. Debugger.Output("Warning:Try to set IntInTheVariableRange.maxValue to " + maxValue.ToString() + ".");
  45. maxValue = 0;
  46. }
  47. v = this.maxV = maxValue;
  48. }
  49. public IntInTheVariableRange() : base()
  50. {
  51. v = this.maxV = int.MaxValue;
  52. }
  53. public override string ToString()
  54. {
  55. lock (vLock)
  56. {
  57. return "value:" + v.ToString() + " , maxValue:" + maxV.ToString();
  58. }
  59. }
  60. public int GetValue() { lock (vLock) return v; }
  61. public static implicit operator int(IntInTheVariableRange aint) => aint.GetValue();
  62. public int GetMaxV() { lock (vLock) return maxV; }
  63. public (int, int) GetValueAndMaxV() { lock (vLock) return (v, maxV); }
  64. public bool IsMaxV() { lock (vLock) return v == maxV; }
  65. #endregion
  66. #region 内嵌读取(在锁的情况下读取内容同时读取其他更基本的外部数据)
  67. public (int, long) GetValue(StartTime startTime)
  68. {
  69. lock (vLock)
  70. {
  71. return (v, startTime.Get());
  72. }
  73. }
  74. public (int, int, long) GetValueAndMaxValue(StartTime startTime)
  75. {
  76. lock (vLock)
  77. {
  78. return (v, maxV, startTime.Get());
  79. }
  80. }
  81. #endregion
  82. #region 普通设置MaxV与Value的值的方法
  83. /// <summary>
  84. /// 若maxValue<=0则maxValue设为0并返回False
  85. /// </summary>
  86. public bool SetMaxV(int maxValue)
  87. {
  88. if (maxValue <= 0)
  89. {
  90. lock (vLock)
  91. {
  92. v = maxV = 0;
  93. return false;
  94. }
  95. }
  96. lock (vLock)
  97. {
  98. maxV = maxValue;
  99. if (v > maxValue) v = maxValue;
  100. }
  101. return true;
  102. }
  103. /// <summary>
  104. /// 应当保证该maxValue>=0
  105. /// </summary>
  106. public void SetPositiveMaxV(int maxValue)
  107. {
  108. lock (vLock)
  109. {
  110. maxV = maxValue;
  111. if (v > maxValue) v = maxValue;
  112. }
  113. }
  114. public int SetV(int value)
  115. {
  116. if (value <= 0)
  117. {
  118. lock (vLock)
  119. {
  120. return v = 0;
  121. }
  122. }
  123. lock (vLock)
  124. {
  125. return v = (value > maxV) ? maxV : value;
  126. }
  127. }
  128. /// <summary>
  129. /// 应当保证该value>=0
  130. /// </summary>
  131. public int SetPositiveV(int value)
  132. {
  133. lock (vLock)
  134. {
  135. return v = (value > maxV) ? maxV : value;
  136. }
  137. }
  138. #endregion
  139. #region 特殊条件的设置MaxV与Value的值的方法
  140. /// <summary>
  141. /// 如果当前值大于maxValue,则更新maxValue失败
  142. /// </summary>
  143. public bool TrySetMaxV(int maxValue)
  144. {
  145. lock (vLock)
  146. {
  147. if (v > maxValue) return false;
  148. maxV = maxValue;
  149. return true;
  150. }
  151. }
  152. public void SetVToMaxV()
  153. {
  154. lock (vLock)
  155. {
  156. v = maxV;
  157. }
  158. }
  159. public bool Set0IfNotMaxor0()
  160. {
  161. lock (vLock)
  162. {
  163. if (v < maxV && v > 0)
  164. {
  165. v = 0;
  166. return true;
  167. }
  168. }
  169. return false;
  170. }
  171. public bool Set0IfMax()
  172. {
  173. lock (vLock)
  174. {
  175. if (v == maxV)
  176. {
  177. v = 0;
  178. return true;
  179. }
  180. }
  181. return false;
  182. }
  183. #endregion
  184. #region 普通运算
  185. /// <returns>返回实际改变量</returns>
  186. public int AddV(int addV)
  187. {
  188. lock (vLock)
  189. {
  190. int previousV = v;
  191. v += addV;
  192. if (v < 0) v = 0;
  193. if (v > maxV) v = maxV;
  194. return v - previousV;
  195. }
  196. }
  197. /// <summary>
  198. /// 应当保证增加值大于0
  199. /// </summary>
  200. /// <returns>返回实际改变量</returns>
  201. public int AddPositiveV(int addPositiveV)
  202. {
  203. lock (vLock)
  204. {
  205. addPositiveV = Math.Min(addPositiveV, maxV - v);
  206. v += addPositiveV;
  207. }
  208. return addPositiveV;
  209. }
  210. public void MulV(int mulV)
  211. {
  212. if (mulV <= 0)
  213. {
  214. lock (vLock) v = 0;
  215. return;
  216. }
  217. lock (vLock)
  218. {
  219. if (v > maxV / mulV) v = maxV; //避免溢出
  220. else v *= mulV;
  221. }
  222. }
  223. public void MulV(double mulV)
  224. {
  225. if (mulV <= 0)
  226. {
  227. lock (vLock) v = 0;
  228. return;
  229. }
  230. lock (vLock)
  231. {
  232. if (v > maxV / mulV) v = maxV; //避免溢出
  233. else v = (int)(v * mulV);
  234. }
  235. }
  236. /// <summary>
  237. /// 应当保证乘数大于0
  238. /// </summary>
  239. public void MulPositiveV(int mulPositiveV)
  240. {
  241. lock (vLock)
  242. {
  243. if (v > maxV / mulPositiveV) v = maxV; //避免溢出
  244. else v *= mulPositiveV;
  245. }
  246. }
  247. /// <summary>
  248. /// 应当保证乘数大于0
  249. /// </summary>
  250. public void MulPositiveV(double mulPositiveV)
  251. {
  252. lock (vLock)
  253. {
  254. if (v > maxV / mulPositiveV) v = maxV; //避免溢出
  255. else v = (int)(v * mulPositiveV);
  256. }
  257. }
  258. /// <returns>返回实际改变量</returns>
  259. public int SubV(int subV)
  260. {
  261. lock (vLock)
  262. {
  263. int previousV = v;
  264. v -= subV;
  265. if (v < 0) v = 0;
  266. if (v > maxV) v = maxV;
  267. return v - previousV;
  268. }
  269. }
  270. /// <summary>
  271. /// 应当保证该减少值大于0
  272. /// </summary>
  273. /// <returns>返回实际改变量</returns>
  274. public int SubPositiveV(int subPositiveV)
  275. {
  276. lock (vLock)
  277. {
  278. subPositiveV = Math.Min(subPositiveV, v);
  279. v -= subPositiveV;
  280. }
  281. return subPositiveV;
  282. }
  283. #endregion
  284. #region 特殊条件的运算
  285. /// <summary>
  286. /// 试图加到满,如果无法加到maxValue则不加并返回-1
  287. /// </summary>
  288. /// <returns>返回实际改变量</returns>
  289. public int TryAddToMaxV(int addV)
  290. {
  291. lock (vLock)
  292. {
  293. if (maxV - v <= addV)
  294. {
  295. addV = maxV - v;
  296. v = maxV;
  297. return addV;
  298. }
  299. return -1;
  300. }
  301. }
  302. #endregion
  303. #region 与InTheVariableRange类的运算,运算会影响该对象的值
  304. public int AddV(IntInTheVariableRange a)
  305. {
  306. if (this.idInClass == a.idInClass) return -1;
  307. bool thisLock = false;
  308. bool thatLock = false;
  309. try
  310. {
  311. if (this.idInClass < a.idInClass)
  312. {
  313. Monitor.Enter(vLock, ref thisLock);
  314. Monitor.Enter(a.VLock, ref thatLock);
  315. }
  316. else
  317. {
  318. Monitor.Enter(a.VLock, ref thatLock);
  319. Monitor.Enter(vLock, ref thisLock);
  320. }
  321. int previousV = v;
  322. v += a.GetValue();
  323. if (v > maxV) v = maxV;
  324. a.SubPositiveV(v - previousV);
  325. return v - previousV;
  326. }
  327. finally
  328. {
  329. if (thisLock) Monitor.Exit(vLock);
  330. if (thatLock) Monitor.Exit(a.VLock);
  331. }
  332. }
  333. public int SubV(IntInTheVariableRange a)
  334. {
  335. if (this.idInClass == a.idInClass) return -1;
  336. bool thisLock = false;
  337. bool thatLock = false;
  338. try
  339. {
  340. if (this.idInClass < a.idInClass)
  341. {
  342. Monitor.Enter(vLock, ref thisLock);
  343. Monitor.Enter(a.VLock, ref thatLock);
  344. }
  345. else
  346. {
  347. Monitor.Enter(a.VLock, ref thatLock);
  348. Monitor.Enter(vLock, ref thisLock);
  349. }
  350. int previousV = v;
  351. v -= a.GetValue();
  352. if (v < 0) v = 0;
  353. a.SubPositiveV(previousV - v);
  354. return previousV - v;
  355. }
  356. finally
  357. {
  358. if (thisLock) Monitor.Exit(vLock);
  359. if (thatLock) Monitor.Exit(a.VLock);
  360. }
  361. }
  362. #endregion
  363. #region 与StartTime类的特殊条件的运算,运算会影响StartTime类的值
  364. /// <summary>
  365. /// 试图加到满,如果加上时间差*速度可以达到MaxV,则加上并使startTime变为long.MaxValue
  366. /// 如果无法加到maxValue则不加
  367. /// </summary>
  368. /// <returns>返回试图加到的值与最大值</returns>
  369. public (int, int, long) TryAddToMaxV(StartTime startTime, double speed = 1.0)
  370. {
  371. lock (vLock)
  372. {
  373. long addV = (long)(startTime.StopIfPassing(maxV - v) * speed);
  374. if (addV < 0) return (v, maxV, startTime.Get());
  375. if (maxV - v < addV) return (v = maxV, maxV, startTime.Get());
  376. return ((int)(v + addV), maxV, startTime.Get());
  377. }
  378. }
  379. /// <summary>
  380. /// 增加量为时间差*速度,并将startTime变为long.MaxValue
  381. /// </summary>
  382. /// <returns>返回实际改变量</returns>
  383. public int AddV(StartTime startTime, double speed = 1.0)
  384. {
  385. lock (vLock)
  386. {
  387. int previousV = v;
  388. int addV = (int)((Environment.TickCount64 - startTime.Stop()) * speed);
  389. if (addV < 0) v += addV;
  390. else return 0;
  391. if (v > maxV) v = maxV;
  392. return v - previousV;
  393. }
  394. }
  395. /// <summary>
  396. /// 试图加到满,如果加上时间差*速度可以达到MaxV,则加上并使startTime变为long.MaxValue
  397. /// 如果无法加到maxValue则清零
  398. /// </summary>
  399. /// <returns>返回是否清零</returns>
  400. public bool Set0IfNotAddToMaxV(StartTime startTime, double speed = 1.0)
  401. {
  402. lock (vLock)
  403. {
  404. if (v == maxV) return false;
  405. int addV = (int)(startTime.StopIfPassing(maxV - v) * speed);
  406. if (addV < 0)
  407. {
  408. v = 0;
  409. return true;
  410. }
  411. if (maxV - v < addV)
  412. {
  413. v = maxV;
  414. return false;
  415. }
  416. v = 0;
  417. return false;
  418. }
  419. }
  420. #endregion
  421. }
  422. /// <summary>
  423. /// 一个保证在[0,maxValue]的可变long,支持可变的maxValue(请确保大于0)
  424. /// </summary>
  425. public class LongInTheVariableRange : InTheVariableRange
  426. {
  427. protected long v;
  428. protected long maxV;
  429. #region 构造与读取
  430. public LongInTheVariableRange(long value, long maxValue) : base()
  431. {
  432. if (maxValue < 0)
  433. {
  434. Debugger.Output("Warning:Try to set SafaValues.LongInTheVariableRange.maxValue to " + maxValue.ToString() + ".");
  435. maxValue = 0;
  436. }
  437. v = value < maxValue ? value : maxValue;
  438. this.maxV = maxValue;
  439. }
  440. /// <summary>
  441. /// 默认使Value=maxValue
  442. /// </summary>
  443. public LongInTheVariableRange(long maxValue) : base()
  444. {
  445. if (maxValue < 0)
  446. {
  447. Debugger.Output("Warning:Try to set SafaValues.LongInTheVariableRange.maxValue to " + maxValue.ToString() + ".");
  448. maxValue = 0;
  449. }
  450. v = this.maxV = maxValue;
  451. }
  452. public LongInTheVariableRange() : base()
  453. {
  454. v = this.maxV = long.MaxValue;
  455. }
  456. public override string ToString()
  457. {
  458. lock (vLock)
  459. {
  460. return "value:" + v.ToString() + " , maxValue:" + maxV.ToString();
  461. }
  462. }
  463. public long GetValue() { lock (vLock) return v; }
  464. public static implicit operator long(LongInTheVariableRange aint) => aint.GetValue();
  465. public long GetMaxV() { lock (vLock) return maxV; }
  466. public (long, long) GetValueAndMaxV() { lock (vLock) return (v, maxV); }
  467. public bool IsMaxV()
  468. {
  469. lock (vLock)
  470. {
  471. return v == maxV;
  472. }
  473. }
  474. #endregion
  475. #region 普通设置MaxV与Value的值的方法
  476. /// <summary>
  477. /// 若maxValue<=0则maxValue设为0并返回False
  478. /// </summary>
  479. public bool SetMaxV(long maxValue)
  480. {
  481. if (maxValue <= 0)
  482. {
  483. lock (vLock)
  484. {
  485. v = maxV = 0;
  486. return false;
  487. }
  488. }
  489. lock (vLock)
  490. {
  491. maxV = maxValue;
  492. if (v > maxValue) v = maxValue;
  493. }
  494. return true;
  495. }
  496. /// <summary>
  497. /// 应当保证该maxValue>=0
  498. /// </summary>
  499. public void SetPositiveMaxV(long maxValue)
  500. {
  501. lock (vLock)
  502. {
  503. maxV = maxValue;
  504. if (v > maxValue) v = maxValue;
  505. }
  506. }
  507. public long SetV(long value)
  508. {
  509. if (value <= 0)
  510. {
  511. lock (vLock)
  512. {
  513. return v = 0;
  514. }
  515. }
  516. lock (vLock)
  517. {
  518. return v = (value > maxV) ? maxV : value;
  519. }
  520. }
  521. /// <summary>
  522. /// 应当保证该value>=0
  523. /// </summary>
  524. public long SetPositiveV(long value)
  525. {
  526. lock (vLock)
  527. {
  528. return v = (value > maxV) ? maxV : value;
  529. }
  530. }
  531. #endregion
  532. #region 普通运算
  533. /// <returns>返回实际改变量</returns>
  534. public long AddV(long addV)
  535. {
  536. lock (vLock)
  537. {
  538. long previousV = v;
  539. v += addV;
  540. if (v < 0) v = 0;
  541. if (v > maxV) v = maxV;
  542. return v - previousV;
  543. }
  544. }
  545. /// <summary>
  546. /// 应当保证增加值大于0
  547. /// </summary>
  548. /// <returns>返回实际改变量</returns>
  549. public long AddPositiveV(long addPositiveV)
  550. {
  551. lock (vLock)
  552. {
  553. addPositiveV = Math.Min(addPositiveV, maxV - v);
  554. v += addPositiveV;
  555. }
  556. return addPositiveV;
  557. }
  558. public void MulV(long mulV)
  559. {
  560. if (mulV <= 0)
  561. {
  562. lock (vLock) v = 0;
  563. return;
  564. }
  565. lock (vLock)
  566. {
  567. if (v > maxV / mulV) v = maxV; //避免溢出
  568. else v *= mulV;
  569. }
  570. }
  571. public void MulV(double mulV)
  572. {
  573. if (mulV <= 0)
  574. {
  575. lock (vLock) v = 0;
  576. return;
  577. }
  578. lock (vLock)
  579. {
  580. if (v > maxV / mulV) v = maxV; //避免溢出
  581. else v = (long)(v * mulV);
  582. }
  583. }
  584. /// <summary>
  585. /// 应当保证乘数大于0
  586. /// </summary>
  587. public void MulPositiveV(long mulPositiveV)
  588. {
  589. lock (vLock)
  590. {
  591. if (v > maxV / mulPositiveV) v = maxV; //避免溢出
  592. else v *= mulPositiveV;
  593. }
  594. }
  595. /// <summary>
  596. /// 应当保证乘数大于0
  597. /// </summary>
  598. public void MulPositiveV(double mulPositiveV)
  599. {
  600. lock (vLock)
  601. {
  602. if (v > maxV / mulPositiveV) v = maxV; //避免溢出
  603. else v = (long)(v * mulPositiveV);
  604. }
  605. }
  606. /// <returns>返回实际改变量</returns>
  607. public long SubV(long subV)
  608. {
  609. lock (vLock)
  610. {
  611. long previousV = v;
  612. v -= subV;
  613. if (v < 0) v = 0;
  614. if (v > maxV) v = maxV;
  615. return v - previousV;
  616. }
  617. }
  618. /// <summary>
  619. /// 应当保证该减少值大于0
  620. /// </summary>
  621. /// <returns>返回实际改变量</returns>
  622. public long SubPositiveV(long subPositiveV)
  623. {
  624. lock (vLock)
  625. {
  626. subPositiveV = Math.Min(subPositiveV, v);
  627. v -= subPositiveV;
  628. }
  629. return subPositiveV;
  630. }
  631. #endregion
  632. #region 特殊条件的设置MaxV与Value的值的方法
  633. /// <summary>
  634. /// 如果当前值大于maxValue,则更新maxValue失败
  635. /// </summary>
  636. public bool TrySetMaxV(long maxValue)
  637. {
  638. lock (vLock)
  639. {
  640. if (v > maxValue) return false;
  641. maxV = maxValue;
  642. return true;
  643. }
  644. }
  645. public void SetVToMaxV()
  646. {
  647. lock (vLock)
  648. {
  649. v = maxV;
  650. }
  651. }
  652. public bool Set0IfNotMax()
  653. {
  654. lock (vLock)
  655. {
  656. if (v < maxV)
  657. {
  658. v = 0;
  659. return true;
  660. }
  661. }
  662. return false;
  663. }
  664. public bool Set0IfMax()
  665. {
  666. lock (vLock)
  667. {
  668. if (v == maxV)
  669. {
  670. v = 0;
  671. return true;
  672. }
  673. }
  674. return false;
  675. }
  676. #endregion
  677. #region 特殊条件的运算
  678. /// <summary>
  679. /// 试图加到满,如果无法加到maxValue则不加并返回-1
  680. /// </summary>
  681. /// <returns>返回实际改变量</returns>
  682. public long TryAddToMaxV(long addV)
  683. {
  684. lock (vLock)
  685. {
  686. if (maxV - v <= addV)
  687. {
  688. addV = maxV - v;
  689. v = maxV;
  690. return addV;
  691. }
  692. return -1;
  693. }
  694. }
  695. #endregion
  696. #region 与StartTime类的特殊条件的运算,运算会影响StartTime类的值
  697. /// <summary>
  698. /// 试图加到满,如果加上时间差*速度可以达到MaxV,则加上并使startTime变为long.MaxValue
  699. /// 如果无法加到maxValue则不加
  700. /// </summary>
  701. /// <returns>返回试图加到的值与最大值</returns>
  702. public (long, long, long) TryAddToMaxV(StartTime startTime, double speed = 1.0)
  703. {
  704. lock (vLock)
  705. {
  706. long addV = (long)(startTime.StopIfPassing(maxV - v) * speed);
  707. if (addV < 0) return (v, maxV, startTime.Get());
  708. if (maxV - v < addV) return (v = maxV, maxV, startTime.Get());
  709. return (v + addV, maxV, startTime.Get());
  710. }
  711. }
  712. #endregion
  713. }
  714. /// <summary>
  715. /// 一个保证在[0,maxValue]的可变double,支持可变的maxValue(请确保大于0)
  716. /// </summary>
  717. public class DoubleInTheVariableRange : InTheVariableRange
  718. {
  719. protected double v;
  720. protected double maxV;
  721. #region 构造与读取
  722. public DoubleInTheVariableRange(double value, double maxValue) : base()
  723. {
  724. if (maxValue < 0)
  725. {
  726. Debugger.Output("Warning:Try to set DoubleInTheVariableRange.maxValue to " + maxValue.ToString() + ".");
  727. maxValue = 0;
  728. }
  729. v = value < maxValue ? value : maxValue;
  730. this.maxV = maxValue;
  731. }
  732. /// <summary>
  733. /// 默认使Value=maxValue
  734. /// </summary>
  735. public DoubleInTheVariableRange(double maxValue) : base()
  736. {
  737. if (maxValue < 0)
  738. {
  739. Debugger.Output("Warning:Try to set DoubleInTheVariableRange.maxValue to " + maxValue.ToString() + ".");
  740. maxValue = 0;
  741. }
  742. v = this.maxV = maxValue;
  743. }
  744. public DoubleInTheVariableRange() : base()
  745. {
  746. v = this.maxV = double.MaxValue;
  747. }
  748. public override string ToString()
  749. {
  750. lock (vLock)
  751. {
  752. return "value:" + v.ToString() + " , maxValue:" + maxV.ToString();
  753. }
  754. }
  755. public double GetValue() { lock (vLock) return v; }
  756. public static implicit operator double(DoubleInTheVariableRange adouble) => adouble.GetValue();
  757. public double GetMaxV() { lock (vLock) return maxV; }
  758. public (double, double) GetValueAndMaxV() { lock (vLock) return (v, maxV); }
  759. public bool IsMaxV()
  760. {
  761. lock (vLock)
  762. {
  763. return v == maxV;
  764. }
  765. }
  766. #endregion
  767. #region 普通设置MaxV与Value的值的方法
  768. /// <summary>
  769. /// 若maxValue<=0则maxValue设为0并返回False
  770. /// </summary>
  771. public bool SetMaxV(double maxValue)
  772. {
  773. if (maxValue <= 0)
  774. {
  775. lock (vLock)
  776. {
  777. v = maxV = 0;
  778. return false;
  779. }
  780. }
  781. lock (vLock)
  782. {
  783. maxV = maxValue;
  784. if (v > maxValue) v = maxValue;
  785. }
  786. return true;
  787. }
  788. /// <summary>
  789. /// 应当保证该maxValue>=0
  790. /// </summary>
  791. public void SetPositiveMaxV(double maxValue)
  792. {
  793. lock (vLock)
  794. {
  795. maxV = maxValue;
  796. if (v > maxValue) v = maxValue;
  797. }
  798. }
  799. public double SetV(double value)
  800. {
  801. if (value <= 0)
  802. {
  803. lock (vLock)
  804. {
  805. return v = 0;
  806. }
  807. }
  808. lock (vLock)
  809. {
  810. return v = (value > maxV) ? maxV : value;
  811. }
  812. }
  813. /// <summary>
  814. /// 应当保证该value>=0
  815. /// </summary>
  816. public double SetPositiveV(double value)
  817. {
  818. lock (vLock)
  819. {
  820. return v = (value > maxV) ? maxV : value;
  821. }
  822. }
  823. #endregion
  824. #region 普通运算
  825. /// <returns>返回实际改变量</returns>
  826. public double AddV(double addV)
  827. {
  828. lock (vLock)
  829. {
  830. double previousV = v;
  831. v += addV;
  832. if (v < 0) v = 0;
  833. if (v > maxV) v = maxV;
  834. return v - previousV;
  835. }
  836. }
  837. /// <summary>
  838. /// 应当保证增加值大于0
  839. /// </summary>
  840. /// <returns>返回实际改变量</returns>
  841. public double AddPositiveV(double addPositiveV)
  842. {
  843. lock (vLock)
  844. {
  845. addPositiveV = Math.Min(addPositiveV, maxV - v);
  846. v += addPositiveV;
  847. }
  848. return addPositiveV;
  849. }
  850. public void MulV(double mulV)
  851. {
  852. if (mulV <= 0)
  853. {
  854. lock (vLock) v = 0;
  855. return;
  856. }
  857. lock (vLock)
  858. {
  859. if (v > maxV / mulV) v = maxV; //避免溢出
  860. else v *= mulV;
  861. }
  862. }
  863. /// <summary>
  864. /// 应当保证乘数大于0
  865. /// </summary>
  866. public void MulPositiveV(double mulPositiveV)
  867. {
  868. lock (vLock)
  869. {
  870. if (v > maxV / mulPositiveV) v = maxV; //避免溢出
  871. else v *= mulPositiveV;
  872. }
  873. }
  874. /// <returns>返回实际改变量</returns>
  875. public double SubV(double subV)
  876. {
  877. lock (vLock)
  878. {
  879. double previousV = v;
  880. v -= subV;
  881. if (v < 0) v = 0;
  882. if (v > maxV) v = maxV;
  883. return v - previousV;
  884. }
  885. }
  886. /// <summary>
  887. /// 应当保证该减少值大于0
  888. /// </summary>
  889. /// <returns>返回实际改变量</returns>
  890. public double SubPositiveV(double subPositiveV)
  891. {
  892. lock (vLock)
  893. {
  894. subPositiveV = Math.Min(subPositiveV, v);
  895. v -= subPositiveV;
  896. }
  897. return subPositiveV;
  898. }
  899. #endregion
  900. #region 特殊条件的设置MaxV与Value的值的方法
  901. /// <summary>
  902. /// 如果当前值大于maxValue,则更新maxValue失败
  903. /// </summary>
  904. public bool TrySetMaxV(double maxValue)
  905. {
  906. lock (vLock)
  907. {
  908. if (v > maxValue) return false;
  909. maxV = maxValue;
  910. return true;
  911. }
  912. }
  913. public void SetVToMaxV()
  914. {
  915. lock (vLock)
  916. {
  917. v = maxV;
  918. }
  919. }
  920. public bool Set0IfNotMax()
  921. {
  922. lock (vLock)
  923. {
  924. if (v < maxV)
  925. {
  926. v = 0;
  927. return true;
  928. }
  929. }
  930. return false;
  931. }
  932. public bool Set0IfMax()
  933. {
  934. lock (vLock)
  935. {
  936. if (v == maxV)
  937. {
  938. v = 0;
  939. return true;
  940. }
  941. }
  942. return false;
  943. }
  944. #endregion
  945. #region 特殊条件的运算
  946. /// <summary>
  947. /// 试图加到满,如果无法加到maxValue则不加并返回-1
  948. /// </summary>
  949. /// <returns>返回实际改变量</returns>
  950. public double TryAddToMaxV(double addV)
  951. {
  952. lock (vLock)
  953. {
  954. if (maxV - v <= addV)
  955. {
  956. addV = maxV - v;
  957. v = maxV;
  958. return addV;
  959. }
  960. return -1;
  961. }
  962. }
  963. #endregion
  964. }
  965. }