Compare commits
724 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
fd8d7b22f4
|
|||
|
b40235db0f
|
|||
|
6b0b19fcfb
|
|||
|
|
b940686cdd | ||
|
|
528c97094c | ||
|
|
c2d13876f6 | ||
|
|
ce3be11e16 | ||
|
|
f5ee557812 | ||
|
|
08f55f2a99 | ||
|
|
33c422264a | ||
|
|
7e21064b8b | ||
|
|
061eccf846 | ||
|
|
222dd7ea8a | ||
|
|
3381e5cbf0 | ||
|
|
ffa6c647f8 | ||
|
|
06f2fcaddd | ||
|
2bc2352cb1
|
|||
|
249de93df7
|
|||
|
c2dcc88e22
|
|||
|
18c77aacbe
|
|||
|
25e918ceea
|
|||
|
|
01920b68d7 | ||
|
|
125d76e5f2 | ||
|
|
f72ddd71e9 | ||
|
|
666126808d | ||
|
|
f53145d62e | ||
|
|
7c6c216b02 | ||
|
42bb1f884a
|
|||
|
734be9ee21
|
|||
|
32fcff1dfc
|
|||
|
a02e8dc67b
|
|||
|
9de2242aaf
|
|||
|
7f40da8e20
|
|||
|
2858346c00
|
|||
|
72a8830891
|
|||
|
5a8322f5b7
|
|||
|
e969533dc0
|
|||
|
40a28aecf3
|
|||
|
f0057ccad2
|
|||
|
14d8e83a64
|
|||
|
efebfc3c9d
|
|||
|
71d27c1061
|
|||
|
|
593cdfb92c | ||
|
|
40b753062a | ||
|
|
1fb16d56c2 | ||
|
|
9988b1b19b | ||
|
18a549be57
|
|||
|
5fd8bcba28
|
|||
|
c19c858de1
|
|||
|
|
1ab775aa3e | ||
|
|
0e11a0f9c4 | ||
|
|
42ff61bf91 | ||
|
|
d4e76dc1a8 | ||
|
|
fb42b0675b | ||
|
|
8bc09d9a59 | ||
|
|
5650cb8fd6 | ||
|
|
ba59f7df79 | ||
|
|
d8b89379cc | ||
|
|
53377485bb | ||
|
|
6ae5cd51b0 | ||
|
|
e2a337a7aa | ||
|
|
3f5153c497 | ||
|
|
4922f0a516 | ||
|
|
82b204aa1f | ||
|
|
9ea34dcc95 | ||
|
|
a25077e989 | ||
|
|
75b5f7ddd5 | ||
|
|
ef1b6bad2e | ||
|
|
b27fe9362a | ||
|
|
6fb68f282a | ||
|
|
cfdb31fe80 | ||
|
|
98e9076f1b | ||
|
|
a675835ad4 | ||
|
|
823990afdc | ||
|
|
c4c62e958f | ||
|
|
4b5f2bfddf | ||
|
|
320ef51bfd | ||
|
|
bcad7597a2 | ||
|
|
ccb9f8350e | ||
|
|
5e035b43df | ||
|
|
4e0f4999a0 | ||
|
|
eca4844792 | ||
|
|
0512cdd711 | ||
|
|
508c464efe | ||
|
|
5262ee11da | ||
|
|
6c09eb15ff | ||
|
|
388977fe04 | ||
|
|
834f5e8de5 | ||
|
|
7a080280f5 | ||
|
|
9a0f645e01 | ||
|
|
dc25063ca1 | ||
|
|
f3658e466f | ||
|
|
3f356c0004 | ||
|
|
d51647a4b5 | ||
|
|
8078e41ed4 | ||
|
|
2c8c307cdd | ||
|
|
839f90d16a | ||
|
|
41da460bfc | ||
|
|
3f68f0dd21 | ||
|
|
c6ef91fde7 | ||
|
|
f4530aee4f | ||
|
|
231546facd | ||
|
|
876f42c59e | ||
|
|
6d35a30ae2 | ||
|
|
8acd7c8925 | ||
|
|
05e5427144 | ||
|
|
2435daab64 | ||
|
|
b0e32dffaf | ||
|
|
c21cbe7299 | ||
|
|
92f19d4646 | ||
| a8c1fd0df1 | |||
|
|
907a902c69 | ||
|
|
4bf700c4ff | ||
|
|
c7b2a07dd0 | ||
|
|
b9c6054185 | ||
|
|
c012e33ef4 | ||
|
|
94df8b3f79 | ||
|
|
542467ccea | ||
|
|
bdeb098dc4 | ||
|
|
b4d77667bc | ||
|
|
d615aaecc5 | ||
|
|
02fd8246cd | ||
|
|
bc590923ad | ||
|
|
e2cfdb37e7 | ||
|
|
9081c66b85 | ||
|
|
10e97019a8 | ||
|
|
3e05290fe9 | ||
|
|
9eb9cad315 | ||
|
|
76d385e235 | ||
| c3a137aebd | |||
| 466fde4885 | |||
| 310178a5ca | |||
|
|
f89a01e4ad | ||
|
|
d08a235d23 | ||
|
|
2a4e26a817 | ||
|
|
93bdbd0e73 | ||
|
|
1d14e80624 | ||
|
|
6a066415eb | ||
| d06ff5888c | |||
| c76243839f | |||
| f40f2a001a | |||
| 8be005ced0 | |||
| 7415ee2434 | |||
| bbaf620297 | |||
| a49a3b2beb | |||
| 6f7bb5d92c | |||
| 299867a910 | |||
|
|
fa3a9da07e | ||
|
|
16cf7d8bda | ||
|
|
be61994ae7 | ||
|
|
1da2e2183c | ||
|
|
0ff158b46e | ||
|
|
ee1ea2f0b0 | ||
|
|
d7e592180b | ||
|
|
b9e633a0ff | ||
|
|
ca8df29dd9 | ||
|
|
6f44ab32f0 | ||
|
|
00bd2e62e8 | ||
|
|
b1716837b5 | ||
|
|
8ae981b121 | ||
|
|
042922a9cd | ||
|
|
75cdcc1e4d | ||
|
|
aabcf29326 | ||
|
|
bbd0017b33 | ||
|
|
2f9dcb42e6 | ||
|
|
68133f5fe6 | ||
|
|
4cb015615a | ||
|
|
097847d286 | ||
|
|
494484ee0b | ||
|
|
d3e18d6567 | ||
|
|
8752f33464 | ||
|
|
815da2b24c | ||
|
|
de592ee65b | ||
|
|
47c78e94fe | ||
|
|
c1e3853eca | ||
|
|
a9690576de | ||
|
|
a5a8a0b71c | ||
|
|
404a2a4b4f | ||
|
|
3ea128ccb0 | ||
|
|
d5c0d5c19f | ||
|
|
86bda7772b | ||
|
|
e9f68fe427 | ||
|
|
335046418e | ||
|
|
e8ba2b218c | ||
|
|
be8f9ea544 | ||
|
|
ed8c2edb15 | ||
|
|
8aa562afee | ||
|
|
a02332745b | ||
| bcbadd5a20 | |||
| 9557e105b9 | |||
| c10fca45e6 | |||
| 6712751141 | |||
| be33f30425 | |||
| 108d7a2d5e | |||
| 033a1c48b5 | |||
| c7990947dd | |||
| 711f4a8d11 | |||
| 58bb22df90 | |||
| 247033dbeb | |||
| 08ec940831 | |||
| 88921d2a4e | |||
| 91751886f3 | |||
| 6f0bf4194b | |||
| 570e49ad76 | |||
| 15d723ea38 | |||
| c46b968562 | |||
| 07f4dd2dca | |||
| e673483ef5 | |||
| f16bbf51c6 | |||
| 19efc1c69e | |||
| 0a86856876 | |||
| b494f2fb8d | |||
| 9d826892eb | |||
|
|
02ef0da374 | ||
|
|
1b92549b34 | ||
|
|
71d407bb88 | ||
|
|
624f232b6b | ||
|
|
c6e5e19a3a | ||
|
|
83da51bf89 | ||
|
|
71eed097a6 | ||
|
|
eac53eca60 | ||
|
|
50796391f9 | ||
|
|
c232b856b9 | ||
|
|
7deec49219 | ||
|
|
ec22181750 | ||
|
|
e6340b4894 | ||
|
|
6c6752fe82 | ||
|
|
9c97d84a6f | ||
|
|
e10eaab5e3 | ||
|
|
22aaec2fa6 | ||
|
|
48bfe1ec00 | ||
|
|
5d0c4cd21a | ||
|
|
e2d6d98002 | ||
|
|
b65af65a26 | ||
|
|
3a266c0e51 | ||
|
|
008b1e9893 | ||
|
|
cc58e77760 | ||
|
|
a917f4359c | ||
|
|
a72bd75907 | ||
|
|
a464ada95d | ||
|
|
93fc5e860c | ||
|
|
4b5b90bd68 | ||
|
|
8a31685ccf | ||
|
|
267618ccc5 | ||
|
|
22f206d939 | ||
|
|
bb4e1a7994 | ||
|
|
9ad9d4744c | ||
|
|
9c2fd4e046 | ||
|
|
baca77f701 | ||
|
|
3844099acf | ||
|
|
3292c09a5f | ||
|
|
b60f8541f2 | ||
|
|
7a5db49cfb | ||
|
|
7e213539ca | ||
|
|
8050a4c2f5 | ||
|
|
96ee827239 | ||
|
|
7369c776dd | ||
|
|
9a17cd4e9e | ||
|
|
91e1987d75 | ||
|
|
36499dc868 | ||
|
|
76da9a1461 | ||
|
|
ca20e0ce12 | ||
|
|
6d6f780b91 | ||
|
|
c7caf356e0 | ||
|
|
d7cb947fff | ||
|
|
c63b0a9fd2 | ||
|
|
bfd48578aa | ||
|
|
41d8d34c79 | ||
|
|
f487504fd3 | ||
|
|
361f55198d | ||
|
|
17212da67a | ||
|
|
413669a68f | ||
|
|
bae8539f82 | ||
|
|
81c0d51417 | ||
|
|
b3e24d7fdc | ||
|
|
8de643b7d1 | ||
|
|
9a652a343c | ||
|
|
ca06ed3da6 | ||
|
|
5c636597d2 | ||
|
|
4a732cb3ac | ||
|
|
9be00475c7 | ||
|
|
307092cfc2 | ||
|
|
1fd0b61408 | ||
|
|
24cde0bd03 | ||
| 86154e93af | |||
| b60593dfca | |||
| 694066286b | |||
| d7ba63a642 | |||
| 7b38286642 | |||
| 07ab60666a | |||
| f08c94908a | |||
| ab67023ea4 | |||
|
|
295644087f | ||
|
|
4e849845c6 | ||
|
|
a80e972460 | ||
|
|
22c962bec7 | ||
| c0a422ca71 | |||
| 9ff34c44b2 | |||
|
|
49b5ebddb1 | ||
|
|
b92eb24438 | ||
|
|
49f0f63338 | ||
|
|
43f7684074 | ||
|
|
f17fea31e8 | ||
|
|
5d941506f6 | ||
|
|
1b1f92dea5 | ||
|
|
c7f343544d | ||
|
|
58794e5872 | ||
|
|
c02763ae9a | ||
|
|
2414f2f7c5 | ||
|
|
f8bce850d5 | ||
|
|
b05b18b1a6 | ||
|
|
232c94c61f | ||
|
|
fcd23152e2 | ||
|
|
9a0f3f5878 | ||
|
|
d948ba4135 | ||
|
|
2018969009 | ||
|
|
8e22be7d9f | ||
|
|
bf5dbdef00 | ||
|
|
4701de0bdc | ||
|
|
b9075eb2f3 | ||
|
|
8092e37312 | ||
|
|
45c85e4ced | ||
|
|
4de074b098 | ||
|
|
e44e4e15a6 | ||
|
|
d95b12facb | ||
|
|
dc5beb09de | ||
|
|
5342c25db8 | ||
|
|
29fddff6f6 | ||
|
|
2d10424d13 | ||
|
|
91eeab7aeb | ||
|
|
cfce855c2c | ||
|
|
cb2831ce4a | ||
|
|
0e2f393334 | ||
|
|
69e0900f7d | ||
|
|
3fa4d18f77 | ||
|
|
7c6b30aa7b | ||
|
|
e369497537 | ||
|
|
93cea9fea3 | ||
|
|
c8915423fd | ||
|
|
441b4a0494 | ||
|
|
0b82e76734 | ||
|
|
ddc0f33e90 | ||
|
|
2e68e6802b | ||
|
|
ab6411fe39 | ||
|
|
2b0b094731 | ||
| 4bdeaadbcb | |||
| a6e38dd59d | |||
| 3f582dc634 | |||
| 45b58aa5a2 | |||
| cdd7915142 | |||
| b5edc53623 | |||
| 917e9edd80 | |||
|
|
d333710a8f | ||
|
|
6c60d271ad | ||
|
|
98e3217df3 | ||
|
|
cfaeeb8aa0 | ||
|
|
0cca672bd7 | ||
|
|
804ba9f9a0 | ||
|
|
669393559b | ||
|
|
a2b89e4fef | ||
|
|
b9ba58324b | ||
|
|
8ef03235fe | ||
| af162a887b | |||
| 2bd241c7a9 | |||
|
|
3fea994e93 | ||
|
|
342e9ed0d8 | ||
|
|
df264ac20d | ||
|
|
55bf37619b | ||
|
|
a3a256395f | ||
|
|
9dcaa7e507 | ||
|
|
74ebbbca7b | ||
|
|
44ab301c24 | ||
|
|
3070fab91b | ||
|
|
55d221cb81 | ||
|
|
bff48227d1 | ||
|
|
ede26291ec | ||
|
|
b8c0086e82 | ||
|
|
7d5935c5d1 | ||
|
|
7ebad522bd | ||
|
|
25c6aa4c30 | ||
|
|
93e8cf3219 | ||
|
|
2866661539 | ||
|
|
0cb7a15909 | ||
|
|
f70e07bd2c | ||
|
|
6abaa8615a | ||
|
|
b7acc6f0a4 | ||
|
|
7c39f2778f | ||
| 6668a45893 | |||
| 81b8426b41 | |||
|
|
1480485438 | ||
|
|
96b6536a7a | ||
|
|
bf2ec306cc | ||
|
|
eca1a4c7ca | ||
|
|
9b7c38ea85 | ||
|
|
b9c390f645 | ||
| 8e9314365e | |||
| dcb4e1c1cf | |||
| e884666225 | |||
| 9482e64fd9 | |||
| 2e420ad902 | |||
|
|
a7a3cfa683 | ||
|
|
55db979ebf | ||
|
|
11c0711726 | ||
|
|
24482ccb85 | ||
|
|
9a03945246 | ||
|
|
65d2c8d6de | ||
|
|
2d52315d68 | ||
|
|
25a8cd48be | ||
| e3ce952cbc | |||
| cc8757b61e | |||
| c26be92734 | |||
| b2a1cc2da8 | |||
| 24266789e8 | |||
| 48ae689a34 | |||
| d5f40cad2f | |||
| 8f7d8839bf | |||
|
|
88c2817f7e | ||
|
|
cd64a2ee53 | ||
|
|
0d742be81d | ||
|
|
59e9499d92 | ||
|
|
3cec6983b8 | ||
|
|
75ce1575fc | ||
|
|
547359ecf3 | ||
|
|
34c4f1c727 | ||
|
|
66b270fc17 | ||
|
|
8960dac951 | ||
| 8a8407d86e | |||
|
|
9c1723cb0e | ||
|
|
95cb8772ea | ||
| 5f69c780a9 | |||
| 7f785cb0c3 | |||
| 3d75bb23c5 | |||
| d61e47f900 | |||
|
|
64dc7c776a | ||
| 03af05a8e9 | |||
| e56f573d9c | |||
| 627fe525fa | |||
|
|
2c85125338 | ||
|
|
5a6f8e207e | ||
|
|
95cfafcad2 | ||
|
|
90aea58d71 | ||
| 7a94fcf360 | |||
|
|
f370642354 | ||
|
|
fb2f80faba | ||
|
|
fd77deb494 | ||
|
|
11889dac61 | ||
|
|
f230fb823b | ||
|
|
54fadfbe8d | ||
|
|
2dfeab36d0 | ||
|
|
dac2fa74c1 | ||
| 95fa96228d | |||
| ab268e6584 | |||
|
|
519c292a1f | ||
|
|
97c0c9d754 | ||
| df59de177a | |||
| aed2cc4d88 | |||
|
|
f509c53836 | ||
|
|
a58bd055b5 | ||
|
|
2bbab92246 | ||
|
|
8f3f572c28 | ||
|
|
3502efc7f6 | ||
|
|
df4adb8435 | ||
|
|
6f5e012cb6 | ||
|
|
4b47abfbbe | ||
|
|
e24e6e5bca | ||
|
|
2efb4f141c | ||
| f57aef5f4f | |||
| c24b460a0d | |||
| 4df972c7a4 | |||
|
|
02a6c3bf6a | ||
|
|
1932443a20 | ||
|
|
8c76d5a486 | ||
|
|
c49d63be98 | ||
|
|
195e2682f9 | ||
|
|
2ba7088290 | ||
|
|
eba14dc2b7 | ||
|
|
1142c6d48d | ||
|
|
c334ef99c6 | ||
|
|
9826af9b45 | ||
|
|
9e7e890d5b | ||
|
|
29615ed47d | ||
|
|
58e5d09099 | ||
|
|
d99652b059 | ||
|
|
a57d58c02c | ||
|
|
8bf4bb1f32 | ||
|
|
69c44d53c0 | ||
|
|
170d88b247 | ||
|
|
90a7bfe38d | ||
|
|
b053274226 | ||
|
|
3f4eb82273 | ||
|
|
4bb72c63b2 | ||
|
|
8043d1fcf3 | ||
|
|
6a16010d17 | ||
| 636e80f54b | |||
| 94e2360701 | |||
|
|
f3ac65f897 | ||
|
|
c7ca6f5702 | ||
|
|
0bfe470349 | ||
|
|
fe24bb48c7 | ||
|
|
022c5637a7 | ||
|
|
1b448c3838 | ||
|
|
f1204f686a | ||
| 2076ea663c | |||
| 05fbbc9414 | |||
| 784ea17c7d | |||
| 251b55dba5 | |||
|
|
d13fe67b37 | ||
|
|
8d2406037b | ||
|
|
eb36214ffa | ||
|
|
374eadd526 | ||
|
|
aec3da98d1 | ||
|
|
db8331afcd | ||
|
|
3ba4701df8 | ||
|
|
7412bdc404 | ||
|
|
f9c4dc9bbe | ||
|
|
59de2e54c5 | ||
|
|
6072ebdcf8 | ||
|
|
7b85b5f85d | ||
|
|
ea63866481 | ||
|
|
cd3b6b4ec3 | ||
| f9e8bd1dd1 | |||
| bb52c57c3c | |||
| dc9f407450 | |||
| 26a40aac70 | |||
| 9593bb0223 | |||
| e212f4021a | |||
| df8266fc40 | |||
| 3cd0f8dce8 | |||
| 5c6f0c8bfc | |||
| b9be604f0d | |||
| 94aeca2ca1 | |||
| a8c14d65c0 | |||
| 6a9b686a09 | |||
| efed817610 | |||
| af6f4c07fa | |||
| 9e8ca9140f | |||
| 99a327f4ed | |||
| af23a06c50 | |||
| b613db1386 | |||
| b6e5b8b6e4 | |||
| 1b49c54822 | |||
| d4be7d0566 | |||
| bf463b6e7b | |||
| 138ae6fb5f | |||
| 98cb5023ec | |||
| 8ec931278b | |||
| 217616db7c | |||
| c3819457e5 | |||
| 0dbddbf1d2 | |||
| 4c0aecdf73 | |||
| 488c79d825 | |||
| c297286782 | |||
| 125e878103 | |||
| dd1116bf63 | |||
| 64cabd912b | |||
| 44557b66c6 | |||
| 2004ba4b30 | |||
| 64238dc010 | |||
| 9ffed42e1a | |||
| c09eb42245 | |||
| 575df473be | |||
| fe43811aca | |||
| bda33e1c8a | |||
| d56d1d1851 | |||
| 9560e4991c | |||
| 72f1148a64 | |||
| 7936052279 | |||
| 554103781a | |||
| 270b8cac3e | |||
| 571cfc1d0c | |||
| db28476067 | |||
| 3031f7196d | |||
| fce33f1e35 | |||
| 0c1e9ebec8 | |||
| 841f3b41ae | |||
| 3fba8c00b7 | |||
| 9b43b02543 | |||
| 41f9e67546 | |||
| 57bde835a1 | |||
|
|
eb764da56f | ||
|
|
efb0636312 | ||
|
|
e91e016f32 | ||
| fb605ca2d9 | |||
| 6a19401083 | |||
| 7db3b4d48f | |||
| 3f5f9ddb87 | |||
| 8f4294783b | |||
| c659b7ce09 | |||
| 5b435f1cad | |||
| cc84215d73 | |||
| 1be6200c58 | |||
| cf6353112a | |||
| 013acc7a98 | |||
| 0988657c91 | |||
| 223687cacb | |||
| a0d72dd36f | |||
| 9afce46cf0 | |||
| 0c0c5e82bc | |||
| 26d56f3e88 | |||
| 688c70f3f7 | |||
| 2b17cef71a | |||
| 127332d6c8 | |||
| 6c98288690 | |||
| 6b81c67b76 | |||
| 488cdbcaef | |||
| f8d13dcc92 | |||
| da5de9ecf7 | |||
| ff2a221bfa | |||
| 942fd82ca0 | |||
| 6e6eb6b8f6 | |||
| e1618da170 | |||
| b51d020704 | |||
| 2322c04ca3 | |||
| 7b04f6592c | |||
| d2c8986d51 | |||
| 0ecbde3fd7 | |||
| 066d5a1a81 | |||
| e358b0e419 | |||
| 9ed52d30d6 | |||
| dc3b180e5b | |||
| cde27fdcc2 | |||
| d560325a72 | |||
| ff9af1e46c | |||
| 1652339295 | |||
| 16b8a227fc | |||
| 9b7eb40cfc | |||
| 1c4d7554e2 | |||
| 0f610d5a81 | |||
| 62b28315b3 | |||
| 313020e468 | |||
| e27a0e9511 | |||
| f79939413b | |||
| 75c916b0b6 | |||
| 984cc46224 | |||
| 3f875f1dfc | |||
| bef03f1271 | |||
| 4be8a8036c | |||
| 2ff26a8e2b | |||
| c3765f9729 | |||
| 5931b1476b | |||
| 972f4ef41d | |||
| 4412990dac | |||
| b27ff00c16 | |||
| 019a91b5fe | |||
| 45ce141d9e | |||
| 4a4398ed84 | |||
| 5b3c9a2d2a | |||
| 12ecacd649 | |||
| 912424efb0 | |||
| 32c94d62a4 | |||
| 0bd526d30a | |||
| 105a70d6c2 | |||
| e60b3a0fcb | |||
| ea9e157abd | |||
| 1e3d6f3752 | |||
| ba069d56fd | |||
| 7ad077d0cf | |||
| 549d284c54 | |||
| 459660c35a | |||
| fc50ebb3d5 | |||
| b2ef1e5cce | |||
| c7f5de4974 | |||
| 16ca4ecbb6 | |||
| c87c117c94 | |||
| 2c28feacb5 | |||
| 7ea59cddb1 | |||
| cd39da1df4 | |||
| 094528b1b8 | |||
| fb752da740 | |||
| a2f986e666 | |||
| e4a2fefabc | |||
| d0ac4e3b84 | |||
| 743bd7f19c | |||
| cec14841f7 | |||
| 77cbcd0dcb | |||
| 926951e268 | |||
| e142513083 | |||
| bc5aec6da8 | |||
| 9100057ae2 | |||
| 67be15157c | |||
| dccd845a3d | |||
| 8fcb6a42d3 | |||
| 79168466bc | |||
| ef85aea1c5 | |||
| a42ea8d0f3 | |||
| fa96e2cf3e | |||
| 4393c59ab7 | |||
| 9b7e4f1c6d | |||
| 1b0b0e22c2 | |||
| f2611e3f05 | |||
| db6fb95dad | |||
| e269c16521 | |||
| 3c49701873 | |||
| 8dbd0a764e | |||
| 6aa00b360b | |||
| efb522d842 | |||
| 68f26c6c9f | |||
| 5002077d9a | |||
| e7e83b9597 | |||
| 39ea821fee | |||
| 0d4322c2b3 | |||
| 446bd0111c | |||
| 8c74ca9553 | |||
|
|
1f12af2a68 | ||
|
|
a7de6c7bd6 | ||
|
|
daf0e8f4a3 | ||
|
|
4ca12b19da | ||
|
|
2415feaca3 | ||
|
|
ad4e8b7e41 | ||
|
|
88524047ff | ||
| 675dd6594a | |||
| 756eb88d26 | |||
| fe2bb8efa1 | |||
| 3376fecd12 | |||
| 6871d6952f | |||
| 45696f2d19 | |||
| 7d7cb0eee0 | |||
| 4480c00cb7 | |||
| f120e7a374 | |||
| 27b348d10a | |||
| ae76557adf | |||
|
|
6a65019bfa | ||
| 8fd06a729c | |||
| 191b2fc319 |
10
Directory.Build.props
Normal file
10
Directory.Build.props
Normal file
@@ -0,0 +1,10 @@
|
||||
<Project>
|
||||
<PropertyGroup>
|
||||
<PackageProjectUrl>https://git.pilzinsel64.de/pilz-framework</PackageProjectUrl>
|
||||
<PackageLicenseExpression>MIT</PackageLicenseExpression>
|
||||
<GenerateSerializationAssemblies>False</GenerateSerializationAssemblies>
|
||||
<GeneratePackageOnBuild>True</GeneratePackageOnBuild>
|
||||
<GenerateDocumentationFile>True</GenerateDocumentationFile>
|
||||
<NoWarn>1591</NoWarn>
|
||||
</PropertyGroup>
|
||||
</Project>
|
||||
@@ -1,6 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<configuration>
|
||||
<startup>
|
||||
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.7.2"/>
|
||||
</startup>
|
||||
</configuration>
|
||||
13
Pilz.Collections/My Project/Application.Designer.vb
generated
13
Pilz.Collections/My Project/Application.Designer.vb
generated
@@ -1,13 +0,0 @@
|
||||
'------------------------------------------------------------------------------
|
||||
' <auto-generated>
|
||||
' Dieser Code wurde von einem Tool generiert.
|
||||
' Laufzeitversion:4.0.30319.42000
|
||||
'
|
||||
' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
|
||||
' der Code erneut generiert wird.
|
||||
' </auto-generated>
|
||||
'------------------------------------------------------------------------------
|
||||
|
||||
Option Strict On
|
||||
Option Explicit On
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<MyApplicationData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<MySubMain>true</MySubMain>
|
||||
<MainForm>Form1</MainForm>
|
||||
<SingleInstance>false</SingleInstance>
|
||||
<ShutdownMode>0</ShutdownMode>
|
||||
<EnableVisualStyles>true</EnableVisualStyles>
|
||||
<AuthenticationMode>0</AuthenticationMode>
|
||||
<ApplicationType>0</ApplicationType>
|
||||
<SaveMySettingsOnExit>true</SaveMySettingsOnExit>
|
||||
</MyApplicationData>
|
||||
63
Pilz.Collections/My Project/Resources.Designer.vb
generated
63
Pilz.Collections/My Project/Resources.Designer.vb
generated
@@ -1,63 +0,0 @@
|
||||
'------------------------------------------------------------------------------
|
||||
' <auto-generated>
|
||||
' Dieser Code wurde von einem Tool generiert.
|
||||
' Laufzeitversion:4.0.30319.42000
|
||||
'
|
||||
' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
|
||||
' der Code erneut generiert wird.
|
||||
' </auto-generated>
|
||||
'------------------------------------------------------------------------------
|
||||
|
||||
Option Strict On
|
||||
Option Explicit On
|
||||
|
||||
Imports System
|
||||
|
||||
Namespace My.Resources
|
||||
|
||||
'Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
|
||||
'-Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
|
||||
'Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
|
||||
'mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
|
||||
'''<summary>
|
||||
''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
|
||||
'''</summary>
|
||||
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0"), _
|
||||
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
|
||||
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
|
||||
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
|
||||
Friend Module Resources
|
||||
|
||||
Private resourceMan As Global.System.Resources.ResourceManager
|
||||
|
||||
Private resourceCulture As Global.System.Globalization.CultureInfo
|
||||
|
||||
'''<summary>
|
||||
''' Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
|
||||
'''</summary>
|
||||
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||
Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
|
||||
Get
|
||||
If Object.ReferenceEquals(resourceMan, Nothing) Then
|
||||
Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("Pilz.Collections.Resources", GetType(Resources).Assembly)
|
||||
resourceMan = temp
|
||||
End If
|
||||
Return resourceMan
|
||||
End Get
|
||||
End Property
|
||||
|
||||
'''<summary>
|
||||
''' Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
|
||||
''' Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
|
||||
'''</summary>
|
||||
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||
Friend Property Culture() As Global.System.Globalization.CultureInfo
|
||||
Get
|
||||
Return resourceCulture
|
||||
End Get
|
||||
Set
|
||||
resourceCulture = value
|
||||
End Set
|
||||
End Property
|
||||
End Module
|
||||
End Namespace
|
||||
16
Pilz.Collections/Pilz.Collections.csproj
Normal file
16
Pilz.Collections/Pilz.Collections.csproj
Normal file
@@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
|
||||
<StartupObject />
|
||||
<TargetFrameworks>net8.0</TargetFrameworks>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<Version>2.1.1</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,86 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<StartupObject />
|
||||
<MyType>Windows</MyType>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<DocumentationFile>Pilz.Collections.xml</DocumentationFile>
|
||||
<DefineTrace>true</DefineTrace>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DefineDebug>true</DefineDebug>
|
||||
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022,40008</NoWarn>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DefineDebug>false</DefineDebug>
|
||||
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||
<RemoveIntegerChecks>true</RemoveIntegerChecks>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<OptionExplicit>On</OptionExplicit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<OptionCompare>Binary</OptionCompare>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<OptionStrict>Off</OptionStrict>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<OptionInfer>On</OptionInfer>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Debug|x86'">
|
||||
<DefineDebug>true</DefineDebug>
|
||||
<OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
|
||||
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022,40008</NoWarn>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
<UseVSHostingProcess>true</UseVSHostingProcess>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)' == 'Release|x86'">
|
||||
<OutputPath>bin\$(Platform)\$(Configuration)\</OutputPath>
|
||||
<RemoveIntegerChecks>true</RemoveIntegerChecks>
|
||||
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||
<CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
|
||||
<PackageReference Include="System.Net.Http" Version="4.3.4" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Import Include="Microsoft.VisualBasic" />
|
||||
<Import Include="System" />
|
||||
<Import Include="System.Collections" />
|
||||
<Import Include="System.Collections.Generic" />
|
||||
<Import Include="System.Data" />
|
||||
<Import Include="System.Drawing" />
|
||||
<Import Include="System.Linq" />
|
||||
<Import Include="System.Xml.Linq" />
|
||||
<Import Include="System.Threading.Tasks" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Update="My Project\Application.Designer.vb">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Application.myapp</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="My Project\Resources.Designer.vb">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="My Project\Resources.resx">
|
||||
<Generator>VbMyResourcesResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.vb</LastGenOutput>
|
||||
<CustomToolNamespace>My.Resources</CustomToolNamespace>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="My Project\Application.myapp">
|
||||
<Generator>MyApplicationCodeGenerator</Generator>
|
||||
<LastGenOutput>Application.Designer.vb</LastGenOutput>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Remove="SimpleHistory\Enums.vb" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
@@ -1,12 +0,0 @@
|
||||
Namespace SimpleHistory
|
||||
|
||||
''' <summary>
|
||||
''' Specify which member types you would include.
|
||||
''' </summary>
|
||||
Public Enum ObjectValueType
|
||||
None = 0
|
||||
Field = 1
|
||||
[Property] = 2
|
||||
End Enum
|
||||
|
||||
End Namespace
|
||||
615
Pilz.Collections/SimpleHistory/HistoryPoint.cs
Normal file
615
Pilz.Collections/SimpleHistory/HistoryPoint.cs
Normal file
@@ -0,0 +1,615 @@
|
||||
using System.Data;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Pilz.Collections.SimpleHistory;
|
||||
|
||||
/// <summary>
|
||||
/// Represent some Object States and Actions.
|
||||
/// </summary>
|
||||
public class HistoryPoint
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents the Name of this History Point
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string Name { get; set; } = string.Empty;
|
||||
|
||||
/// <summary>
|
||||
/// A List of Object States and Actions.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public List<ObjectBase> Entries { get; } = [];
|
||||
|
||||
/// <summary>
|
||||
/// Some data can be refered on this HistoryPoint. Don't know, in some situations this can be helpful.
|
||||
/// </summary>
|
||||
public readonly object? Tag = null;
|
||||
|
||||
public bool HasEntries<T>() where T : ObjectBase
|
||||
{
|
||||
return Entries.Where(n => n is T).Any();
|
||||
}
|
||||
|
||||
internal void Undo()
|
||||
{
|
||||
foreach (var s in Entries.OrderBy(n => n.UndoPriority))
|
||||
{
|
||||
switch (s)
|
||||
{
|
||||
case ObjectState state:
|
||||
state.Patch();
|
||||
break;
|
||||
case ObjectAction action:
|
||||
action.Undo();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal void Redo()
|
||||
{
|
||||
foreach (var s in Entries.OrderBy(n => n.RedoPriority))
|
||||
{
|
||||
switch (s)
|
||||
{
|
||||
case ObjectState state:
|
||||
state.Patch();
|
||||
break;
|
||||
case ObjectAction action:
|
||||
action.Redo();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="obj">The objects that should be included.</param>
|
||||
/// <param name="whiteList">Specify which members to include.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object[] obj, MemberWhiteList whiteList)
|
||||
{
|
||||
return FromObject([obj], ObjectValueType.None, (object)whiteList, BindingFlags.Default);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="obj">The objects that should be included.</param>
|
||||
/// <param name="blackList">Specify which members to exclude.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object[] obj, MemberBlackList blackList)
|
||||
{
|
||||
return FromObject([obj], ObjectValueType.None, (object)blackList, BindingFlags.Default);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="obj">The objects that should be included.</param>
|
||||
/// <param name="memberName">The member names to include.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object[] obj, params string[] memberName)
|
||||
{
|
||||
return FromObject(obj, true, memberName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="obj">The objects that should be included.</param>
|
||||
/// <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
|
||||
/// <param name="memberName">The member names to include/exclude.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object[] obj, bool isWhiteList, params string[] memberName)
|
||||
{
|
||||
if (isWhiteList)
|
||||
return FromObject([obj], ObjectValueType.None, (object)new MemberWhiteList(memberName), BindingFlags.Default);
|
||||
else
|
||||
return FromObject([obj], ObjectValueType.None, (object)new MemberBlackList(memberName), BindingFlags.Default);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="obj">The objects that should be included.</param>
|
||||
/// <param name="membersToStore">Specify what member types to include.</param>
|
||||
/// <param name="memberName">The member names to include.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object[] obj, ObjectValueType membersToStore, params string[] memberName)
|
||||
{
|
||||
return FromObject(obj, membersToStore, true, memberName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="obj">The objects that should be included.</param>
|
||||
/// <param name="membersToStore">Specify what member types to include.</param>
|
||||
/// <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
|
||||
/// <param name="memberName">The member names to include/exclude.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object[] obj, ObjectValueType membersToStore, bool isWhiteList, params string[] memberName)
|
||||
{
|
||||
if (isWhiteList)
|
||||
return FromObject([obj], membersToStore, (object)new MemberWhiteList(memberName), BindingFlags.Default);
|
||||
else
|
||||
return FromObject([obj], membersToStore, (object)new MemberBlackList(memberName), BindingFlags.Default);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="obj">The objects that should be included.</param>
|
||||
/// <param name="flags">The Binding Flags that the members should have.</param>
|
||||
/// <param name="memberName">The member names to include.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object[] obj, BindingFlags flags, params string[] memberName)
|
||||
{
|
||||
return FromObject(obj, flags, true, memberName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="obj">The objects that should be included.</param>
|
||||
/// <param name="flags">The Binding Flags that the members should have.</param>
|
||||
/// <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
|
||||
/// <param name="memberName">The member names to include/exclude.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object[] obj, BindingFlags flags, bool isWhiteList, params string[] memberName)
|
||||
{
|
||||
if (isWhiteList)
|
||||
return FromObject([obj], ObjectValueType.None, (object)new MemberWhiteList(memberName), flags);
|
||||
else
|
||||
return FromObject([obj], ObjectValueType.None, (object)new MemberBlackList(memberName), flags);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="obj">The objects that should be included.</param>
|
||||
/// <param name="membersToStore">Specify what member types to include.</param>
|
||||
/// <param name="flags">The Binding Flags that the members should have.</param>
|
||||
/// <param name="memberName">The member names to include.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object[] obj, ObjectValueType membersToStore, BindingFlags flags, params string[] memberName)
|
||||
{
|
||||
return FromObject(obj, flags, true, memberName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="obj">The objects that should be included.</param>
|
||||
/// <param name="membersToStore">Specify what member types to include.</param>
|
||||
/// <param name="flags">The Binding Flags that the members should have.</param>
|
||||
/// <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
|
||||
/// <param name="memberName">The member names to include/exclude.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object[] obj, ObjectValueType membersToStore, BindingFlags flags, bool isWhiteList, params string[] memberName)
|
||||
{
|
||||
if (isWhiteList)
|
||||
return FromObject([obj], membersToStore, (object)new MemberWhiteList(memberName), flags);
|
||||
else
|
||||
return FromObject([obj], membersToStore, (object)new MemberBlackList(memberName), flags);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object that should be included.</param>
|
||||
/// <param name="whiteList">Specify which members to include.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object obj, MemberWhiteList whiteList)
|
||||
{
|
||||
return FromObject([obj], ObjectValueType.None, (object)whiteList, BindingFlags.Default);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object that should be included.</param>
|
||||
/// <param name="blackList">Specify which members to exclude.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object obj, MemberBlackList blackList)
|
||||
{
|
||||
return FromObject([obj], ObjectValueType.None, (object)blackList, BindingFlags.Default);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object that should be included.</param>
|
||||
/// <param name="memberName">The member names to include/exclude.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object obj, params string[] memberName)
|
||||
{
|
||||
return FromObject(obj, true, memberName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object that should be included.</param>
|
||||
/// <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
|
||||
/// <param name="memberName">The member names to include/exclude.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object obj, bool isWhiteList, params string[] memberName)
|
||||
{
|
||||
if (isWhiteList)
|
||||
return FromObject([obj], ObjectValueType.None, (object)new MemberWhiteList(memberName), BindingFlags.Default);
|
||||
else
|
||||
return FromObject([obj], ObjectValueType.None, (object)new MemberBlackList(memberName), BindingFlags.Default);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object that should be included.</param>
|
||||
/// <param name="membersToStore">Specify what member types to include.</param>
|
||||
/// <param name="memberName">The member names to include.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object obj, ObjectValueType membersToStore, params string[] memberName)
|
||||
{
|
||||
return FromObject(obj, membersToStore, true, memberName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object that should be included.</param>
|
||||
/// <param name="membersToStore">Specify what member types to include.</param>
|
||||
/// <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
|
||||
/// <param name="memberName">The member names to include/exclude.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object obj, ObjectValueType membersToStore, bool isWhiteList, params string[] memberName)
|
||||
{
|
||||
if (isWhiteList)
|
||||
return FromObject([obj], membersToStore, (object)new MemberWhiteList(memberName), BindingFlags.Default);
|
||||
else
|
||||
return FromObject([obj], membersToStore, (object)new MemberBlackList(memberName), BindingFlags.Default);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object that should be included.</param>
|
||||
/// <param name="flags">The Binding Flags that the members should have.</param>
|
||||
/// <param name="memberName">The member names to include.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object obj, BindingFlags flags, params string[] memberName)
|
||||
{
|
||||
return FromObject(obj, flags, true, memberName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object that should be included.</param>
|
||||
/// <param name="flags">The Binding Flags that the members should have.</param>
|
||||
/// <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
|
||||
/// <param name="memberName">The member names to include/exclude.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object obj, BindingFlags flags, bool isWhiteList, params string[] memberName)
|
||||
{
|
||||
if (isWhiteList)
|
||||
return FromObject([obj], ObjectValueType.None, (object)new MemberWhiteList(memberName), flags);
|
||||
else
|
||||
return FromObject([obj], ObjectValueType.None, (object)new MemberBlackList(memberName), flags);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object that should be included.</param>
|
||||
/// <param name="membersToStore">Specify what member types to include.</param>
|
||||
/// <param name="flags">The Binding Flags that the members should have.</param>
|
||||
/// <param name="memberName">The member names to include.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object obj, ObjectValueType membersToStore, BindingFlags flags, params string[] memberName)
|
||||
{
|
||||
return FromObject(obj, flags, true, memberName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object that should be included.</param>
|
||||
/// <param name="membersToStore">Specify what member types to include.</param>
|
||||
/// <param name="flags">The Binding Flags that the members should have.</param>
|
||||
/// <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
|
||||
/// <param name="memberName">The member names to include/exclude.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object obj, ObjectValueType membersToStore, BindingFlags flags, bool isWhiteList, params string[] memberName)
|
||||
{
|
||||
if (isWhiteList)
|
||||
return FromObject([obj], membersToStore, (object)new MemberWhiteList(memberName), flags);
|
||||
else
|
||||
return FromObject([obj], membersToStore, (object)new MemberBlackList(memberName), flags);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object that should be included.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object obj)
|
||||
{
|
||||
return FromObject([obj], ObjectValueType.None, default(object), BindingFlags.Default);
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object that should be included.</param>
|
||||
/// <param name="membersToStore">Specify what member types to include.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object obj, ObjectValueType membersToStore)
|
||||
{
|
||||
return FromObject([obj], membersToStore, default(object), BindingFlags.Default);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object that should be included.</param>
|
||||
/// <param name="membersToStore">Specify what member types to include.</param>
|
||||
/// <param name="whiteList">Specify which members to include.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object obj, ObjectValueType membersToStore, MemberWhiteList whiteList)
|
||||
{
|
||||
return FromObject([obj], membersToStore, (object)whiteList, BindingFlags.Default);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object that should be included.</param>
|
||||
/// <param name="membersToStore">Specify what member types to include.</param>
|
||||
/// <param name="blackList">Specify which members to exclude.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object obj, ObjectValueType membersToStore, MemberBlackList blackList)
|
||||
{
|
||||
return FromObject([obj], membersToStore, (object)blackList, BindingFlags.Default);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object that should be included.</param>
|
||||
/// <param name="flags">The Binding Flags that the members should have.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object obj, BindingFlags flags)
|
||||
{
|
||||
return FromObject([obj], ObjectValueType.None, default(object), flags);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object that should be included.</param>
|
||||
/// <param name="membersToStore">Specify what member types to include.</param>
|
||||
/// <param name="flags">The Binding Flags that the members should have.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object obj, ObjectValueType membersToStore, BindingFlags flags)
|
||||
{
|
||||
return FromObject([obj], membersToStore, default(object), flags);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object that should be included.</param>
|
||||
/// <param name="membersToStore">Specify what member types to include.</param>
|
||||
/// <param name="whiteList">Specify which members to include.</param>
|
||||
/// <param name="flags">The Binding Flags that the members should have.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object obj, ObjectValueType membersToStore, MemberWhiteList whiteList, BindingFlags flags)
|
||||
{
|
||||
return FromObject([obj], membersToStore, (object)whiteList, flags);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="obj">The object that should be included.</param>
|
||||
/// <param name="membersToStore">Specify what member types to include.</param>
|
||||
/// <param name="blackList">Specify which members to exclude.</param>
|
||||
/// <param name="flags">The Binding Flags that the members should have.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object obj, ObjectValueType membersToStore, MemberBlackList blackList, BindingFlags flags)
|
||||
{
|
||||
return FromObject([obj], membersToStore, (object)blackList, flags);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="objs">The objects that should be included.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object[] objs)
|
||||
{
|
||||
return FromObject(objs, ObjectValueType.None, default(object), BindingFlags.Default);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="objs">The objects that should be included.</param>
|
||||
/// <param name="membersToStore">Specify what member types to include.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object[] objs, ObjectValueType membersToStore)
|
||||
{
|
||||
return FromObject(objs, membersToStore, default(object), BindingFlags.Default);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="objs">The objects that should be included.</param>
|
||||
/// <param name="membersToStore">Specify what member types to include.</param>
|
||||
/// <param name="whiteList">Specify which members to include.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object[] objs, ObjectValueType membersToStore, MemberWhiteList whiteList)
|
||||
{
|
||||
return FromObject(objs, membersToStore, (object)whiteList, BindingFlags.Default);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="objs">The objects that should be included.</param>
|
||||
/// <param name="membersToStore">Specify what member types to include.</param>
|
||||
/// <param name="blackList">Specify which members to exclude.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object[] objs, ObjectValueType membersToStore, MemberBlackList blackList)
|
||||
{
|
||||
return FromObject(objs, membersToStore, (object)blackList, BindingFlags.Default);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="objs">The objects that should be included.</param>
|
||||
/// <param name="flags">The Binding Flags that the members should have.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object[] objs, BindingFlags flags)
|
||||
{
|
||||
return FromObject(objs, ObjectValueType.None, default(object), flags);
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="objs">The objects that should be included.</param>
|
||||
/// <param name="membersToStore">Specify what member types to include.</param>
|
||||
/// <param name="flags">The Binding Flags that the members should have.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object[] objs, ObjectValueType membersToStore, BindingFlags flags)
|
||||
{
|
||||
return FromObject(objs, membersToStore, default(object), flags);
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="objs">The objects that should be included.</param>
|
||||
/// <param name="membersToStore">Specify what member types to include.</param>
|
||||
/// <param name="whiteList">Specify which members to include.</param>
|
||||
/// <param name="flags">The Binding Flags that the members should have.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object[] objs, ObjectValueType membersToStore, MemberWhiteList whiteList, BindingFlags flags)
|
||||
{
|
||||
return FromObject(objs, membersToStore, (object)whiteList, flags);
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="objs">The objects that should be included.</param>
|
||||
/// <param name="membersToStore">Specify what member types to include.</param>
|
||||
/// <param name="blackList">Specify which members to exclude.</param>
|
||||
/// <param name="flags">The Binding Flags that the members should have.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
public static HistoryPoint FromObject(object[] objs, ObjectValueType membersToStore, MemberBlackList blackList, BindingFlags flags)
|
||||
{
|
||||
return FromObject(objs, membersToStore, (object)blackList, flags);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates an History Point with Object States automaticly from input.
|
||||
/// </summary>
|
||||
/// <param name="objs">The objects that should be included.</param>
|
||||
/// <param name="membersToStore">Specify what member types to include.</param>
|
||||
/// <param name="whiteOrBlackList">Specify which members to include.</param>
|
||||
/// <param name="flags">The Binding Flags that the members should have.</param>
|
||||
/// <returns>A History Point with Object States.</returns>
|
||||
private static HistoryPoint FromObject(object[] objs, ObjectValueType membersToStore, object? whiteOrBlackList, BindingFlags flags)
|
||||
{
|
||||
var hp = new HistoryPoint();
|
||||
|
||||
whiteOrBlackList ??= new MemberBlackList();
|
||||
var isWhiteList = whiteOrBlackList is MemberWhiteList;
|
||||
|
||||
if (flags == BindingFlags.Default)
|
||||
flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
|
||||
|
||||
if (membersToStore == ObjectValueType.None)
|
||||
membersToStore = ObjectValueType.Field | ObjectValueType.Property;
|
||||
|
||||
foreach (var obj in objs)
|
||||
{
|
||||
if ((membersToStore & ObjectValueType.Field) == ObjectValueType.Field)
|
||||
{
|
||||
foreach (var fi in obj.GetType().GetFields(flags))
|
||||
{
|
||||
var contains = ((List<string>)whiteOrBlackList).Contains(fi.Name);
|
||||
if (isWhiteList ? contains : !contains)
|
||||
{
|
||||
var os = new ObjectState
|
||||
{
|
||||
Object = obj,
|
||||
MemberName = fi.Name,
|
||||
MemberType = ObjectValueType.Field,
|
||||
MemberFlags = flags,
|
||||
ValueToPatch = fi.GetValue(obj)
|
||||
};
|
||||
hp.Entries.Add(os);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if ((membersToStore & ObjectValueType.Property) == ObjectValueType.Property)
|
||||
{
|
||||
foreach (var pi in obj.GetType().GetProperties(flags))
|
||||
{
|
||||
var contains = ((List<string>)whiteOrBlackList).Contains(pi.Name);
|
||||
if (isWhiteList ? contains : !contains)
|
||||
{
|
||||
var os = new ObjectState
|
||||
{
|
||||
Object = obj,
|
||||
MemberName = pi.Name,
|
||||
MemberType = ObjectValueType.Property,
|
||||
MemberFlags = flags,
|
||||
ValueToPatch = pi.GetValue(obj)
|
||||
};
|
||||
hp.Entries.Add(os);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return hp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Combines some History Points to one.
|
||||
/// </summary>
|
||||
/// <param name="hps">An array of History Points to combine.</param>
|
||||
/// <returns>One History Point that contains all Data of inputted History Points.</returns>
|
||||
public static HistoryPoint Concat(params HistoryPoint[] hps)
|
||||
{
|
||||
return Concat(null, hps);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Combines some History Points to one.
|
||||
/// </summary>
|
||||
/// <param name="hps">An array of History Points to combine.</param>
|
||||
/// <param name="newName">The new name for the History Point after concating.</param>
|
||||
/// <returns>One History Point that contains all Data of inputted History Points.</returns>
|
||||
public static HistoryPoint Concat(string? newName, params HistoryPoint[] hps)
|
||||
{
|
||||
var hp = new HistoryPoint();
|
||||
|
||||
foreach (var _hp in hps)
|
||||
hp.Entries.AddRange(_hp.Entries);
|
||||
|
||||
if (newName != null)
|
||||
hp.Name = newName;
|
||||
else
|
||||
hp.Name = hps.FirstOrDefault()?.Name ?? string.Empty;
|
||||
|
||||
return hp;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,543 +0,0 @@
|
||||
Imports System.Reflection
|
||||
|
||||
Namespace SimpleHistory
|
||||
|
||||
''' <summary>
|
||||
''' Represent some Object States and Actions.
|
||||
''' </summary>
|
||||
Public Class HistoryPoint
|
||||
|
||||
''' <summary>
|
||||
''' Represents the Name of this History Point
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Property Name As String = ""
|
||||
''' <summary>
|
||||
''' A List of Object States and Actions.
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public ReadOnly Property Entries As New List(Of ObjectBase)
|
||||
''' <summary>
|
||||
''' Some data can be refered on this HistoryPoint. Don't know, in some situations this can be helpful.
|
||||
''' </summary>
|
||||
Public ReadOnly Tag As Object = Nothing
|
||||
|
||||
Public Function HasEntries(Of T As ObjectBase)() As Boolean
|
||||
Return Entries.Where(Function(n) TypeOf n Is T).Count > 0
|
||||
End Function
|
||||
|
||||
Friend Sub Undo()
|
||||
For Each s As ObjectBase In Entries.OrderBy(Function(n) n.UndoPriority)
|
||||
If TypeOf s Is ObjectState Then
|
||||
CType(s, ObjectState).Patch()
|
||||
ElseIf TypeOf s Is ObjectAction Then
|
||||
CType(s, ObjectAction).Undo()
|
||||
End If
|
||||
Next
|
||||
End Sub
|
||||
|
||||
Friend Sub Redo()
|
||||
For Each s As ObjectBase In Entries.OrderBy(Function(n) n.RedoPriority)
|
||||
If TypeOf s Is ObjectState Then
|
||||
CType(s, ObjectState).Patch()
|
||||
ElseIf TypeOf s Is ObjectAction Then
|
||||
CType(s, ObjectAction).Redo()
|
||||
End If
|
||||
Next
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="obj">The objects that should be included.</param>
|
||||
''' <param name="whiteList">Specify which members to include.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(obj As Object(), whiteList As MemberWhiteList) As HistoryPoint
|
||||
Return FromObject({obj}, ObjectValueType.None, CObj(whiteList), BindingFlags.Default)
|
||||
End Function
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="obj">The objects that should be included.</param>
|
||||
''' <param name="blackList">Specify which members to exclude.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(obj As Object(), blackList As MemberBlackList) As HistoryPoint
|
||||
Return FromObject({obj}, ObjectValueType.None, CObj(blackList), BindingFlags.Default)
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="obj">The objects that should be included.</param>
|
||||
''' <param name="memberName">The member names to include.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(obj As Object(), ParamArray memberName As String()) As HistoryPoint
|
||||
Return FromObject(obj, True, memberName)
|
||||
End Function
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="obj">The objects that should be included.</param>
|
||||
''' <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
|
||||
''' <param name="memberName">The member names to include/exclude.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(obj As Object(), isWhiteList As Boolean, ParamArray memberName As String()) As HistoryPoint
|
||||
If isWhiteList Then
|
||||
Return FromObject({obj}, ObjectValueType.None, CObj(New MemberWhiteList(memberName)), BindingFlags.Default)
|
||||
Else
|
||||
Return FromObject({obj}, ObjectValueType.None, CObj(New MemberBlackList(memberName)), BindingFlags.Default)
|
||||
End If
|
||||
End Function
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="obj">The objects that should be included.</param>
|
||||
''' <param name="membersToStore">Specify what member types to include.</param>
|
||||
''' <param name="memberName">The member names to include.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(obj As Object(), membersToStore As ObjectValueType, ParamArray memberName As String()) As HistoryPoint
|
||||
Return FromObject(obj, membersToStore, True, memberName)
|
||||
End Function
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="obj">The objects that should be included.</param>
|
||||
''' <param name="membersToStore">Specify what member types to include.</param>
|
||||
''' <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
|
||||
''' <param name="memberName">The member names to include/exclude.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(obj As Object(), membersToStore As ObjectValueType, isWhiteList As Boolean, ParamArray memberName As String()) As HistoryPoint
|
||||
If isWhiteList Then
|
||||
Return FromObject({obj}, membersToStore, CObj(New MemberWhiteList(memberName)), BindingFlags.Default)
|
||||
Else
|
||||
Return FromObject({obj}, membersToStore, CObj(New MemberBlackList(memberName)), BindingFlags.Default)
|
||||
End If
|
||||
End Function
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="obj">The objects that should be included.</param>
|
||||
''' <param name="flags">The Binding Flags that the members should have.</param>
|
||||
''' <param name="memberName">The member names to include.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(obj As Object(), flags As BindingFlags, ParamArray memberName As String()) As HistoryPoint
|
||||
Return FromObject(obj, flags, True, memberName)
|
||||
End Function
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="obj">The objects that should be included.</param>
|
||||
''' <param name="flags">The Binding Flags that the members should have.</param>
|
||||
''' <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
|
||||
''' <param name="memberName">The member names to include/exclude.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(obj As Object(), flags As BindingFlags, isWhiteList As Boolean, ParamArray memberName As String()) As HistoryPoint
|
||||
If isWhiteList Then
|
||||
Return FromObject({obj}, ObjectValueType.None, CObj(New MemberWhiteList(memberName)), flags)
|
||||
Else
|
||||
Return FromObject({obj}, ObjectValueType.None, CObj(New MemberBlackList(memberName)), flags)
|
||||
End If
|
||||
End Function
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="obj">The objects that should be included.</param>
|
||||
''' <param name="membersToStore">Specify what member types to include.</param>
|
||||
''' <param name="flags">The Binding Flags that the members should have.</param>
|
||||
''' <param name="memberName">The member names to include.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(obj As Object(), membersToStore As ObjectValueType, flags As BindingFlags, ParamArray memberName As String()) As HistoryPoint
|
||||
Return FromObject(obj, flags, True, memberName)
|
||||
End Function
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="obj">The objects that should be included.</param>
|
||||
''' <param name="membersToStore">Specify what member types to include.</param>
|
||||
''' <param name="flags">The Binding Flags that the members should have.</param>
|
||||
''' <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
|
||||
''' <param name="memberName">The member names to include/exclude.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(obj As Object(), membersToStore As ObjectValueType, flags As BindingFlags, isWhiteList As Boolean, ParamArray memberName As String()) As HistoryPoint
|
||||
If isWhiteList Then
|
||||
Return FromObject({obj}, membersToStore, CObj(New MemberWhiteList(memberName)), flags)
|
||||
Else
|
||||
Return FromObject({obj}, membersToStore, CObj(New MemberBlackList(memberName)), flags)
|
||||
End If
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="obj">The object that should be included.</param>
|
||||
''' <param name="whiteList">Specify which members to include.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(obj As Object, whiteList As MemberWhiteList) As HistoryPoint
|
||||
Return FromObject({obj}, ObjectValueType.None, CObj(whiteList), BindingFlags.Default)
|
||||
End Function
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="obj">The object that should be included.</param>
|
||||
''' <param name="blackList">Specify which members to exclude.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(obj As Object, blackList As MemberBlackList) As HistoryPoint
|
||||
Return FromObject({obj}, ObjectValueType.None, CObj(blackList), BindingFlags.Default)
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="obj">The object that should be included.</param>
|
||||
''' <param name="memberName">The member names to include/exclude.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(obj As Object, ParamArray memberName As String()) As HistoryPoint
|
||||
Return FromObject(obj, True, memberName)
|
||||
End Function
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="obj">The object that should be included.</param>
|
||||
''' <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
|
||||
''' <param name="memberName">The member names to include/exclude.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(obj As Object, isWhiteList As Boolean, ParamArray memberName As String()) As HistoryPoint
|
||||
If isWhiteList Then
|
||||
Return FromObject({obj}, ObjectValueType.None, CObj(New MemberWhiteList(memberName)), BindingFlags.Default)
|
||||
Else
|
||||
Return FromObject({obj}, ObjectValueType.None, CObj(New MemberBlackList(memberName)), BindingFlags.Default)
|
||||
End If
|
||||
End Function
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="obj">The object that should be included.</param>
|
||||
''' <param name="membersToStore">Specify what member types to include.</param>
|
||||
''' <param name="memberName">The member names to include.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(obj As Object, membersToStore As ObjectValueType, ParamArray memberName As String()) As HistoryPoint
|
||||
Return FromObject(obj, membersToStore, True, memberName)
|
||||
End Function
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="obj">The object that should be included.</param>
|
||||
''' <param name="membersToStore">Specify what member types to include.</param>
|
||||
''' <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
|
||||
''' <param name="memberName">The member names to include/exclude.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(obj As Object, membersToStore As ObjectValueType, isWhiteList As Boolean, ParamArray memberName As String()) As HistoryPoint
|
||||
If isWhiteList Then
|
||||
Return FromObject({obj}, membersToStore, CObj(New MemberWhiteList(memberName)), BindingFlags.Default)
|
||||
Else
|
||||
Return FromObject({obj}, membersToStore, CObj(New MemberBlackList(memberName)), BindingFlags.Default)
|
||||
End If
|
||||
End Function
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="obj">The object that should be included.</param>
|
||||
''' <param name="flags">The Binding Flags that the members should have.</param>
|
||||
''' <param name="memberName">The member names to include.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(obj As Object, flags As BindingFlags, ParamArray memberName As String()) As HistoryPoint
|
||||
Return FromObject(obj, flags, True, memberName)
|
||||
End Function
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="obj">The object that should be included.</param>
|
||||
''' <param name="flags">The Binding Flags that the members should have.</param>
|
||||
''' <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
|
||||
''' <param name="memberName">The member names to include/exclude.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(obj As Object, flags As BindingFlags, isWhiteList As Boolean, ParamArray memberName As String()) As HistoryPoint
|
||||
If isWhiteList Then
|
||||
Return FromObject({obj}, ObjectValueType.None, CObj(New MemberWhiteList(memberName)), flags)
|
||||
Else
|
||||
Return FromObject({obj}, ObjectValueType.None, CObj(New MemberBlackList(memberName)), flags)
|
||||
End If
|
||||
End Function
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="obj">The object that should be included.</param>
|
||||
''' <param name="membersToStore">Specify what member types to include.</param>
|
||||
''' <param name="flags">The Binding Flags that the members should have.</param>
|
||||
''' <param name="memberName">The member names to include.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(obj As Object, membersToStore As ObjectValueType, flags As BindingFlags, ParamArray memberName As String()) As HistoryPoint
|
||||
Return FromObject(obj, flags, True, memberName)
|
||||
End Function
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="obj">The object that should be included.</param>
|
||||
''' <param name="membersToStore">Specify what member types to include.</param>
|
||||
''' <param name="flags">The Binding Flags that the members should have.</param>
|
||||
''' <param name="isWhiteList">If true, the memberName-Array has member names that should be included.</param>
|
||||
''' <param name="memberName">The member names to include/exclude.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(obj As Object, membersToStore As ObjectValueType, flags As BindingFlags, isWhiteList As Boolean, ParamArray memberName As String()) As HistoryPoint
|
||||
If isWhiteList Then
|
||||
Return FromObject({obj}, membersToStore, CObj(New MemberWhiteList(memberName)), flags)
|
||||
Else
|
||||
Return FromObject({obj}, membersToStore, CObj(New MemberBlackList(memberName)), flags)
|
||||
End If
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="obj">The object that should be included.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(obj As Object) As HistoryPoint
|
||||
Return FromObject({obj}, ObjectValueType.None, CObj(Nothing), BindingFlags.Default)
|
||||
End Function
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="obj">The object that should be included.</param>
|
||||
''' <param name="membersToStore">Specify what member types to include.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(obj As Object, membersToStore As ObjectValueType) As HistoryPoint
|
||||
Return FromObject({obj}, membersToStore, CObj(Nothing), BindingFlags.Default)
|
||||
End Function
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="obj">The object that should be included.</param>
|
||||
''' <param name="membersToStore">Specify what member types to include.</param>
|
||||
''' <param name="whiteList">Specify which members to include.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(obj As Object, membersToStore As ObjectValueType, whiteList As MemberWhiteList) As HistoryPoint
|
||||
Return FromObject({obj}, membersToStore, CObj(whiteList), BindingFlags.Default)
|
||||
End Function
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="obj">The object that should be included.</param>
|
||||
''' <param name="membersToStore">Specify what member types to include.</param>
|
||||
''' <param name="blackList">Specify which members to exclude.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(obj As Object, membersToStore As ObjectValueType, blackList As MemberBlackList) As HistoryPoint
|
||||
Return FromObject({obj}, membersToStore, CObj(blackList), BindingFlags.Default)
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="obj">The object that should be included.</param>
|
||||
''' <param name="flags">The Binding Flags that the members should have.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(obj As Object, flags As BindingFlags) As HistoryPoint
|
||||
Return FromObject({obj}, ObjectValueType.None, CObj(Nothing), flags)
|
||||
End Function
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="obj">The object that should be included.</param>
|
||||
''' <param name="membersToStore">Specify what member types to include.</param>
|
||||
''' <param name="flags">The Binding Flags that the members should have.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(obj As Object, membersToStore As ObjectValueType, flags As BindingFlags) As HistoryPoint
|
||||
Return FromObject({obj}, membersToStore, CObj(Nothing), flags)
|
||||
End Function
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="obj">The object that should be included.</param>
|
||||
''' <param name="membersToStore">Specify what member types to include.</param>
|
||||
''' <param name="whiteList">Specify which members to include.</param>
|
||||
''' <param name="flags">The Binding Flags that the members should have.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(obj As Object, membersToStore As ObjectValueType, whiteList As MemberWhiteList, flags As BindingFlags) As HistoryPoint
|
||||
Return FromObject({obj}, membersToStore, CObj(whiteList), flags)
|
||||
End Function
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="obj">The object that should be included.</param>
|
||||
''' <param name="membersToStore">Specify what member types to include.</param>
|
||||
''' <param name="blackList">Specify which members to exclude.</param>
|
||||
''' <param name="flags">The Binding Flags that the members should have.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(obj As Object, membersToStore As ObjectValueType, blackList As MemberBlackList, flags As BindingFlags) As HistoryPoint
|
||||
Return FromObject({obj}, membersToStore, CObj(blackList), flags)
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="objs">The objects that should be included.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(objs As Object()) As HistoryPoint
|
||||
Return FromObject(objs, ObjectValueType.None, CObj(Nothing), BindingFlags.Default)
|
||||
End Function
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="objs">The objects that should be included.</param>
|
||||
''' <param name="membersToStore">Specify what member types to include.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(objs As Object(), membersToStore As ObjectValueType) As HistoryPoint
|
||||
Return FromObject(objs, membersToStore, CObj(Nothing), BindingFlags.Default)
|
||||
End Function
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="objs">The objects that should be included.</param>
|
||||
''' <param name="membersToStore">Specify what member types to include.</param>
|
||||
''' <param name="whiteList">Specify which members to include.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(objs As Object(), membersToStore As ObjectValueType, whiteList As MemberWhiteList) As HistoryPoint
|
||||
Return FromObject(objs, membersToStore, CObj(whiteList), BindingFlags.Default)
|
||||
End Function
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="objs">The objects that should be included.</param>
|
||||
''' <param name="membersToStore">Specify what member types to include.</param>
|
||||
''' <param name="blackList">Specify which members to exclude.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(objs As Object(), membersToStore As ObjectValueType, blackList As MemberBlackList) As HistoryPoint
|
||||
Return FromObject(objs, membersToStore, CObj(blackList), BindingFlags.Default)
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="objs">The objects that should be included.</param>
|
||||
''' <param name="flags">The Binding Flags that the members should have.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(objs As Object(), flags As BindingFlags) As HistoryPoint
|
||||
Return FromObject(objs, ObjectValueType.None, CObj(Nothing), flags)
|
||||
End Function
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="objs">The objects that should be included.</param>
|
||||
''' <param name="membersToStore">Specify what member types to include.</param>
|
||||
''' <param name="flags">The Binding Flags that the members should have.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(objs As Object(), membersToStore As ObjectValueType, flags As BindingFlags) As HistoryPoint
|
||||
Return FromObject(objs, membersToStore, CObj(Nothing), flags)
|
||||
End Function
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="objs">The objects that should be included.</param>
|
||||
''' <param name="membersToStore">Specify what member types to include.</param>
|
||||
''' <param name="whiteList">Specify which members to include.</param>
|
||||
''' <param name="flags">The Binding Flags that the members should have.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(objs As Object(), membersToStore As ObjectValueType, whiteList As MemberWhiteList, flags As BindingFlags) As HistoryPoint
|
||||
Return FromObject(objs, membersToStore, CObj(whiteList), flags)
|
||||
End Function
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="objs">The objects that should be included.</param>
|
||||
''' <param name="membersToStore">Specify what member types to include.</param>
|
||||
''' <param name="blackList">Specify which members to exclude.</param>
|
||||
''' <param name="flags">The Binding Flags that the members should have.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Public Shared Function FromObject(objs As Object(), membersToStore As ObjectValueType, blackList As MemberBlackList, flags As BindingFlags) As HistoryPoint
|
||||
Return FromObject(objs, membersToStore, CObj(blackList), flags)
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Creates an History Point with Object States automaticly from input.
|
||||
''' </summary>
|
||||
''' <param name="objs">The objects that should be included.</param>
|
||||
''' <param name="membersToStore">Specify what member types to include.</param>
|
||||
''' <param name="whiteOrBlackList">Specify which members to include.</param>
|
||||
''' <param name="flags">The Binding Flags that the members should have.</param>
|
||||
''' <returns>A History Point with Object States.</returns>
|
||||
Private Shared Function FromObject(objs As Object(), membersToStore As ObjectValueType, whiteOrBlackList As Object, flags As BindingFlags) As HistoryPoint
|
||||
Dim hp As New HistoryPoint
|
||||
|
||||
If whiteOrBlackList Is Nothing Then whiteOrBlackList = New MemberBlackList
|
||||
Dim isWhiteList As Boolean = TypeOf whiteOrBlackList Is MemberWhiteList
|
||||
|
||||
If flags = BindingFlags.Default Then
|
||||
flags = BindingFlags.Instance Or BindingFlags.Public Or BindingFlags.NonPublic
|
||||
End If
|
||||
If membersToStore = ObjectValueType.None Then
|
||||
membersToStore = ObjectValueType.Field Or ObjectValueType.Property
|
||||
End If
|
||||
|
||||
For Each obj As Object In objs
|
||||
If (membersToStore And ObjectValueType.Field) = ObjectValueType.Field Then
|
||||
|
||||
For Each fi As FieldInfo In obj.GetType.GetFields(flags)
|
||||
|
||||
Dim contains As Boolean = CType(whiteOrBlackList, List(Of String)).Contains(fi.Name)
|
||||
If If(isWhiteList, contains, Not contains) Then
|
||||
|
||||
Dim os As New ObjectState
|
||||
os.Object = obj
|
||||
os.MemberName = fi.Name
|
||||
os.MemberType = ObjectValueType.Field
|
||||
os.MemberFlags = flags
|
||||
os.ValueToPatch = fi.GetValue(obj)
|
||||
hp.Entries.Add(os)
|
||||
|
||||
End If
|
||||
|
||||
Next
|
||||
|
||||
End If
|
||||
|
||||
If (membersToStore And ObjectValueType.Property) = ObjectValueType.Property Then
|
||||
|
||||
For Each pi As PropertyInfo In obj.GetType.GetProperties(flags)
|
||||
|
||||
Dim contains As Boolean = CType(whiteOrBlackList, List(Of String)).Contains(pi.Name)
|
||||
If If(isWhiteList, contains, Not contains) Then
|
||||
|
||||
Dim os As New ObjectState
|
||||
os.Object = obj
|
||||
os.MemberName = pi.Name
|
||||
os.MemberType = ObjectValueType.Property
|
||||
os.MemberFlags = flags
|
||||
os.ValueToPatch = pi.GetValue(obj)
|
||||
hp.Entries.Add(os)
|
||||
|
||||
End If
|
||||
|
||||
Next
|
||||
|
||||
End If
|
||||
Next
|
||||
|
||||
Return hp
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Combines some History Points to one.
|
||||
''' </summary>
|
||||
''' <param name="hps">An array of History Points to combine.</param>
|
||||
''' <returns>One History Point that contains all Data of inputted History Points.</returns>
|
||||
Public Shared Function Concat(ParamArray hps As HistoryPoint()) As HistoryPoint
|
||||
Return Concat(hps.FirstOrDefault?.Name, hps)
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Combines some History Points to one.
|
||||
''' </summary>
|
||||
''' <param name="hps">An array of History Points to combine.</param>
|
||||
''' <returns>One History Point that contains all Data of inputted History Points.</returns>
|
||||
Public Shared Function Concat(newName As String, ParamArray hps As HistoryPoint()) As HistoryPoint
|
||||
Dim hp As New HistoryPoint
|
||||
|
||||
For Each _hp As HistoryPoint In hps
|
||||
hp.Entries.AddRange(_hp.Entries)
|
||||
Next
|
||||
|
||||
Return hp
|
||||
End Function
|
||||
|
||||
End Class
|
||||
|
||||
End Namespace
|
||||
31
Pilz.Collections/SimpleHistory/MemberLists.cs
Normal file
31
Pilz.Collections/SimpleHistory/MemberLists.cs
Normal file
@@ -0,0 +1,31 @@
|
||||
namespace Pilz.Collections.SimpleHistory;
|
||||
|
||||
/// <summary>
|
||||
/// List contianing member names to include.
|
||||
/// </summary>
|
||||
public class MemberWhiteList : List<string>
|
||||
{
|
||||
|
||||
public MemberWhiteList() : base()
|
||||
{
|
||||
}
|
||||
|
||||
public MemberWhiteList(string[] entries) : base(entries)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// List contianing member names to exclude
|
||||
/// </summary>
|
||||
public class MemberBlackList : List<string>
|
||||
{
|
||||
|
||||
public MemberBlackList() : base()
|
||||
{
|
||||
}
|
||||
|
||||
public MemberBlackList(string[] entries) : base(entries)
|
||||
{
|
||||
}
|
||||
}
|
||||
@@ -1,33 +0,0 @@
|
||||
Namespace SimpleHistory
|
||||
|
||||
''' <summary>
|
||||
''' List contianing member names to include.
|
||||
''' </summary>
|
||||
Public Class MemberWhiteList
|
||||
Inherits List(Of String)
|
||||
|
||||
Public Sub New()
|
||||
MyBase.New
|
||||
End Sub
|
||||
|
||||
Public Sub New(entries As String())
|
||||
MyBase.New(entries)
|
||||
End Sub
|
||||
End Class
|
||||
|
||||
''' <summary>
|
||||
''' List contianing member names to exclude
|
||||
''' </summary>
|
||||
Public Class MemberBlackList
|
||||
Inherits List(Of String)
|
||||
|
||||
Public Sub New()
|
||||
MyBase.New
|
||||
End Sub
|
||||
|
||||
Public Sub New(entries As String())
|
||||
MyBase.New(entries)
|
||||
End Sub
|
||||
End Class
|
||||
|
||||
End Namespace
|
||||
176
Pilz.Collections/SimpleHistory/ObjectAction.cs
Normal file
176
Pilz.Collections/SimpleHistory/ObjectAction.cs
Normal file
@@ -0,0 +1,176 @@
|
||||
using System.Reflection;
|
||||
|
||||
namespace Pilz.Collections.SimpleHistory;
|
||||
|
||||
public class ObjectAction : ObjectBase
|
||||
{
|
||||
public object? Object { get; set; } = null;
|
||||
public List<object> ParametersUndo { get; } = [];
|
||||
public List<object> ParametersRedo { get; } = [];
|
||||
public MethodInfo? MethodUndo { get; set; } = null;
|
||||
public MethodInfo? MethodRedo { get; set; } = null;
|
||||
public bool AutogenerateObject { get; set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Instance of Object Action.
|
||||
/// </summary>
|
||||
public ObjectAction()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Instance of Object Action.
|
||||
/// </summary>
|
||||
/// <param name="obj">The Objects that contains the methodes to call.</param>
|
||||
/// <param name="methodNameUndo">The name of the methode to call on Undo.</param>
|
||||
/// <param name="methodNameRedo">The name of the methode to call on Redo.</param>
|
||||
public ObjectAction(object obj, string methodNameUndo, string methodNameRedo) : this(obj, methodNameUndo, methodNameRedo, [], [], BindingFlags.Default, BindingFlags.Default)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Instance of Object Action.
|
||||
/// </summary>
|
||||
/// <param name="obj">The Objects that contains the methodes to call.</param>
|
||||
/// <param name="methodNameUndo">The name of the methode to call on Undo.</param>
|
||||
/// <param name="methodNameRedo">The name of the methode to call on Redo.</param>
|
||||
/// <param name="paramsUndo">The parameters for calling the methode on Undo.</param>
|
||||
/// <param name="paramsRedo">The parameters for calling the methode on Redo.</param>
|
||||
public ObjectAction(object obj, string methodNameUndo, string methodNameRedo, object[] paramsUndo, object[] paramsRedo) : this(obj, methodNameUndo, methodNameRedo, paramsUndo, paramsRedo, BindingFlags.Default, BindingFlags.Default)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Instance of Object Action.
|
||||
/// </summary>
|
||||
/// <param name="obj">The Objects that contains the methodes to call.</param>
|
||||
/// <param name="methodNameUndo">The name of the methode to call on Undo.</param>
|
||||
/// <param name="methodNameRedo">The name of the methode to call on Redo.</param>
|
||||
/// <param name="paramsUndo">The parameters for calling the methode on Undo.</param>
|
||||
/// <param name="paramsRedo">The parameters for calling the methode on Redo.</param>
|
||||
/// <param name="methodFlagsUndo">The Binding Flags of Methode on Undo.</param>
|
||||
/// <param name="methodFlagsRedo">The Binding Flags of Methode on Redo.</param>
|
||||
public ObjectAction(object obj, string methodNameUndo, string methodNameRedo, object[] paramsUndo, object[] paramsRedo, BindingFlags methodFlagsUndo, BindingFlags methodFlagsRedo)
|
||||
{
|
||||
Object = obj;
|
||||
ParametersUndo.AddRange(paramsUndo);
|
||||
ParametersRedo.AddRange(paramsRedo);
|
||||
MethodUndo = GetMethodInfo(obj, methodNameUndo, GetFlags(methodFlagsUndo));
|
||||
MethodRedo = GetMethodInfo(obj, methodNameRedo, GetFlags(methodFlagsRedo));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Instance of Object Action.
|
||||
/// </summary>
|
||||
/// <param name="obj">The Objects that contains the methodes to call.</param>
|
||||
/// <param name="methodNameUndo">The name of the methode to call on Undo.</param>
|
||||
/// <param name="methodNameRedo">The name of the methode to call on Redo.</param>
|
||||
/// <param name="methodFlagsUndo">The Binding Flags of Methode on Undo.</param>
|
||||
/// <param name="methodFlagsRedo">The Binding Flags of Methode on Redo.</param>
|
||||
public ObjectAction(object obj, string methodNameUndo, string methodNameRedo, BindingFlags methodFlagsUndo, BindingFlags methodFlagsRedo) : this(obj, methodNameUndo, methodNameRedo, [], [], methodFlagsUndo, methodFlagsRedo)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Instance of Object Action.
|
||||
/// </summary>
|
||||
/// <param name="obj">The Objects that contains the methodes to call.</param>
|
||||
/// <param name="methodUndo">The MethodInfo of the methode to call on Undo.</param>
|
||||
/// <param name="methodRedo">The MethodInfo of the methode to call on Redo.</param>
|
||||
public ObjectAction(object obj, MethodInfo methodUndo, MethodInfo methodRedo)
|
||||
{
|
||||
Object = obj;
|
||||
MethodUndo = methodUndo;
|
||||
MethodRedo = methodRedo;
|
||||
}
|
||||
/// <summary>
|
||||
/// Creates a new Instance of Object Action.
|
||||
/// </summary>
|
||||
/// <param name="obj">The Objects that contains the methodes to call.</param>
|
||||
/// <param name="methodUndo">The MethodInfo of the methode to call on Undo.</param>
|
||||
/// <param name="methodRedo">The MethodInfo of the methode to call on Redo.</param>
|
||||
/// <param name="paramsUndo">The parameters for calling the methode on Undo.</param>
|
||||
/// <param name="paramsRedo">The parameters for calling the methode on Redo.</param>
|
||||
public ObjectAction(object obj, MethodInfo methodUndo, MethodInfo methodRedo, object[] paramsUndo, object[] paramsRedo) : this(obj, methodUndo, methodRedo)
|
||||
{
|
||||
ParametersUndo.AddRange(paramsUndo);
|
||||
ParametersRedo.AddRange(paramsRedo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Instance of Object Action.
|
||||
/// </summary>
|
||||
/// <param name="obj">The Objects that contains the methodes to call.</param>
|
||||
/// <param name="methodUndo">The Delegate of the methode to call on Undo.</param>
|
||||
/// <param name="methodRedo">The Delegate of the methode to call on Redo.</param>
|
||||
public ObjectAction(object obj, Delegate methodUndo, Delegate methodRedo)
|
||||
{
|
||||
Object = obj;
|
||||
MethodUndo = methodUndo.Method;
|
||||
MethodRedo = methodRedo.Method;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Instance of Object Action.
|
||||
/// </summary>
|
||||
/// <param name="obj">The Objects that contains the methodes to call.</param>
|
||||
/// <param name="methodUndo">The Delegate of the methode to call on Undo.</param>
|
||||
/// <param name="methodRedo">The Delegate of the methode to call on Redo.</param>
|
||||
/// <param name="paramsUndo">The parameters for calling the methode on Undo.</param>
|
||||
/// <param name="paramsRedo">The parameters for calling the methode on Redo.</param>
|
||||
public ObjectAction(object obj, Delegate methodUndo, Delegate methodRedo, object[] paramsUndo, object[] paramsRedo) : this(obj, methodUndo, methodRedo)
|
||||
{
|
||||
ParametersUndo.AddRange(paramsUndo);
|
||||
ParametersRedo.AddRange(paramsRedo);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Instance of Object Action.
|
||||
/// </summary>
|
||||
/// <param name="obj">The Objects that contains the methodes to call.</param>
|
||||
/// <param name="methodUndo">The Action of the methode to call on Undo.</param>
|
||||
/// <param name="methodRedo">The Action of the methode to call on Redo.</param>
|
||||
public ObjectAction(object obj, Action methodUndo, Action methodRedo)
|
||||
{
|
||||
Object = obj;
|
||||
MethodUndo = methodUndo.Method;
|
||||
MethodRedo = methodRedo.Method;
|
||||
}
|
||||
|
||||
private static BindingFlags GetFlags(BindingFlags flags)
|
||||
{
|
||||
if (flags == BindingFlags.Default)
|
||||
flags = BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic;
|
||||
return flags;
|
||||
}
|
||||
|
||||
private static MethodInfo? GetMethodInfo(object obj, string name, BindingFlags flags)
|
||||
{
|
||||
return obj.GetType().GetMethod(name, flags);
|
||||
}
|
||||
|
||||
internal void Undo()
|
||||
{
|
||||
CheckIfObjIsNothing(MethodUndo);
|
||||
MethodUndo?.Invoke(Object, ParametersUndo.ToArray());
|
||||
}
|
||||
|
||||
internal void Redo()
|
||||
{
|
||||
CheckIfObjIsNothing(MethodRedo);
|
||||
MethodRedo?.Invoke(Object, ParametersRedo.ToArray());
|
||||
}
|
||||
|
||||
private void CheckIfObjIsNothing(MethodInfo? mi)
|
||||
{
|
||||
if (mi is not null && !mi.IsStatic && AutogenerateObject)
|
||||
{
|
||||
if ((Object is null || Object.GetType() != mi.ReflectedType) && !mi.IsStatic)
|
||||
{
|
||||
var constructor = mi.ReflectedType?.GetConstructor(Type.EmptyTypes);
|
||||
var classObject = constructor?.Invoke([]);
|
||||
Object = classObject;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
Imports System.Reflection
|
||||
Imports System.Runtime.InteropServices
|
||||
|
||||
Namespace SimpleHistory
|
||||
|
||||
Public Class ObjectAction
|
||||
Inherits ObjectBase
|
||||
|
||||
Public Property [Object] As Object = Nothing
|
||||
Public ReadOnly Property ParametersUndo As New List(Of Object)
|
||||
Public ReadOnly Property ParametersRedo As New List(Of Object)
|
||||
Public Property MethodUndo As MethodInfo = Nothing
|
||||
Public Property MethodRedo As MethodInfo = Nothing
|
||||
Public Property AutogenerateObject As Boolean = True
|
||||
|
||||
''' <summary>
|
||||
''' Creates a new Instance of Object Action.
|
||||
''' </summary>
|
||||
Public Sub New()
|
||||
End Sub
|
||||
|
||||
Private Function GetMethodInfo(obj As Object, name As String, flags As BindingFlags)
|
||||
Return obj.GetType.GetMethod(name, flags)
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Creates a new Instance of Object Action.
|
||||
''' </summary>
|
||||
''' <param name="obj">The Objects that contains the methodes to call.</param>
|
||||
''' <param name="methodNameUndo">The name of the methode to call on Undo.</param>
|
||||
''' <param name="methodNameRedo">The name of the methode to call on Redo.</param>
|
||||
Public Sub New(obj As Object, methodNameUndo As String, methodNameRedo As String)
|
||||
Me.New(obj, methodNameUndo, methodNameRedo, {}, {}, BindingFlags.Default, BindingFlags.Default)
|
||||
End Sub
|
||||
''' <summary>
|
||||
''' Creates a new Instance of Object Action.
|
||||
''' </summary>
|
||||
''' <param name="obj">The Objects that contains the methodes to call.</param>
|
||||
''' <param name="methodNameUndo">The name of the methode to call on Undo.</param>
|
||||
''' <param name="methodNameRedo">The name of the methode to call on Redo.</param>
|
||||
''' <param name="paramsUndo">The parameters for calling the methode on Undo.</param>
|
||||
''' <param name="paramsRedo">The parameters for calling the methode on Redo.</param>
|
||||
Public Sub New(obj As Object, methodNameUndo As String, methodNameRedo As String, paramsUndo As Object(), paramsRedo As Object())
|
||||
Me.New(obj, methodNameUndo, methodNameRedo, paramsUndo, paramsRedo, BindingFlags.Default, BindingFlags.Default)
|
||||
End Sub
|
||||
''' <summary>
|
||||
''' Creates a new Instance of Object Action.
|
||||
''' </summary>
|
||||
''' <param name="obj">The Objects that contains the methodes to call.</param>
|
||||
''' <param name="methodNameUndo">The name of the methode to call on Undo.</param>
|
||||
''' <param name="methodNameRedo">The name of the methode to call on Redo.</param>
|
||||
''' <param name="paramsUndo">The parameters for calling the methode on Undo.</param>
|
||||
''' <param name="paramsRedo">The parameters for calling the methode on Redo.</param>
|
||||
''' <param name="methodFlagsUndo">The Binding Flags of Methode on Undo.</param>
|
||||
''' <param name="methodFlagsRedo">The Binding Flags of Methode on Redo.</param>
|
||||
Public Sub New(obj As Object, methodNameUndo As String, methodNameRedo As String, paramsUndo As Object(), paramsRedo As Object(), methodFlagsUndo As BindingFlags, methodFlagsRedo As BindingFlags)
|
||||
[Object] = obj
|
||||
ParametersUndo.AddRange(paramsUndo)
|
||||
ParametersRedo.AddRange(paramsRedo)
|
||||
MethodUndo = GetMethodInfo(obj, methodNameUndo, GetFlags(methodFlagsUndo))
|
||||
MethodRedo = GetMethodInfo(obj, methodNameRedo, GetFlags(methodFlagsRedo))
|
||||
End Sub
|
||||
''' <summary>
|
||||
''' Creates a new Instance of Object Action.
|
||||
''' </summary>
|
||||
''' <param name="obj">The Objects that contains the methodes to call.</param>
|
||||
''' <param name="methodNameUndo">The name of the methode to call on Undo.</param>
|
||||
''' <param name="methodNameRedo">The name of the methode to call on Redo.</param>
|
||||
''' <param name="methodFlagsUndo">The Binding Flags of Methode on Undo.</param>
|
||||
''' <param name="methodFlagsRedo">The Binding Flags of Methode on Redo.</param>
|
||||
Public Sub New(obj As Object, methodNameUndo As String, methodNameRedo As String, methodFlagsUndo As BindingFlags, methodFlagsRedo As BindingFlags)
|
||||
Me.New(obj, methodNameUndo, methodNameRedo, {}, {}, methodFlagsUndo, methodFlagsRedo)
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Creates a new Instance of Object Action.
|
||||
''' </summary>
|
||||
''' <param name="obj">The Objects that contains the methodes to call.</param>
|
||||
''' <param name="methodUndo">The MethodInfo of the methode to call on Undo.</param>
|
||||
''' <param name="methodRedo">The MethodInfo of the methode to call on Redo.</param>
|
||||
Public Sub New(obj As Object, methodUndo As MethodInfo, methodRedo As MethodInfo)
|
||||
[Object] = obj
|
||||
Me.MethodUndo = methodUndo
|
||||
Me.MethodRedo = methodRedo
|
||||
End Sub
|
||||
''' <summary>
|
||||
''' Creates a new Instance of Object Action.
|
||||
''' </summary>
|
||||
''' <param name="obj">The Objects that contains the methodes to call.</param>
|
||||
''' <param name="methodUndo">The MethodInfo of the methode to call on Undo.</param>
|
||||
''' <param name="methodRedo">The MethodInfo of the methode to call on Redo.</param>
|
||||
''' <param name="paramsUndo">The parameters for calling the methode on Undo.</param>
|
||||
''' <param name="paramsRedo">The parameters for calling the methode on Redo.</param>
|
||||
Public Sub New(obj As Object, methodUndo As MethodInfo, methodRedo As MethodInfo, paramsUndo As Object(), paramsRedo As Object())
|
||||
Me.New(obj, methodUndo, methodRedo)
|
||||
ParametersUndo.AddRange(paramsUndo)
|
||||
ParametersRedo.AddRange(paramsRedo)
|
||||
End Sub
|
||||
''' <summary>
|
||||
''' Creates a new Instance of Object Action.
|
||||
''' </summary>
|
||||
''' <param name="obj">The Objects that contains the methodes to call.</param>
|
||||
''' <param name="methodUndo">The Delegate of the methode to call on Undo.</param>
|
||||
''' <param name="methodRedo">The Delegate of the methode to call on Redo.</param>
|
||||
Public Sub New(obj As Object, methodUndo As [Delegate], methodRedo As [Delegate])
|
||||
[Object] = obj
|
||||
Me.MethodUndo = methodUndo.Method
|
||||
Me.MethodRedo = methodRedo.Method
|
||||
End Sub
|
||||
''' <summary>
|
||||
''' Creates a new Instance of Object Action.
|
||||
''' </summary>
|
||||
''' <param name="obj">The Objects that contains the methodes to call.</param>
|
||||
''' <param name="methodUndo">The Delegate of the methode to call on Undo.</param>
|
||||
''' <param name="methodRedo">The Delegate of the methode to call on Redo.</param>
|
||||
''' <param name="paramsUndo">The parameters for calling the methode on Undo.</param>
|
||||
''' <param name="paramsRedo">The parameters for calling the methode on Redo.</param>
|
||||
Public Sub New(obj As Object, methodUndo As [Delegate], methodRedo As [Delegate], paramsUndo As Object(), paramsRedo As Object())
|
||||
Me.New(obj, methodUndo, methodRedo)
|
||||
ParametersUndo.AddRange(paramsUndo)
|
||||
ParametersRedo.AddRange(paramsRedo)
|
||||
End Sub
|
||||
''' <summary>
|
||||
''' Creates a new Instance of Object Action.
|
||||
''' </summary>
|
||||
''' <param name="obj">The Objects that contains the methodes to call.</param>
|
||||
''' <param name="methodUndo">The Action of the methode to call on Undo.</param>
|
||||
''' <param name="methodRedo">The Action of the methode to call on Redo.</param>
|
||||
Public Sub New(obj As Object, methodUndo As Action, methodRedo As Action)
|
||||
[Object] = obj
|
||||
Me.MethodUndo = methodUndo.Method
|
||||
Me.MethodRedo = methodRedo.Method
|
||||
End Sub
|
||||
|
||||
Private Function GetFlags(flags As BindingFlags) As BindingFlags
|
||||
If flags = BindingFlags.Default Then
|
||||
flags = BindingFlags.Instance Or BindingFlags.Public Or BindingFlags.NonPublic
|
||||
End If
|
||||
Return flags
|
||||
End Function
|
||||
|
||||
Friend Sub Undo()
|
||||
CheckIfObjIsNothing(MethodUndo)
|
||||
MethodUndo?.Invoke([Object], ParametersUndo.ToArray)
|
||||
End Sub
|
||||
|
||||
Friend Sub Redo()
|
||||
CheckIfObjIsNothing(MethodRedo)
|
||||
MethodRedo?.Invoke([Object], ParametersRedo.ToArray)
|
||||
End Sub
|
||||
|
||||
Private Sub CheckIfObjIsNothing(mi As MethodInfo)
|
||||
If mi IsNot Nothing AndAlso Not mi.IsStatic AndAlso AutogenerateObject Then
|
||||
If (Me.Object Is Nothing OrElse Me.Object.GetType <> mi.ReflectedType) AndAlso Not mi.IsStatic Then
|
||||
Dim constructor As ConstructorInfo = mi.ReflectedType.GetConstructor(Type.EmptyTypes)
|
||||
Dim classObject As Object = constructor.Invoke({})
|
||||
Me.Object = classObject
|
||||
End If
|
||||
End If
|
||||
End Sub
|
||||
|
||||
End Class
|
||||
|
||||
|
||||
End Namespace
|
||||
10
Pilz.Collections/SimpleHistory/ObjectBase.cs
Normal file
10
Pilz.Collections/SimpleHistory/ObjectBase.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
namespace Pilz.Collections.SimpleHistory;
|
||||
|
||||
public class ObjectBase
|
||||
{
|
||||
public static int DefaultPriorityValue { get; set; } = 1000;
|
||||
|
||||
public int UndoPriority { get; set; } = DefaultPriorityValue;
|
||||
|
||||
public int RedoPriority { get; set; } = DefaultPriorityValue;
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
Namespace SimpleHistory
|
||||
|
||||
Public Class ObjectBase
|
||||
|
||||
Public Shared Property DefaultPriorityValue As Integer = 1000
|
||||
|
||||
Public Property UndoPriority As Integer = DefaultPriorityValue
|
||||
Public Property RedoPriority As Integer = DefaultPriorityValue
|
||||
|
||||
End Class
|
||||
|
||||
|
||||
End Namespace
|
||||
88
Pilz.Collections/SimpleHistory/ObjectState.cs
Normal file
88
Pilz.Collections/SimpleHistory/ObjectState.cs
Normal file
@@ -0,0 +1,88 @@
|
||||
using System.Reflection;
|
||||
|
||||
namespace Pilz.Collections.SimpleHistory;
|
||||
|
||||
public class ObjectState : ObjectBase
|
||||
{
|
||||
/// <summary>
|
||||
/// The Object including the members to patch.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public object? Object { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// The name of the Member to patch.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public string MemberName { get; set; } = "";
|
||||
|
||||
/// <summary>
|
||||
/// The Value that should be patched.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public object? ValueToPatch { get; set; } = null;
|
||||
|
||||
/// <summary>
|
||||
/// The member types to include at searching for the member.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public ObjectValueType MemberType { get; set; } = ObjectValueType.Field;
|
||||
|
||||
/// <summary>
|
||||
/// The Binding Flags that are used at searching for the member.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public BindingFlags MemberFlags { get; set; } = BindingFlags.Default;
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Instance of ObjectState from input.
|
||||
/// </summary>
|
||||
/// <param name="obj">The Object including the members to patch.</param>
|
||||
/// <param name="valname">The name of the Member to patch.</param>
|
||||
/// <param name="valToPatch">The member types to include at searching for the member.</param>
|
||||
/// <param name="valtype">The Binding Flags that are used at searching for the member.</param>
|
||||
public ObjectState(object obj, string valname, object valToPatch, ObjectValueType valtype)
|
||||
{
|
||||
Object = obj;
|
||||
MemberName = valname;
|
||||
ValueToPatch = valToPatch;
|
||||
MemberType = valtype;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new Instance of ObjectState.
|
||||
/// </summary>
|
||||
public ObjectState()
|
||||
{
|
||||
}
|
||||
|
||||
internal void Patch()
|
||||
{
|
||||
if (Object is null)
|
||||
return;
|
||||
|
||||
var t = Object.GetType();
|
||||
|
||||
switch (MemberType)
|
||||
{
|
||||
case ObjectValueType.Field:
|
||||
if (t.GetField(MemberName, MemberFlags) is FieldInfo f)
|
||||
{
|
||||
var temp = f.GetValue(Object);
|
||||
f.SetValue(Object, ValueToPatch);
|
||||
ValueToPatch = temp;
|
||||
}
|
||||
break;
|
||||
case ObjectValueType.Property:
|
||||
if (t.GetProperty(MemberName, BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static) is PropertyInfo p)
|
||||
{
|
||||
var temp = p.GetValue(Object);
|
||||
p.SetValue(Object, ValueToPatch);
|
||||
ValueToPatch = temp;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
throw new Exception("ValueType is invalid!");
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,84 +0,0 @@
|
||||
Imports System.Reflection
|
||||
|
||||
Namespace SimpleHistory
|
||||
|
||||
Public Class ObjectState
|
||||
Inherits ObjectBase
|
||||
|
||||
''' <summary>
|
||||
''' The Object including the members to patch.
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Property [Object] As Object = Nothing
|
||||
''' <summary>
|
||||
''' The name of the Member to patch.
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Property MemberName As String = ""
|
||||
''' <summary>
|
||||
''' The Value that should be patched.
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Property ValueToPatch As Object = Nothing
|
||||
''' <summary>
|
||||
''' The member types to include at searching for the member.
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Property MemberType As ObjectValueType = ObjectValueType.Field
|
||||
''' <summary>
|
||||
''' The Binding Flags that are used at searching for the member.
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Property MemberFlags As BindingFlags = BindingFlags.Default
|
||||
|
||||
''' <summary>
|
||||
''' Creates a new Instance of ObjectState from input.
|
||||
''' </summary>
|
||||
''' <param name="obj">The Object including the members to patch.</param>
|
||||
''' <param name="valname">The name of the Member to patch.</param>
|
||||
''' <param name="valToPatch">The member types to include at searching for the member.</param>
|
||||
''' <param name="valtype">The Binding Flags that are used at searching for the member.</param>
|
||||
Public Sub New(obj As Object, valname As String, valToPatch As Object, valtype As ObjectValueType)
|
||||
[Object] = obj
|
||||
MemberName = valname
|
||||
ValueToPatch = valToPatch
|
||||
MemberType = valtype
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Creates a new Instance of ObjectState.
|
||||
''' </summary>
|
||||
Public Sub New()
|
||||
End Sub
|
||||
|
||||
Friend Sub Patch()
|
||||
Dim t As Type = [Object].GetType
|
||||
Select Case MemberType
|
||||
Case ObjectValueType.Field
|
||||
Dim f As FieldInfo = t.GetField(MemberName, MemberFlags)
|
||||
Dim temp As Object = Nothing
|
||||
|
||||
If f IsNot Nothing Then
|
||||
temp = f.GetValue([Object])
|
||||
f.SetValue([Object], ValueToPatch)
|
||||
ValueToPatch = temp
|
||||
End If
|
||||
|
||||
Case ObjectValueType.Property
|
||||
Dim p As PropertyInfo = t.GetProperty(MemberName, BindingFlags.Instance Or BindingFlags.Public Or BindingFlags.NonPublic Or BindingFlags.Static)
|
||||
Dim temp As Object = Nothing
|
||||
|
||||
If p IsNot Nothing Then
|
||||
temp = p.GetValue([Object])
|
||||
p.SetValue([Object], ValueToPatch)
|
||||
ValueToPatch = temp
|
||||
End If
|
||||
|
||||
Case Else
|
||||
Throw New Exception("ValueType is invalid!")
|
||||
End Select
|
||||
End Sub
|
||||
|
||||
End Class
|
||||
|
||||
End Namespace
|
||||
11
Pilz.Collections/SimpleHistory/ObjectValueType.cs
Normal file
11
Pilz.Collections/SimpleHistory/ObjectValueType.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace Pilz.Collections.SimpleHistory;
|
||||
|
||||
/// <summary>
|
||||
/// Specify which member types you would include.
|
||||
/// </summary>
|
||||
public enum ObjectValueType
|
||||
{
|
||||
None = 0,
|
||||
Field = 1,
|
||||
Property = 2,
|
||||
}
|
||||
@@ -1,12 +0,0 @@
|
||||
Namespace SimpleHistory
|
||||
|
||||
''' <summary>
|
||||
''' Specify which member types you would include.
|
||||
''' </summary>
|
||||
Public Enum ObjectValueType
|
||||
None = 0
|
||||
Field = 1
|
||||
[Property] = 2
|
||||
End Enum
|
||||
|
||||
End Namespace
|
||||
101
Pilz.Collections/SimpleHistory/SimpleHistory.cs
Normal file
101
Pilz.Collections/SimpleHistory/SimpleHistory.cs
Normal file
@@ -0,0 +1,101 @@
|
||||
namespace Pilz.Collections.SimpleHistory;
|
||||
|
||||
public class HistoryStack
|
||||
{
|
||||
private readonly Stack<HistoryPoint> stackPast = new();
|
||||
private readonly Stack<HistoryPoint> stackFuture = new();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the count of history points.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public int ChangesCount => stackPast.Count;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current stack of all past HistoryPoints that are used for the Undo function.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public HistoryPoint[] PastHistoryPoints => [.. stackPast];
|
||||
|
||||
/// <summary>
|
||||
/// Gets the current stack of all future HistoryPoints that are used for the Redo function.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public HistoryPoint[] FutureHistoryPoints => [.. stackFuture];
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the History has past changes.
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public bool HasChanges() => stackPast.Count > 0;
|
||||
|
||||
/// <summary>
|
||||
/// Patch Object States and call Undo Actions.
|
||||
/// </summary>
|
||||
public HistoryPoint? Undo()
|
||||
{
|
||||
HistoryPoint? ret;
|
||||
|
||||
if (stackPast.Count > 0)
|
||||
{
|
||||
var hp = stackPast.Pop();
|
||||
hp.Undo();
|
||||
stackFuture.Push(hp);
|
||||
ret = hp;
|
||||
}
|
||||
else
|
||||
ret = null;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Patch Object States and call Redo Actions.
|
||||
/// </summary>
|
||||
public HistoryPoint? Redo()
|
||||
{
|
||||
HistoryPoint? ret;
|
||||
|
||||
if (stackFuture.Count > 0)
|
||||
{
|
||||
var hp = stackFuture.Pop();
|
||||
hp.Redo();
|
||||
stackPast.Push(hp);
|
||||
ret = hp;
|
||||
}
|
||||
else
|
||||
ret = null;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clear the History.
|
||||
/// </summary>
|
||||
public void Clear()
|
||||
{
|
||||
stackPast.Clear();
|
||||
stackFuture.Clear();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Store a History Point.
|
||||
/// </summary>
|
||||
/// <param name="point">The History Point to add to the past changes.</param>
|
||||
/// <param name="newName">The name to set for the History Point.</param>
|
||||
public void Store(HistoryPoint point, string newName)
|
||||
{
|
||||
point.Name = newName;
|
||||
Store(point);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Store a History Point.
|
||||
/// </summary>
|
||||
/// <param name="point">The History Point to add to the past changes.</param>
|
||||
public void Store(HistoryPoint point)
|
||||
{
|
||||
stackPast.Push(point);
|
||||
stackFuture.Clear();
|
||||
}
|
||||
}
|
||||
@@ -1,93 +0,0 @@
|
||||
Imports System.Reflection
|
||||
|
||||
Namespace SimpleHistory
|
||||
|
||||
Public Class HistoryStack
|
||||
|
||||
Private stackPast As New Stack(Of HistoryPoint)
|
||||
Private stackFuture As New Stack(Of HistoryPoint)
|
||||
|
||||
''' <summary>
|
||||
''' Gets the count of history points.
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public ReadOnly Property ChangesCount As Boolean
|
||||
Get
|
||||
Return stackPast.Count
|
||||
End Get
|
||||
End Property
|
||||
|
||||
''' <summary>
|
||||
''' Checks if the History has past changes.
|
||||
''' </summary>
|
||||
''' <returns></returns>
|
||||
Public Function HasChanges() As Boolean
|
||||
Return stackPast.Count > 0
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Patch Object States and call Undo Actions.
|
||||
''' </summary>
|
||||
Public Function Undo() As HistoryPoint
|
||||
Dim ret As HistoryPoint
|
||||
|
||||
If stackPast.Count > 0 Then
|
||||
Dim hp As HistoryPoint = stackPast.Pop
|
||||
hp.Undo()
|
||||
stackFuture.Push(hp)
|
||||
ret = hp
|
||||
Else
|
||||
ret = Nothing
|
||||
End If
|
||||
|
||||
Return ret
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Patch Object States and call Redo Actions.
|
||||
''' </summary>
|
||||
Public Function Redo() As HistoryPoint
|
||||
Dim ret As HistoryPoint
|
||||
|
||||
If stackFuture.Count > 0 Then
|
||||
Dim hp As HistoryPoint = stackFuture.Pop
|
||||
hp.Redo()
|
||||
stackPast.Push(hp)
|
||||
ret = hp
|
||||
Else
|
||||
ret = Nothing
|
||||
End If
|
||||
|
||||
Return ret
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Clear the History.
|
||||
''' </summary>
|
||||
Public Sub Clear()
|
||||
stackPast.Clear()
|
||||
stackFuture.Clear()
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Store a History Point.
|
||||
''' </summary>
|
||||
''' <param name="point">The History Point to add to the past changes.</param>
|
||||
''' <param name="newName">The name to set for the History Point.</param>
|
||||
Public Sub Store(point As HistoryPoint, newName As String)
|
||||
point.Name = newName
|
||||
Store(point)
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Store a History Point.
|
||||
''' </summary>
|
||||
''' <param name="point">The History Point to add to the past changes.</param>
|
||||
Public Sub Store(point As HistoryPoint)
|
||||
stackPast.Push(point)
|
||||
stackFuture.Clear()
|
||||
End Sub
|
||||
|
||||
End Class
|
||||
|
||||
End Namespace
|
||||
86
Pilz.Configuration/AutoSaveConfigurationManager.cs
Normal file
86
Pilz.Configuration/AutoSaveConfigurationManager.cs
Normal file
@@ -0,0 +1,86 @@
|
||||
using System;
|
||||
|
||||
namespace Pilz.Configuration;
|
||||
|
||||
public class AutoSaveConfigurationManager : ConfigurationManager
|
||||
{
|
||||
private bool addedHandler = false;
|
||||
private bool enableAutoSave = false;
|
||||
private string _ConfigFilePath = string.Empty;
|
||||
private bool _AutoLoadConfigOnAccess = false;
|
||||
|
||||
public string ConfigFilePath
|
||||
{
|
||||
get => _ConfigFilePath;
|
||||
set
|
||||
{
|
||||
_ConfigFilePath = value;
|
||||
if (AutoLoadConfigOnAccess)
|
||||
Load();
|
||||
}
|
||||
}
|
||||
|
||||
public bool AutoLoadConfigOnAccess
|
||||
{
|
||||
get => _AutoLoadConfigOnAccess;
|
||||
set
|
||||
{
|
||||
_AutoLoadConfigOnAccess = value;
|
||||
if (value)
|
||||
Load();
|
||||
}
|
||||
}
|
||||
|
||||
public bool AutoSaveConfigOnExit
|
||||
{
|
||||
get => enableAutoSave;
|
||||
set
|
||||
{
|
||||
if (enableAutoSave != value)
|
||||
{
|
||||
enableAutoSave = value;
|
||||
if (enableAutoSave)
|
||||
AddAutoSaveHandler();
|
||||
else
|
||||
RemoveAutoSaveHandler();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void AddAutoSaveHandler()
|
||||
{
|
||||
if (!addedHandler)
|
||||
{
|
||||
AppDomain.CurrentDomain.ProcessExit += AutoSaveSettingsOnExit;
|
||||
addedHandler = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void RemoveAutoSaveHandler()
|
||||
{
|
||||
AppDomain.CurrentDomain.ProcessExit -= AutoSaveSettingsOnExit;
|
||||
addedHandler = false;
|
||||
}
|
||||
|
||||
private void AutoSaveSettingsOnExit(object sender, EventArgs e)
|
||||
{
|
||||
Save();
|
||||
}
|
||||
|
||||
private void Save()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(ConfigFilePath) && Configuration is not null)
|
||||
Configuration.WriteToFile(ConfigFilePath);
|
||||
}
|
||||
|
||||
private void Load()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(ConfigFilePath))
|
||||
Configuration.ReadFromFile(ConfigFilePath);
|
||||
}
|
||||
|
||||
~AutoSaveConfigurationManager()
|
||||
{
|
||||
RemoveAutoSaveHandler();
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
Public Class AutoSaveConfigurationManager
|
||||
Inherits ConfigurationManager
|
||||
|
||||
Private addedHandler As Boolean = False
|
||||
Private enableAutoSave As Boolean = False
|
||||
Private _ConfigFilePath As String = String.Empty
|
||||
Private _AutoLoadConfigOnAccess As Boolean = False
|
||||
|
||||
Public Property ConfigFilePath As String
|
||||
Get
|
||||
Return _ConfigFilePath
|
||||
End Get
|
||||
Set
|
||||
_ConfigFilePath = Value
|
||||
If AutoLoadConfigOnAccess Then Load()
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Public Property AutoLoadConfigOnAccess As Boolean
|
||||
Get
|
||||
Return _AutoLoadConfigOnAccess
|
||||
End Get
|
||||
Set
|
||||
_AutoLoadConfigOnAccess = Value
|
||||
If Value Then Load()
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Public Property AutoSaveConfigOnExit As Boolean
|
||||
Get
|
||||
Return enableAutoSave
|
||||
End Get
|
||||
Set
|
||||
If enableAutoSave <> Value Then
|
||||
enableAutoSave = Value
|
||||
Select Case enableAutoSave
|
||||
Case True
|
||||
AddAutoSaveHandler()
|
||||
Case False
|
||||
RemoveAutoSaveHandler()
|
||||
End Select
|
||||
End If
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Private Sub AddAutoSaveHandler()
|
||||
If Not addedHandler Then
|
||||
AddHandler AppDomain.CurrentDomain.ProcessExit, AddressOf AutoSaveSettingsOnExit
|
||||
addedHandler = True
|
||||
End If
|
||||
End Sub
|
||||
|
||||
Private Sub RemoveAutoSaveHandler()
|
||||
RemoveHandler AppDomain.CurrentDomain.ProcessExit, AddressOf AutoSaveSettingsOnExit
|
||||
addedHandler = False
|
||||
End Sub
|
||||
|
||||
Private Sub AutoSaveSettingsOnExit(sender As Object, e As EventArgs)
|
||||
Save()
|
||||
End Sub
|
||||
|
||||
Private Sub Save()
|
||||
If Not String.IsNullOrEmpty(ConfigFilePath) AndAlso Configuration IsNot Nothing Then
|
||||
Configuration.WriteToFile(ConfigFilePath)
|
||||
End If
|
||||
End Sub
|
||||
|
||||
Private Sub Load()
|
||||
If Not String.IsNullOrEmpty(ConfigFilePath) Then
|
||||
Configuration.ReadFromFile(ConfigFilePath)
|
||||
End If
|
||||
End Sub
|
||||
|
||||
Protected Overrides Sub Finalize()
|
||||
RemoveAutoSaveHandler()
|
||||
End Sub
|
||||
|
||||
End Class
|
||||
11
Pilz.Configuration/ConfigurationManager.cs
Normal file
11
Pilz.Configuration/ConfigurationManager.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace Pilz.Configuration;
|
||||
|
||||
public abstract class ConfigurationManager
|
||||
{
|
||||
public SimpleConfiguration Configuration { get; private set; }
|
||||
|
||||
internal void SetConfiguration(SimpleConfiguration configuration)
|
||||
{
|
||||
Configuration = configuration;
|
||||
}
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
Public MustInherit Class ConfigurationManager
|
||||
|
||||
Public ReadOnly Property Configuration As SimpleConfiguration
|
||||
|
||||
Friend Sub SetConfiguration(configuration As SimpleConfiguration)
|
||||
_Configuration = configuration
|
||||
End Sub
|
||||
|
||||
End Class
|
||||
87
Pilz.Configuration/ConfigurationManagerList.cs
Normal file
87
Pilz.Configuration/ConfigurationManagerList.cs
Normal file
@@ -0,0 +1,87 @@
|
||||
using Pilz.GeneralEventArgs;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Pilz.Configuration;
|
||||
|
||||
public class ConfigurationManagerList : IList<ConfigurationManager>
|
||||
{
|
||||
public event GettingParentManagerEventHandler GettingParentManager;
|
||||
|
||||
public delegate void GettingParentManagerEventHandler(object sender, GetValueEventArgs<SimpleConfiguration> e);
|
||||
|
||||
private readonly List<ConfigurationManager> myList = [];
|
||||
|
||||
private object GetParentManager()
|
||||
{
|
||||
var args = new GetValueEventArgs<SimpleConfiguration>();
|
||||
GettingParentManager?.Invoke(this, args);
|
||||
return args.Value;
|
||||
}
|
||||
|
||||
public ConfigurationManager this[int index]
|
||||
{
|
||||
get => myList[index];
|
||||
set => myList[index] = value;
|
||||
}
|
||||
|
||||
public int Count => myList.Count;
|
||||
|
||||
public bool IsReadOnly => false;
|
||||
|
||||
public void Insert(int index, ConfigurationManager item)
|
||||
{
|
||||
myList.Insert(index, item);
|
||||
item.SetConfiguration((SimpleConfiguration)GetParentManager());
|
||||
}
|
||||
|
||||
public void RemoveAt(int index)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
public void Add(ConfigurationManager item)
|
||||
{
|
||||
item.SetConfiguration((SimpleConfiguration)GetParentManager());
|
||||
}
|
||||
|
||||
public void Clear()
|
||||
{
|
||||
foreach (ConfigurationManager item in myList)
|
||||
item.SetConfiguration(null);
|
||||
myList.Clear();
|
||||
}
|
||||
|
||||
public void CopyTo(ConfigurationManager[] array, int arrayIndex)
|
||||
{
|
||||
myList.CopyTo(array, arrayIndex);
|
||||
}
|
||||
|
||||
public int IndexOf(ConfigurationManager item)
|
||||
{
|
||||
return myList.IndexOf(item);
|
||||
}
|
||||
|
||||
public bool Contains(ConfigurationManager item)
|
||||
{
|
||||
return myList.Contains(item);
|
||||
}
|
||||
|
||||
public bool Remove(ConfigurationManager item)
|
||||
{
|
||||
item.SetConfiguration(null);
|
||||
return myList.Remove(item);
|
||||
}
|
||||
|
||||
public IEnumerator<ConfigurationManager> GetEnumerator()
|
||||
{
|
||||
return (IEnumerator<ConfigurationManager>)IEnumerable_GetEnumerator();
|
||||
}
|
||||
|
||||
private IEnumerator IEnumerable_GetEnumerator()
|
||||
{
|
||||
return myList.GetEnumerator();
|
||||
}
|
||||
|
||||
IEnumerator IEnumerable.GetEnumerator() => IEnumerable_GetEnumerator();
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
Imports Pilz.Configuration
|
||||
Imports Pilz.GeneralEventArgs
|
||||
|
||||
Public Class ConfigurationManagerList
|
||||
Implements IList(Of ConfigurationManager)
|
||||
|
||||
Public Event GettingParentManager(sender As Object, e As GetValueEventArgs(Of SimpleConfiguration))
|
||||
|
||||
Private ReadOnly myList As New List(Of ConfigurationManager)
|
||||
|
||||
Private Function GetParentManager()
|
||||
Dim args As New GetValueEventArgs(Of SimpleConfiguration)
|
||||
RaiseEvent GettingParentManager(Me, args)
|
||||
Return args.Value
|
||||
End Function
|
||||
|
||||
Default Public Property Item(index As Integer) As ConfigurationManager Implements IList(Of ConfigurationManager).Item
|
||||
Get
|
||||
Return myList(index)
|
||||
End Get
|
||||
Set(value As ConfigurationManager)
|
||||
myList(index) = value
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Public ReadOnly Property Count As Integer Implements ICollection(Of ConfigurationManager).Count
|
||||
Get
|
||||
Return myList.Count
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Public ReadOnly Property IsReadOnly As Boolean Implements ICollection(Of ConfigurationManager).IsReadOnly
|
||||
Get
|
||||
Return False
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Public Sub Insert(index As Integer, item As ConfigurationManager) Implements IList(Of ConfigurationManager).Insert
|
||||
myList.Insert(index, item)
|
||||
item.SetConfiguration(GetParentManager)
|
||||
End Sub
|
||||
|
||||
Public Sub RemoveAt(index As Integer) Implements IList(Of ConfigurationManager).RemoveAt
|
||||
|
||||
End Sub
|
||||
|
||||
Public Sub Add(item As ConfigurationManager) Implements ICollection(Of ConfigurationManager).Add
|
||||
item.SetConfiguration(GetParentManager)
|
||||
End Sub
|
||||
|
||||
Public Sub Clear() Implements ICollection(Of ConfigurationManager).Clear
|
||||
For Each item As ConfigurationManager In myList
|
||||
item.SetConfiguration(Nothing)
|
||||
Next
|
||||
myList.Clear()
|
||||
End Sub
|
||||
|
||||
Public Sub CopyTo(array() As ConfigurationManager, arrayIndex As Integer) Implements ICollection(Of ConfigurationManager).CopyTo
|
||||
myList.CopyTo(array, arrayIndex)
|
||||
End Sub
|
||||
|
||||
Public Function IndexOf(item As ConfigurationManager) As Integer Implements IList(Of ConfigurationManager).IndexOf
|
||||
Return myList.IndexOf(item)
|
||||
End Function
|
||||
|
||||
Public Function Contains(item As ConfigurationManager) As Boolean Implements ICollection(Of ConfigurationManager).Contains
|
||||
Return myList.Contains(item)
|
||||
End Function
|
||||
|
||||
Public Function Remove(item As ConfigurationManager) As Boolean Implements ICollection(Of ConfigurationManager).Remove
|
||||
item.SetConfiguration(Nothing)
|
||||
Return myList.Remove(item)
|
||||
End Function
|
||||
|
||||
Public Function GetEnumerator() As IEnumerator(Of ConfigurationManager) Implements IEnumerable(Of ConfigurationManager).GetEnumerator
|
||||
Return IEnumerable_GetEnumerator()
|
||||
End Function
|
||||
|
||||
Private Function IEnumerable_GetEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator
|
||||
Return myList.GetEnumerator
|
||||
End Function
|
||||
|
||||
End Class
|
||||
138
Pilz.Configuration/ConfigurationSerializer.cs
Normal file
138
Pilz.Configuration/ConfigurationSerializer.cs
Normal file
@@ -0,0 +1,138 @@
|
||||
using Newtonsoft.Json;
|
||||
using Pilz.GeneralEventArgs;
|
||||
using System.IO;
|
||||
|
||||
namespace Pilz.Configuration;
|
||||
|
||||
public static class ConfigurationSerializer
|
||||
{
|
||||
public static event GettingJsonSerializerEventHandler GettingJsonSerializer;
|
||||
|
||||
public delegate void GettingJsonSerializerEventHandler(object instance, GetValueEventArgs<JsonSerializer> e);
|
||||
|
||||
private static JsonSerializer GetJsonSerializer(SimpleConfiguration instance)
|
||||
{
|
||||
var args = new GetValueEventArgs<JsonSerializer>(JsonSerializer.CreateDefault());
|
||||
GettingJsonSerializer?.Invoke(instance, args);
|
||||
return args.Value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the given instance to a string and return it.
|
||||
/// </summary>
|
||||
/// <param name="instance">The configuration instance that should be serialized.</param>
|
||||
/// <returns>The content of the configuration instance as string.</returns>
|
||||
public static string WriteToString(SimpleConfiguration instance)
|
||||
{
|
||||
var tw = new StringWriter();
|
||||
GetJsonSerializer(instance).Serialize(tw, instance);
|
||||
string txt = tw.ToString();
|
||||
tw.Close();
|
||||
return txt;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write the given instance to a given stream.
|
||||
/// </summary>
|
||||
/// <param name="instance">The configuration instance that should be serialized.</param>
|
||||
/// <param name="stream">The stream where the content should be written to.</param>
|
||||
public static void WriteToStream(SimpleConfiguration instance, Stream stream)
|
||||
{
|
||||
var sr = new StreamWriter(stream);
|
||||
sr.Write(WriteToString(instance));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the given instance to the given filePath as text file.
|
||||
/// </summary>
|
||||
/// <param name="instance">The configuration instance that should be serialized.</param>
|
||||
/// <param name="filePath">The file path where the content should be written to. The file will be created or overwritten.</param>
|
||||
public static void WriteToFile(SimpleConfiguration instance, string filePath)
|
||||
{
|
||||
var fs = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite);
|
||||
WriteToStream(instance, fs);
|
||||
fs.Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a configuratin from the given string and returns an instance of it.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the configuration class to instance.</typeparam>
|
||||
/// <param name="content">The content of the configuration as string.</param>
|
||||
/// <returns></returns>
|
||||
public static T ReadFromString<T>(string content) where T : SimpleConfiguration
|
||||
{
|
||||
var sr = new StringReader(content);
|
||||
T instance = (T)GetJsonSerializer(null).Deserialize(sr, typeof(T));
|
||||
sr.Close();
|
||||
return instance;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a configuration from the given string and put them to the given instance.
|
||||
/// </summary>
|
||||
/// <param name="instance">The instance to populate with the configuration.</param>
|
||||
/// <param name="content">The content of the configuration as string.</param>
|
||||
public static void ReadFromString(SimpleConfiguration instance, string content)
|
||||
{
|
||||
var sr = new StringReader(content);
|
||||
GetJsonSerializer(null).Populate(sr, content);
|
||||
sr.Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a configuratin from the given string and returns an instance of it.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the configuration class to instance.</typeparam>
|
||||
/// <param name="stream">The stream with the content of the configuration.</param>
|
||||
/// <returns></returns>
|
||||
public static T ReadFromStream<T>(Stream stream) where T : SimpleConfiguration
|
||||
{
|
||||
return ReadFromString<T>(GetContentOfStream(stream));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a configuration from the given string and put them to the given instance.
|
||||
/// </summary>
|
||||
/// <param name="instance">The instance to populate with the configuration.</param>
|
||||
/// <param name="stream">The stream with the content of the configuration.</param>
|
||||
public static void ReadFromStream(SimpleConfiguration instance, Stream stream)
|
||||
{
|
||||
ReadFromString(instance, GetContentOfStream(stream));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a configuratin from the given string and returns an instance of it.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the configuration class to instance.</typeparam>
|
||||
/// <param name="filePath">The path to the file with the content of the configuration.</param>
|
||||
/// <returns></returns>
|
||||
public static T ReadFromFile<T>(string filePath) where T : SimpleConfiguration
|
||||
{
|
||||
return ReadFromString<T>(GetContentOfFile(filePath));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a configuration from the given string and put them to the given instance.
|
||||
/// </summary>
|
||||
/// <param name="instance">The instance to populate with the configuration.</param>
|
||||
/// <param name="filePath">The path to the file with the content of the configuration.</param>
|
||||
public static void ReadFromFile(SimpleConfiguration instance, string filePath)
|
||||
{
|
||||
ReadFromString(instance, GetContentOfFile(filePath));
|
||||
}
|
||||
|
||||
private static string GetContentOfStream(Stream stream)
|
||||
{
|
||||
var sr = new StreamReader(stream);
|
||||
return sr.ReadToEnd();
|
||||
}
|
||||
|
||||
private static string GetContentOfFile(string filePath)
|
||||
{
|
||||
var fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
|
||||
string content = GetContentOfStream(fs);
|
||||
fs.Close();
|
||||
return content;
|
||||
}
|
||||
}
|
||||
@@ -1,123 +0,0 @@
|
||||
Imports System.IO
|
||||
Imports Newtonsoft.Json
|
||||
Imports Pilz.GeneralEventArgs
|
||||
|
||||
Public Module ConfigurationSerializer
|
||||
|
||||
Public Event GettingJsonSerializer(instance As Object, e As GetValueEventArgs(Of JsonSerializer))
|
||||
|
||||
Private Function GetJsonSerializer(instance As SimpleConfiguration) As JsonSerializer
|
||||
Dim args As New GetValueEventArgs(Of JsonSerializer)(JsonSerializer.CreateDefault)
|
||||
RaiseEvent GettingJsonSerializer(instance, args)
|
||||
Return args.Value
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Writes the given instance to a string and return it.
|
||||
''' </summary>
|
||||
''' <param name="instance">The configuration instance that should be serialized.</param>
|
||||
''' <returns>The content of the configuration instance as string.</returns>
|
||||
Public Function WriteToString(instance As SimpleConfiguration) As String
|
||||
Dim tw As New StringWriter
|
||||
GetJsonSerializer(instance).Serialize(tw, instance)
|
||||
Dim txt = tw.ToString
|
||||
tw.Close()
|
||||
Return txt
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Write the given instance to a given stream.
|
||||
''' </summary>
|
||||
''' <param name="instance">The configuration instance that should be serialized.</param>
|
||||
''' <param name="stream">The stream where the content should be written to.</param>
|
||||
Public Sub WriteToStream(instance As SimpleConfiguration, stream As Stream)
|
||||
Dim sr As New StreamWriter(stream)
|
||||
sr.Write(WriteToString(instance))
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Writes the given instance to the given filePath as text file.
|
||||
''' </summary>
|
||||
''' <param name="instance">The configuration instance that should be serialized.</param>
|
||||
''' <param name="filePath">The file path where the content should be written to. The file will be created or overwritten.</param>
|
||||
Public Sub WriteToFile(instance As SimpleConfiguration, filePath As String)
|
||||
Dim fs As New FileStream(filePath, FileMode.Create, FileAccess.ReadWrite)
|
||||
WriteToStream(instance, fs)
|
||||
fs.Close()
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Reads a configuratin from the given string and returns an instance of it.
|
||||
''' </summary>
|
||||
''' <typeparam name="T">The type of the configuration class to instance.</typeparam>
|
||||
''' <param name="content">The content of the configuration as string.</param>
|
||||
''' <returns></returns>
|
||||
Public Function ReadFromString(Of T As SimpleConfiguration)(content As String) As T
|
||||
Dim sr As New StringReader(content)
|
||||
Dim instance As T = GetJsonSerializer(Nothing).Deserialize(sr, GetType(T))
|
||||
sr.Close()
|
||||
Return instance
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Read a configuration from the given string and put them to the given instance.
|
||||
''' </summary>
|
||||
''' <param name="instance">The instance to populate with the configuration.</param>
|
||||
''' <param name="content">The content of the configuration as string.</param>
|
||||
Public Sub ReadFromString(instance As SimpleConfiguration, content As String)
|
||||
Dim sr As New StringReader(content)
|
||||
GetJsonSerializer(Nothing).Populate(sr, content)
|
||||
sr.Close()
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Reads a configuratin from the given string and returns an instance of it.
|
||||
''' </summary>
|
||||
''' <typeparam name="T">The type of the configuration class to instance.</typeparam>
|
||||
''' <param name="stream">The stream with the content of the configuration.</param>
|
||||
''' <returns></returns>
|
||||
Public Function ReadFromStream(Of T As SimpleConfiguration)(stream As Stream) As T
|
||||
Return ReadFromString(Of T)(GetContentOfStream(stream))
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Read a configuration from the given string and put them to the given instance.
|
||||
''' </summary>
|
||||
''' <param name="instance">The instance to populate with the configuration.</param>
|
||||
''' <param name="stream">The stream with the content of the configuration.</param>
|
||||
Public Sub ReadFromStream(instance As SimpleConfiguration, stream As Stream)
|
||||
ReadFromString(instance, GetContentOfStream(stream))
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Reads a configuratin from the given string and returns an instance of it.
|
||||
''' </summary>
|
||||
''' <typeparam name="T">The type of the configuration class to instance.</typeparam>
|
||||
''' <param name="filePath">The path to the file with the content of the configuration.</param>
|
||||
''' <returns></returns>
|
||||
Public Function ReadFromFile(Of T As SimpleConfiguration)(filePath As String) As T
|
||||
Return ReadFromString(Of T)(GetContentOfFile(filePath))
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Read a configuration from the given string and put them to the given instance.
|
||||
''' </summary>
|
||||
''' <param name="instance">The instance to populate with the configuration.</param>
|
||||
''' <param name="filePath">The path to the file with the content of the configuration.</param>
|
||||
Public Sub ReadFromFile(instance As SimpleConfiguration, filePath As String)
|
||||
ReadFromString(instance, GetContentOfFile(filePath))
|
||||
End Sub
|
||||
|
||||
Private Function GetContentOfStream(stream As Stream) As String
|
||||
Dim sr As New StreamReader(stream)
|
||||
Return sr.ReadToEnd
|
||||
End Function
|
||||
|
||||
Private Function GetContentOfFile(filePath As String) As String
|
||||
Dim fs As New FileStream(filePath, FileMode.Open, FileAccess.Read)
|
||||
Dim content = GetContentOfStream(fs)
|
||||
fs.Close()
|
||||
Return content
|
||||
End Function
|
||||
|
||||
End Module
|
||||
16
Pilz.Configuration/ISettings.cs
Normal file
16
Pilz.Configuration/ISettings.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using Castle.Core.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Pilz.Configuration;
|
||||
|
||||
public interface ISettings
|
||||
{
|
||||
IReadOnlyCollection<ISettingsNode> Childs { get; }
|
||||
ILogger Logger { get; set; }
|
||||
|
||||
T Get<T>() where T : ISettingsNode, ISettingsIdentifier;
|
||||
void Reset();
|
||||
string Save(JsonSerializerSettings serializer);
|
||||
bool Load(JsonSerializerSettings serializer, string raw);
|
||||
}
|
||||
8
Pilz.Configuration/ISettingsIdentifier.cs
Normal file
8
Pilz.Configuration/ISettingsIdentifier.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Pilz.Configuration;
|
||||
|
||||
public interface ISettingsIdentifier
|
||||
{
|
||||
#if NET8_0_OR_GREATER
|
||||
static abstract string Identifier { get; }
|
||||
#endif
|
||||
}
|
||||
10
Pilz.Configuration/ISettingsManager.cs
Normal file
10
Pilz.Configuration/ISettingsManager.cs
Normal file
@@ -0,0 +1,10 @@
|
||||
|
||||
namespace Pilz.Configuration;
|
||||
|
||||
public interface ISettingsManager
|
||||
{
|
||||
ISettings Instance { get; }
|
||||
void Save();
|
||||
void Load();
|
||||
void Reset();
|
||||
}
|
||||
@@ -1,6 +0,0 @@
|
||||
Public Interface ISettingsManager
|
||||
Property ConfigFilePath As String
|
||||
Sub Save()
|
||||
Sub Load()
|
||||
Sub Reset()
|
||||
End Interface
|
||||
11
Pilz.Configuration/ISettingsNode.cs
Normal file
11
Pilz.Configuration/ISettingsNode.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
using System;
|
||||
|
||||
namespace Pilz.Configuration;
|
||||
|
||||
public interface ISettingsNode
|
||||
{
|
||||
void Reset();
|
||||
}
|
||||
|
||||
[Obsolete("Use ISettingsNode instead!")]
|
||||
public interface IChildSettings : ISettingsNode;
|
||||
6
Pilz.Configuration/ISettingsValueOptionValueAccessor.cs
Normal file
6
Pilz.Configuration/ISettingsValueOptionValueAccessor.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace Pilz.Configuration;
|
||||
|
||||
internal interface ISettingsValueOptionValueAccessor
|
||||
{
|
||||
public object ValueRaw { get; set; }
|
||||
}
|
||||
@@ -1,13 +0,0 @@
|
||||
'------------------------------------------------------------------------------
|
||||
' <auto-generated>
|
||||
' Dieser Code wurde von einem Tool generiert.
|
||||
' Laufzeitversion:4.0.30319.42000
|
||||
'
|
||||
' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
|
||||
' der Code erneut generiert wird.
|
||||
' </auto-generated>
|
||||
'------------------------------------------------------------------------------
|
||||
|
||||
Option Strict On
|
||||
Option Explicit On
|
||||
|
||||
@@ -1,10 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<MyApplicationData xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
|
||||
<MySubMain>false</MySubMain>
|
||||
<SingleInstance>false</SingleInstance>
|
||||
<ShutdownMode>0</ShutdownMode>
|
||||
<EnableVisualStyles>true</EnableVisualStyles>
|
||||
<AuthenticationMode>0</AuthenticationMode>
|
||||
<ApplicationType>1</ApplicationType>
|
||||
<SaveMySettingsOnExit>true</SaveMySettingsOnExit>
|
||||
</MyApplicationData>
|
||||
63
Pilz.Configuration/My Project/Resources.Designer.vb
generated
63
Pilz.Configuration/My Project/Resources.Designer.vb
generated
@@ -1,63 +0,0 @@
|
||||
'------------------------------------------------------------------------------
|
||||
' <auto-generated>
|
||||
' Dieser Code wurde von einem Tool generiert.
|
||||
' Laufzeitversion:4.0.30319.42000
|
||||
'
|
||||
' Änderungen an dieser Datei können falsches Verhalten verursachen und gehen verloren, wenn
|
||||
' der Code erneut generiert wird.
|
||||
' </auto-generated>
|
||||
'------------------------------------------------------------------------------
|
||||
|
||||
Option Strict On
|
||||
Option Explicit On
|
||||
|
||||
Imports System
|
||||
|
||||
Namespace My.Resources
|
||||
|
||||
'Diese Klasse wurde von der StronglyTypedResourceBuilder automatisch generiert
|
||||
'-Klasse über ein Tool wie ResGen oder Visual Studio automatisch generiert.
|
||||
'Um einen Member hinzuzufügen oder zu entfernen, bearbeiten Sie die .ResX-Datei und führen dann ResGen
|
||||
'mit der /str-Option erneut aus, oder Sie erstellen Ihr VS-Projekt neu.
|
||||
'''<summary>
|
||||
''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
|
||||
'''</summary>
|
||||
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0"), _
|
||||
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
|
||||
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
|
||||
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
|
||||
Friend Module Resources
|
||||
|
||||
Private resourceMan As Global.System.Resources.ResourceManager
|
||||
|
||||
Private resourceCulture As Global.System.Globalization.CultureInfo
|
||||
|
||||
'''<summary>
|
||||
''' Gibt die zwischengespeicherte ResourceManager-Instanz zurück, die von dieser Klasse verwendet wird.
|
||||
'''</summary>
|
||||
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||
Friend ReadOnly Property ResourceManager() As Global.System.Resources.ResourceManager
|
||||
Get
|
||||
If Object.ReferenceEquals(resourceMan, Nothing) Then
|
||||
Dim temp As Global.System.Resources.ResourceManager = New Global.System.Resources.ResourceManager("Pilz.Configuration.Resources", GetType(Resources).Assembly)
|
||||
resourceMan = temp
|
||||
End If
|
||||
Return resourceMan
|
||||
End Get
|
||||
End Property
|
||||
|
||||
'''<summary>
|
||||
''' Überschreibt die CurrentUICulture-Eigenschaft des aktuellen Threads für alle
|
||||
''' Ressourcenzuordnungen, die diese stark typisierte Ressourcenklasse verwenden.
|
||||
'''</summary>
|
||||
<Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
|
||||
Friend Property Culture() As Global.System.Globalization.CultureInfo
|
||||
Get
|
||||
Return resourceCulture
|
||||
End Get
|
||||
Set
|
||||
resourceCulture = value
|
||||
End Set
|
||||
End Property
|
||||
End Module
|
||||
End Namespace
|
||||
@@ -1,117 +0,0 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
<xsd:complexType>
|
||||
<xsd:choice maxOccurs="unbounded">
|
||||
<xsd:element name="metadata">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
<xsd:attribute name="type" type="xsd:string" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="assembly">
|
||||
<xsd:complexType>
|
||||
<xsd:attribute name="alias" type="xsd:string" />
|
||||
<xsd:attribute name="name" type="xsd:string" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="data">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
<xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" msdata:Ordinal="1" />
|
||||
<xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
|
||||
<xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
<xsd:element name="resheader">
|
||||
<xsd:complexType>
|
||||
<xsd:sequence>
|
||||
<xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
|
||||
</xsd:sequence>
|
||||
<xsd:attribute name="name" type="xsd:string" use="required" />
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:choice>
|
||||
</xsd:complexType>
|
||||
</xsd:element>
|
||||
</xsd:schema>
|
||||
<resheader name="resmimetype">
|
||||
<value>text/microsoft-resx</value>
|
||||
</resheader>
|
||||
<resheader name="version">
|
||||
<value>2.0</value>
|
||||
</resheader>
|
||||
<resheader name="reader">
|
||||
<value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
</root>
|
||||
22
Pilz.Configuration/Pilz.Configuration.csproj
Normal file
22
Pilz.Configuration/Pilz.Configuration.csproj
Normal file
@@ -0,0 +1,22 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net8.0;netstandard2.0</TargetFrameworks>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<Nullable>disable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<Version>3.2.8</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Castle.Core" Version="5.2.1" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Pilz\Pilz.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,73 +0,0 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<MyType>Windows</MyType>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||
<DocumentationFile>Pilz.Configuration.xml</DocumentationFile>
|
||||
<DefineTrace>true</DefineTrace>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DefineDebug>true</DefineDebug>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
|
||||
<DefineDebug>false</DefineDebug>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<OptionExplicit>On</OptionExplicit>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<OptionCompare>Binary</OptionCompare>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<OptionStrict>Off</OptionStrict>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<OptionInfer>On</OptionInfer>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
|
||||
<PackageReference Include="System.Net.Http" Version="4.3.4" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Import Include="Microsoft.VisualBasic" />
|
||||
<Import Include="System" />
|
||||
<Import Include="System.Collections" />
|
||||
<Import Include="System.Collections.Generic" />
|
||||
<Import Include="System.Data" />
|
||||
<Import Include="System.Diagnostics" />
|
||||
<Import Include="System.Linq" />
|
||||
<Import Include="System.Xml.Linq" />
|
||||
<Import Include="System.Threading.Tasks" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Update="My Project\Application.Designer.vb">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Application.myapp</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="My Project\Resources.Designer.vb">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DesignTime>True</DesignTime>
|
||||
<DependentUpon>Resources.resx</DependentUpon>
|
||||
</Compile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Update="My Project\Resources.resx">
|
||||
<Generator>VbMyResourcesResXFileCodeGenerator</Generator>
|
||||
<LastGenOutput>Resources.Designer.vb</LastGenOutput>
|
||||
<CustomToolNamespace>My.Resources</CustomToolNamespace>
|
||||
<SubType>Designer</SubType>
|
||||
</EmbeddedResource>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="My Project\Application.myapp">
|
||||
<Generator>MyApplicationCodeGenerator</Generator>
|
||||
<LastGenOutput>Application.Designer.vb</LastGenOutput>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Pilz\Pilz.vbproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
143
Pilz.Configuration/Settings.cs
Normal file
143
Pilz.Configuration/Settings.cs
Normal file
@@ -0,0 +1,143 @@
|
||||
using Castle.Core.Logging;
|
||||
using Newtonsoft.Json;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace Pilz.Configuration;
|
||||
|
||||
public class Settings : ISettings
|
||||
{
|
||||
protected readonly Dictionary<string, JObject> settingsJson = [];
|
||||
protected readonly Dictionary<string, ISettingsNode> settings = [];
|
||||
protected JsonSerializerSettings serializerSettings;
|
||||
|
||||
public virtual IReadOnlyCollection<ISettingsNode> Childs => settings.Values;
|
||||
public virtual ILogger Logger { get; set; } = NullLogger.Instance;
|
||||
|
||||
public virtual T Get<T>() where T : ISettingsNode, ISettingsIdentifier
|
||||
{
|
||||
// Find existing one
|
||||
if (settings.TryGetValue(GetIdentifier<T>(), out var valueExisting) && valueExisting is T settingsExisting)
|
||||
return settingsExisting;
|
||||
|
||||
// Create new & reset
|
||||
if (Activator.CreateInstance<T>() is T settingsNew)
|
||||
settingsNew.Reset();
|
||||
else
|
||||
{
|
||||
settingsNew = default;
|
||||
Logger.WarnFormat("Not able to create new settings node instance {0}.", GetIdentifier<T>());
|
||||
}
|
||||
|
||||
// Try deserialize
|
||||
if (settingsJson.TryGetValue(GetIdentifier<T>(), out var valueRaw))
|
||||
{
|
||||
var serializer = JsonSerializer.CreateDefault(serializerSettings);
|
||||
|
||||
// Populate
|
||||
if (settingsNew != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
serializer.Populate(valueRaw.CreateReader(), settingsNew);
|
||||
Logger.InfoFormat("Populated settings node {0}.", GetIdentifier<T>());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error("Error populating settings node instance.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
// Deserialize (fallback)
|
||||
else if (valueRaw.ToObject<T>() is T settingsDeserialized)
|
||||
{
|
||||
try
|
||||
{
|
||||
settingsNew = settingsDeserialized;
|
||||
Logger.WarnFormat("Deserialied settings node {0} via fallback variant.", GetIdentifier<T>());
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Error("Error deserializing settings node instance.", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Remember
|
||||
if (settingsNew != null)
|
||||
settings[GetIdentifier<T>()] = settingsNew;
|
||||
|
||||
// Return
|
||||
return settingsNew;
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
foreach (var s in settings.Values)
|
||||
s.Reset();
|
||||
}
|
||||
|
||||
public virtual string Save(JsonSerializerSettings serializerSettings)
|
||||
{
|
||||
this.serializerSettings = serializerSettings;
|
||||
var serializer = JsonSerializer.CreateDefault(serializerSettings);
|
||||
|
||||
foreach (var kvp in settings)
|
||||
{
|
||||
var raw = JObject.FromObject(kvp.Value, serializer);
|
||||
settingsJson[kvp.Key] = raw;
|
||||
}
|
||||
|
||||
var objList = new JObject();
|
||||
foreach (var kvp in settingsJson)
|
||||
objList.Add(kvp.Key, kvp.Value);
|
||||
|
||||
var objSettings = new JObject
|
||||
{
|
||||
{ "Settings", objList }
|
||||
};
|
||||
|
||||
return objSettings.ToString(serializer.Formatting);
|
||||
}
|
||||
|
||||
public virtual bool Load(JsonSerializerSettings serializerSettings, string raw)
|
||||
{
|
||||
this.serializerSettings = serializerSettings;
|
||||
|
||||
var objSettings = JObject.Parse(raw);
|
||||
if (!objSettings.TryGetValue("Settings", out var tokenList) || tokenList is not JObject objList)
|
||||
return false;
|
||||
|
||||
settingsJson.Clear();
|
||||
settings.Clear();
|
||||
|
||||
foreach (var child in objList)
|
||||
{
|
||||
if (child.Value is not JObject value)
|
||||
continue;
|
||||
|
||||
settingsJson.Add(child.Key, value);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
protected virtual JToken Serialize(object o, JsonSerializer jsonSerializer)
|
||||
{
|
||||
using JTokenWriter jTokenWriter = new JTokenWriter();
|
||||
jsonSerializer.Serialize(jTokenWriter, o, o.GetType());
|
||||
return jTokenWriter.Token;
|
||||
}
|
||||
|
||||
|
||||
|
||||
protected static string GetIdentifier<T>() where T : ISettingsIdentifier
|
||||
{
|
||||
#if NET8_0_OR_GREATER
|
||||
return T.Identifier;
|
||||
#else
|
||||
return typeof(T).GetProperty("Identifier", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.Public).GetValue(null) as string;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -1,20 +0,0 @@
|
||||
Imports Newtonsoft.Json
|
||||
|
||||
Public MustInherit Class SettingsBase
|
||||
|
||||
Public Sub New()
|
||||
ResetValues()
|
||||
End Sub
|
||||
|
||||
<JsonIgnore>
|
||||
Friend _settingsManager As ISettingsManager
|
||||
<JsonIgnore>
|
||||
Public ReadOnly Property SettingsManager As ISettingsManager
|
||||
Get
|
||||
Return _settingsManager
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Public MustOverride Sub ResetValues()
|
||||
|
||||
End Class
|
||||
145
Pilz.Configuration/SettingsManager.cs
Normal file
145
Pilz.Configuration/SettingsManager.cs
Normal file
@@ -0,0 +1,145 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.IO;
|
||||
using ErrorEventArgs = Newtonsoft.Json.Serialization.ErrorEventArgs;
|
||||
|
||||
namespace Pilz.Configuration;
|
||||
|
||||
public class SettingsManager : ISettingsManager
|
||||
{
|
||||
public event EventHandler AutoSavingSettings;
|
||||
public event EventHandler SavingSettings;
|
||||
public event EventHandler SavedSettings;
|
||||
public event EventHandler<ErrorEventArgs> OnSerializationError;
|
||||
|
||||
protected ISettings defaultInstance = null;
|
||||
protected bool enableAutoSave = false;
|
||||
protected bool addedHandler = false;
|
||||
|
||||
public string ConfigFilePath { get; set; }
|
||||
|
||||
public ISettings Instance
|
||||
{
|
||||
get
|
||||
{
|
||||
if (defaultInstance is null)
|
||||
Load();
|
||||
return defaultInstance;
|
||||
}
|
||||
}
|
||||
|
||||
public bool AutoSaveOnExit
|
||||
{
|
||||
get => enableAutoSave;
|
||||
set
|
||||
{
|
||||
if (enableAutoSave != value)
|
||||
{
|
||||
enableAutoSave = value;
|
||||
if (enableAutoSave)
|
||||
{
|
||||
if (!addedHandler)
|
||||
AddAutoSaveHandler();
|
||||
}
|
||||
else
|
||||
{
|
||||
if (addedHandler)
|
||||
RemoveAutoSaveHandler();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public SettingsManager()
|
||||
{
|
||||
}
|
||||
|
||||
public SettingsManager(string fileName, bool autoSaveOnExit) : this()
|
||||
{
|
||||
ConfigFilePath = fileName;
|
||||
AutoSaveOnExit = autoSaveOnExit;
|
||||
}
|
||||
|
||||
protected void AddAutoSaveHandler()
|
||||
{
|
||||
AppDomain.CurrentDomain.ProcessExit += AutoSaveSettingsOnExit;
|
||||
addedHandler = true;
|
||||
}
|
||||
|
||||
protected void RemoveAutoSaveHandler()
|
||||
{
|
||||
AppDomain.CurrentDomain.ProcessExit -= AutoSaveSettingsOnExit;
|
||||
addedHandler = false;
|
||||
}
|
||||
|
||||
private void AutoSaveSettingsOnExit(object sender, EventArgs e)
|
||||
{
|
||||
AutoSavingSettings?.Invoke(this, new EventArgs());
|
||||
Save();
|
||||
}
|
||||
|
||||
public void Save()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(ConfigFilePath) && defaultInstance is not null)
|
||||
SaveInternal();
|
||||
}
|
||||
|
||||
public void Load()
|
||||
{
|
||||
if (!string.IsNullOrEmpty(ConfigFilePath) && File.Exists(ConfigFilePath))
|
||||
LoadInternal();
|
||||
else
|
||||
CreateNewInstance();
|
||||
}
|
||||
|
||||
public void Reset()
|
||||
{
|
||||
Instance.Reset();
|
||||
}
|
||||
|
||||
protected virtual ISettings CreateInstance()
|
||||
{
|
||||
return new Settings();
|
||||
}
|
||||
|
||||
protected virtual void CreateNewInstance()
|
||||
{
|
||||
defaultInstance = CreateInstance();
|
||||
defaultInstance.Reset();
|
||||
}
|
||||
|
||||
protected virtual void LoadInternal()
|
||||
{
|
||||
defaultInstance = CreateInstance();
|
||||
defaultInstance.Load(CreateJsonSerializerSettings(), File.ReadAllText(ConfigFilePath));
|
||||
}
|
||||
|
||||
protected virtual void SaveInternal()
|
||||
{
|
||||
SavingSettings?.Invoke(this, EventArgs.Empty);
|
||||
File.WriteAllText(ConfigFilePath, defaultInstance.Save(CreateJsonSerializerSettings()));
|
||||
SavedSettings?.Invoke(this, EventArgs.Empty);
|
||||
}
|
||||
|
||||
public virtual JsonSerializerSettings CreateJsonSerializerSettings()
|
||||
{
|
||||
return new JsonSerializerSettings
|
||||
{
|
||||
Formatting = Formatting.Indented,
|
||||
TypeNameHandling = TypeNameHandling.Auto,
|
||||
Error = JsonSerializer_OnError,
|
||||
};
|
||||
}
|
||||
|
||||
protected virtual void JsonSerializer_OnError(object sender, ErrorEventArgs e)
|
||||
{
|
||||
const string errorResolvingType = "Error resolving type specified in JSON";
|
||||
|
||||
// Invoke event
|
||||
OnSerializationError?.Invoke(sender, e);
|
||||
|
||||
// Handle ourself
|
||||
if (!e.ErrorContext.Handled && e.ErrorContext.Error is JsonSerializationException serializationException && serializationException.Message.StartsWith(errorResolvingType))
|
||||
e.ErrorContext.Handled = true;
|
||||
}
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
Imports System.IO
|
||||
Imports System.Reflection
|
||||
Imports Newtonsoft.Json.Linq
|
||||
|
||||
Public NotInheritable Class SettingsManager(Of T As SettingsBase)
|
||||
Implements ISettingsManager
|
||||
|
||||
Public Event AutoSavingSettings As EventHandler
|
||||
Public Event SavingSettings As EventHandler
|
||||
Public Event SavedSettings As EventHandler
|
||||
|
||||
Private defaultInstance As T = Nothing
|
||||
Private enableAutoSave As Boolean = False
|
||||
Private addedHandler As Boolean = False
|
||||
|
||||
Public Property ConfigFilePath As String Implements ISettingsManager.ConfigFilePath
|
||||
|
||||
Public Property AutoSaveOnExit As Boolean
|
||||
Get
|
||||
Return enableAutoSave
|
||||
End Get
|
||||
Set
|
||||
If enableAutoSave <> Value Then
|
||||
enableAutoSave = Value
|
||||
Select Case enableAutoSave
|
||||
Case True
|
||||
If Not addedHandler Then
|
||||
AddAutoSaveHandler()
|
||||
End If
|
||||
Case False
|
||||
If addedHandler Then
|
||||
RemoveAutoSaveHandler()
|
||||
End If
|
||||
End Select
|
||||
End If
|
||||
End Set
|
||||
End Property
|
||||
|
||||
Private Sub AddAutoSaveHandler()
|
||||
AddHandler AppDomain.CurrentDomain.ProcessExit, AddressOf AutoSaveSettingsOnExit
|
||||
addedHandler = True
|
||||
End Sub
|
||||
Private Sub RemoveAutoSaveHandler()
|
||||
RemoveHandler AppDomain.CurrentDomain.ProcessExit, AddressOf AutoSaveSettingsOnExit
|
||||
addedHandler = False
|
||||
End Sub
|
||||
|
||||
Public ReadOnly Property Instance As T
|
||||
Get
|
||||
If defaultInstance Is Nothing Then
|
||||
Load()
|
||||
End If
|
||||
Return defaultInstance
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Public Sub New()
|
||||
ConfigFilePath = ""
|
||||
AutoSaveOnExit = False
|
||||
End Sub
|
||||
Public Sub New(fileName As String, autoSaveOnExit As Boolean)
|
||||
ConfigFilePath = fileName
|
||||
Me.AutoSaveOnExit = autoSaveOnExit
|
||||
End Sub
|
||||
|
||||
Private Sub AutoSaveSettingsOnExit(sender As Object, e As EventArgs)
|
||||
RaiseEvent AutoSavingSettings(Me, New EventArgs)
|
||||
Save()
|
||||
End Sub
|
||||
|
||||
Public Sub Save() Implements ISettingsManager.Save
|
||||
If Not String.IsNullOrEmpty(ConfigFilePath) AndAlso defaultInstance IsNot Nothing Then
|
||||
SavePrivate()
|
||||
End If
|
||||
End Sub
|
||||
|
||||
Public Sub Load() Implements ISettingsManager.Load
|
||||
If Not String.IsNullOrEmpty(ConfigFilePath) AndAlso File.Exists(ConfigFilePath) Then
|
||||
LoadPrivate()
|
||||
Else
|
||||
CreateNewInstance()
|
||||
End If
|
||||
|
||||
If defaultInstance IsNot Nothing Then
|
||||
defaultInstance._settingsManager = Me
|
||||
End If
|
||||
End Sub
|
||||
|
||||
Public Sub Reset() Implements ISettingsManager.Reset
|
||||
Instance.ResetValues()
|
||||
End Sub
|
||||
|
||||
Private Sub CreateNewInstance()
|
||||
Dim ctor As ConstructorInfo = GetType(T).GetConstructor({})
|
||||
If ctor IsNot Nothing Then
|
||||
defaultInstance = ctor.Invoke({})
|
||||
|
||||
defaultInstance.ResetValues()
|
||||
Else
|
||||
Throw New Exception("The base type has no constructor with no parameters.")
|
||||
End If
|
||||
End Sub
|
||||
|
||||
Private Sub LoadPrivate()
|
||||
defaultInstance = JObject.Parse(File.ReadAllText(ConfigFilePath)).ToObject(Of T)
|
||||
End Sub
|
||||
|
||||
Private Sub SavePrivate()
|
||||
RaiseEvent SavingSettings(Me, New EventArgs)
|
||||
|
||||
Dim obj As JObject = JObject.FromObject(defaultInstance)
|
||||
If obj IsNot Nothing Then
|
||||
File.WriteAllText(ConfigFilePath, obj.ToString)
|
||||
End If
|
||||
|
||||
RaiseEvent SavedSettings(Me, New EventArgs)
|
||||
End Sub
|
||||
|
||||
End Class
|
||||
56
Pilz.Configuration/SettingsValueOption.cs
Normal file
56
Pilz.Configuration/SettingsValueOption.cs
Normal file
@@ -0,0 +1,56 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
|
||||
namespace Pilz.Configuration;
|
||||
|
||||
[JsonObject(ItemNullValueHandling = NullValueHandling.Ignore)]
|
||||
[JsonConverter(typeof(SettingsValueOptionJsonConverter))]
|
||||
public class SettingsValueOption<T> : ISettingsValueOptionValueAccessor where T : struct
|
||||
{
|
||||
protected T? value;
|
||||
|
||||
public T DefaultValue { get; }
|
||||
public virtual bool IsDefault => value == null;
|
||||
|
||||
public SettingsValueOption()
|
||||
{
|
||||
}
|
||||
|
||||
public SettingsValueOption(T value)
|
||||
{
|
||||
DefaultValue = value;
|
||||
}
|
||||
|
||||
public virtual T Value
|
||||
{
|
||||
get => value ?? DefaultValue;
|
||||
set => this.value = value;
|
||||
}
|
||||
|
||||
public static implicit operator T(SettingsValueOption<T> option)
|
||||
{
|
||||
return option.Value;
|
||||
}
|
||||
|
||||
object ISettingsValueOptionValueAccessor.ValueRaw
|
||||
{
|
||||
get => value;
|
||||
set
|
||||
{
|
||||
if (value is not null)
|
||||
this.value = Convert.ChangeType(value, typeof(T)) as T?;
|
||||
else
|
||||
this.value = null;
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Reset()
|
||||
{
|
||||
value = null;
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return Value.ToString();
|
||||
}
|
||||
}
|
||||
27
Pilz.Configuration/SettingsValueOptionJsonConverter.cs
Normal file
27
Pilz.Configuration/SettingsValueOptionJsonConverter.cs
Normal file
@@ -0,0 +1,27 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
|
||||
namespace Pilz.Configuration;
|
||||
|
||||
public class SettingsValueOptionJsonConverter : JsonConverter
|
||||
{
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (existingValue is ISettingsValueOptionValueAccessor option)
|
||||
option.ValueRaw = reader.Value;
|
||||
return existingValue;
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
if (value is ISettingsValueOptionValueAccessor option)
|
||||
writer.WriteValue(option.ValueRaw);
|
||||
else
|
||||
writer.WriteNull();
|
||||
}
|
||||
}
|
||||
109
Pilz.Configuration/SimpleConfiguration.cs
Normal file
109
Pilz.Configuration/SimpleConfiguration.cs
Normal file
@@ -0,0 +1,109 @@
|
||||
using Newtonsoft.Json;
|
||||
using Pilz.GeneralEventArgs;
|
||||
using System.IO;
|
||||
|
||||
namespace Pilz.Configuration;
|
||||
|
||||
public class SimpleConfiguration
|
||||
{
|
||||
[JsonIgnore]
|
||||
public readonly ConfigurationManagerList Managers = [];
|
||||
|
||||
public SimpleConfiguration()
|
||||
{
|
||||
Managers.GettingParentManager += Managers_GettingParentManager;
|
||||
}
|
||||
|
||||
private void Managers_GettingParentManager(object sender, GetValueEventArgs<SimpleConfiguration> e)
|
||||
{
|
||||
if (ReferenceEquals(sender, Managers))
|
||||
e.Value = this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes this instance to a string and return it.
|
||||
/// </summary>
|
||||
/// <returns>The content of the configuration instance as string.</returns>
|
||||
public string WriteToString()
|
||||
{
|
||||
return ConfigurationSerializer.WriteToString(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Write this instance to a given stream.
|
||||
/// </summary>
|
||||
/// <param name="stream">The stream where the content should be written to.</param>
|
||||
public void WriteToStream(Stream stream)
|
||||
{
|
||||
ConfigurationSerializer.WriteToStream(this, stream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes this instance to the given filePath as text file.
|
||||
/// </summary>
|
||||
/// <param name="filePath">The file path where the content should be written to. The file will be created or overwritten.</param>
|
||||
public void WriteToFile(string filePath)
|
||||
{
|
||||
ConfigurationSerializer.WriteToFile(this, filePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a configuratin from the given string and returns an instance of it.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the configuration class to instance.</typeparam>
|
||||
/// <param name="content">The content of the configuration as string.</param>
|
||||
/// <returns></returns>
|
||||
public static T ReadFromString<T>(string content) where T : SimpleConfiguration
|
||||
{
|
||||
return ConfigurationSerializer.ReadFromString<T>(content);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a configuration from the given string and put them to this instance.
|
||||
/// </summary>
|
||||
/// <param name="content">The content of the configuration as string.</param>
|
||||
public void ReadFromString(string content)
|
||||
{
|
||||
ConfigurationSerializer.ReadFromString(this, content);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a configuratin from the given string and returns an instance of it.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the configuration class to instance.</typeparam>
|
||||
/// <param name="stream">The stream with the content of the configuration.</param>
|
||||
/// <returns></returns>
|
||||
public static T ReadFromStream<T>(Stream stream) where T : SimpleConfiguration
|
||||
{
|
||||
return ConfigurationSerializer.ReadFromStream<T>(stream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a configuration from the given string and put them to this instance.
|
||||
/// </summary>
|
||||
/// <param name="stream">The stream with the content of the configuration.</param>
|
||||
public void ReadFromStream(Stream stream)
|
||||
{
|
||||
ConfigurationSerializer.ReadFromStream(this, stream);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads a configuratin from the given string and returns an instance of it.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The type of the configuration class to instance.</typeparam>
|
||||
/// <param name="filePath">The path to the file with the content of the configuration.</param>
|
||||
/// <returns></returns>
|
||||
public static T ReadFromFile<T>(string filePath) where T : SimpleConfiguration
|
||||
{
|
||||
return ConfigurationSerializer.ReadFromFile<T>(filePath);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Read a configuration from the given string and put them to this instance.
|
||||
/// </summary>
|
||||
/// <param name="filePath">The path to the file with the content of the configuration.</param>
|
||||
public void ReadFromFile(string filePath)
|
||||
{
|
||||
ConfigurationSerializer.ReadFromFile(this, filePath);
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
Imports System.IO
|
||||
Imports Newtonsoft.Json
|
||||
Imports Pilz.Configuration
|
||||
Imports Pilz.GeneralEventArgs
|
||||
|
||||
Public Class SimpleConfiguration
|
||||
|
||||
<JsonIgnore>
|
||||
Public ReadOnly Managers As New ConfigurationManagerList
|
||||
|
||||
Public Sub New()
|
||||
AddHandler Managers.GettingParentManager, AddressOf Managers_GettingParentManager
|
||||
End Sub
|
||||
|
||||
Private Sub Managers_GettingParentManager(sender As Object, e As GetValueEventArgs(Of SimpleConfiguration))
|
||||
If sender Is Managers Then
|
||||
e.Value = Me
|
||||
End If
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Writes this instance to a string and return it.
|
||||
''' </summary>
|
||||
''' <returns>The content of the configuration instance as string.</returns>
|
||||
Public Function WriteToString() As String
|
||||
Return ConfigurationSerializer.WriteToString(Me)
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Write this instance to a given stream.
|
||||
''' </summary>
|
||||
''' <param name="stream">The stream where the content should be written to.</param>
|
||||
Public Sub WriteToStream(stream As Stream)
|
||||
ConfigurationSerializer.WriteToStream(Me, stream)
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Writes this instance to the given filePath as text file.
|
||||
''' </summary>
|
||||
''' <param name="filePath">The file path where the content should be written to. The file will be created or overwritten.</param>
|
||||
Public Sub WriteToFile(filePath As String)
|
||||
ConfigurationSerializer.WriteToFile(Me, filePath)
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Reads a configuratin from the given string and returns an instance of it.
|
||||
''' </summary>
|
||||
''' <typeparam name="T">The type of the configuration class to instance.</typeparam>
|
||||
''' <param name="content">The content of the configuration as string.</param>
|
||||
''' <returns></returns>
|
||||
Public Shared Function ReadFromString(Of T As SimpleConfiguration)(content As String) As T
|
||||
Return ConfigurationSerializer.ReadFromString(Of T)(content)
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Read a configuration from the given string and put them to this instance.
|
||||
''' </summary>
|
||||
''' <param name="content">The content of the configuration as string.</param>
|
||||
Public Sub ReadFromString(content As String)
|
||||
ConfigurationSerializer.ReadFromString(Me, content)
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Reads a configuratin from the given string and returns an instance of it.
|
||||
''' </summary>
|
||||
''' <typeparam name="T">The type of the configuration class to instance.</typeparam>
|
||||
''' <param name="stream">The stream with the content of the configuration.</param>
|
||||
''' <returns></returns>
|
||||
Public Shared Function ReadFromStream(Of T As SimpleConfiguration)(stream As Stream) As T
|
||||
Return ConfigurationSerializer.ReadFromStream(Of T)(stream)
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Read a configuration from the given string and put them to this instance.
|
||||
''' </summary>
|
||||
''' <param name="stream">The stream with the content of the configuration.</param>
|
||||
Public Sub ReadFromStream(stream As Stream)
|
||||
ConfigurationSerializer.ReadFromStream(Me, stream)
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Reads a configuratin from the given string and returns an instance of it.
|
||||
''' </summary>
|
||||
''' <typeparam name="T">The type of the configuration class to instance.</typeparam>
|
||||
''' <param name="filePath">The path to the file with the content of the configuration.</param>
|
||||
''' <returns></returns>
|
||||
Public Shared Function ReadFromFile(Of T As SimpleConfiguration)(filePath As String) As T
|
||||
Return ConfigurationSerializer.ReadFromFile(Of T)(filePath)
|
||||
End Function
|
||||
|
||||
''' <summary>
|
||||
''' Read a configuration from the given string and put them to this instance.
|
||||
''' </summary>
|
||||
''' <param name="filePath">The path to the file with the content of the configuration.</param>
|
||||
Public Sub ReadFromFile(filePath As String)
|
||||
ConfigurationSerializer.ReadFromFile(Me, filePath)
|
||||
End Sub
|
||||
|
||||
End Class
|
||||
51
Pilz.Cryptography/Helpers.cs
Normal file
51
Pilz.Cryptography/Helpers.cs
Normal file
@@ -0,0 +1,51 @@
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Management;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace Pilz.Cryptography;
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public static class Helpers
|
||||
{
|
||||
private static string clientSecret = null;
|
||||
|
||||
public static string CalculateClientSecret()
|
||||
{
|
||||
// Try getting serial number of C drive
|
||||
if (clientSecret == null && RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
|
||||
{
|
||||
ManagementObjectSearcher searcher = new("SELECT * FROM Win32_PhysicalMedia");
|
||||
string sn = null;
|
||||
|
||||
foreach (var entry in searcher.Get())
|
||||
{
|
||||
if (entry is ManagementObject wmi_HD && string.IsNullOrEmpty(sn) && wmi_HD["SerialNumber"] != null)
|
||||
sn = wmi_HD["SerialNumber"].ToString()?.Trim();
|
||||
}
|
||||
|
||||
clientSecret = sn;
|
||||
}
|
||||
|
||||
// Fallback to Mashine name
|
||||
clientSecret ??= Environment.MachineName;
|
||||
|
||||
return clientSecret;
|
||||
}
|
||||
|
||||
public static string GenerateUniquieID<T>(string var)
|
||||
{
|
||||
var sn = CalculateClientSecret();
|
||||
var dateTime = DateTime.UtcNow.ToString("yyyyMMddHHmmssfffffff");
|
||||
var type = typeof(T).ToString();
|
||||
var together = sn + dateTime + type + var;
|
||||
#if NET5_0_OR_GREATER
|
||||
var hash = BitConverter.ToString(MD5.HashData(Encoding.Default.GetBytes(together))).Replace("-", string.Empty);
|
||||
#else
|
||||
var hash = BitConverter.ToString(MD5.Create().ComputeHash(Encoding.Default.GetBytes(together))).Replace("-", string.Empty);
|
||||
#endif
|
||||
return hash;
|
||||
}
|
||||
}
|
||||
@@ -1,14 +1,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
namespace Pilz.Cryptography;
|
||||
|
||||
namespace Pilz.Cryptography
|
||||
public interface ICrypter
|
||||
{
|
||||
public interface ICrypter
|
||||
{
|
||||
string Encrypt(string plainValue);
|
||||
string Decrypt(string encryptedValue);
|
||||
}
|
||||
string Encrypt(string plainValue);
|
||||
string Decrypt(string encryptedValue);
|
||||
}
|
||||
|
||||
14
Pilz.Cryptography/IUniquieID.cs
Normal file
14
Pilz.Cryptography/IUniquieID.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using Newtonsoft.Json;
|
||||
|
||||
namespace Pilz.Cryptography;
|
||||
|
||||
[JsonConverter(typeof(Json.Converters.UniquieIDStringJsonConverter))]
|
||||
public interface IUniquieID
|
||||
{
|
||||
bool HasID { get; }
|
||||
string ID { get; }
|
||||
|
||||
void GenerateIfNull();
|
||||
void Generate();
|
||||
bool Equals(object obj);
|
||||
}
|
||||
9
Pilz.Cryptography/IUniquieIDHost.cs
Normal file
9
Pilz.Cryptography/IUniquieIDHost.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace Pilz.Cryptography;
|
||||
|
||||
/// <summary>
|
||||
/// Can be implemented on objects that provides an UniquieID.
|
||||
/// </summary>
|
||||
public interface IUniquieIDHost
|
||||
{
|
||||
UniquieID ID { get; }
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
using Newtonsoft.Json;
|
||||
using Pilz.Cryptography;
|
||||
using System;
|
||||
|
||||
namespace Pilz.Json.Converters;
|
||||
|
||||
public class UniquieIDStringJsonConverter : JsonConverter
|
||||
{
|
||||
public static bool EnableCheckForDepricatedTypes { get; set; } = true;
|
||||
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
return typeof(IUniquieID).IsAssignableFrom(objectType);
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
var idString = serializer.Deserialize<string>(reader);
|
||||
UniquieID id;
|
||||
|
||||
if (existingValue is UniquieID existingID && (!EnableCheckForDepricatedTypes || existingID.GetType() == typeof(UniquieID)))
|
||||
id = existingID;
|
||||
else
|
||||
id = new UniquieID();
|
||||
|
||||
id.ID = idString;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
serializer.Serialize(writer, ((UniquieID)value).ID);
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,17 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netstandard2.0</TargetFramework>
|
||||
<AssemblyTitle>Pilz.Cryptography</AssemblyTitle>
|
||||
<Product>Pilz.Cryptography</Product>
|
||||
<Copyright>Copyright © 2020</Copyright>
|
||||
<TargetFrameworks>net8.0</TargetFrameworks>
|
||||
<LangVersion>latest</LangVersion>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<Version>2.1.3</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Management" Version="4.7.0" />
|
||||
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
|
||||
<PackageReference Include="Microsoft.CSharp" Version="4.7.0" />
|
||||
<PackageReference Include="System.Net.Http" Version="4.3.4" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" Version="12.0.3" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.4" />
|
||||
<PackageReference Include="System.Management" Version="9.0.9" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
||||
@@ -1,6 +1,4 @@
|
||||
using System.Reflection;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Runtime.InteropServices;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
// Durch Festlegen von ComVisible auf FALSE werden die Typen in dieser Assembly
|
||||
// für COM-Komponenten unsichtbar. Wenn Sie auf einen Typ in dieser Assembly von
|
||||
|
||||
@@ -1,79 +1,72 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Pilz.Cryptography
|
||||
namespace Pilz.Cryptography;
|
||||
|
||||
[JsonConverter(typeof(Json.Converters.SecureStringJsonConverter))]
|
||||
public class SecureString
|
||||
{
|
||||
[JsonConverter(typeof(Json.Converters.SecureStringJsonConverter))]
|
||||
public class SecureString
|
||||
public static ICrypter DefaultCrypter { get; set; }
|
||||
public ICrypter Crypter { get; set; }
|
||||
public string EncryptedValue { get; set; }
|
||||
public string Value
|
||||
{
|
||||
public static ICrypter DefaultCrypter { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public ICrypter Crypter { get; set; }
|
||||
|
||||
[JsonProperty]
|
||||
public string EncryptedValue { get; set; }
|
||||
|
||||
[JsonIgnore]
|
||||
public string Value
|
||||
{
|
||||
get => GetCrypter().Decrypt(EncryptedValue);
|
||||
set => EncryptedValue = GetCrypter().Encrypt(value);
|
||||
}
|
||||
|
||||
public SecureString() :
|
||||
this(string.Empty, true)
|
||||
{
|
||||
}
|
||||
|
||||
public SecureString(string value, bool isEncrypted) :
|
||||
this(value, isEncrypted, null)
|
||||
{
|
||||
}
|
||||
|
||||
public SecureString(string value, bool isEncrypted, ICrypter crypter)
|
||||
{
|
||||
Crypter = crypter;
|
||||
|
||||
if (isEncrypted)
|
||||
EncryptedValue = value;
|
||||
else
|
||||
Value = value;
|
||||
}
|
||||
|
||||
private ICrypter GetCrypter()
|
||||
{
|
||||
if (Crypter == null)
|
||||
{
|
||||
if (DefaultCrypter == null)
|
||||
DefaultCrypter = new SimpleStringCrypter(string.Empty);
|
||||
Crypter = DefaultCrypter;
|
||||
}
|
||||
return Crypter;
|
||||
}
|
||||
|
||||
public override string ToString() => Value;
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
var @string = obj as SecureString;
|
||||
return @string != null &&
|
||||
EncryptedValue == @string.EncryptedValue;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return -2303024 + EqualityComparer<string>.Default.GetHashCode(EncryptedValue);
|
||||
}
|
||||
|
||||
public static implicit operator string(SecureString value) => value?.Value;
|
||||
public static implicit operator SecureString(string value) => new SecureString(value, false);
|
||||
|
||||
public static bool operator ==(SecureString left, SecureString right) => left.EncryptedValue == right.EncryptedValue;
|
||||
public static bool operator !=(SecureString left, SecureString right) => left.EncryptedValue != right.EncryptedValue;
|
||||
get => GetCrypter()?.Decrypt(EncryptedValue);
|
||||
set => EncryptedValue = GetCrypter().Encrypt(value);
|
||||
}
|
||||
|
||||
[JsonConstructor]
|
||||
private SecureString(JsonConstructorAttribute dummyAttribute)
|
||||
{
|
||||
}
|
||||
|
||||
public SecureString() :
|
||||
this(string.Empty, true)
|
||||
{
|
||||
}
|
||||
|
||||
public SecureString(string value, bool isEncrypted) :
|
||||
this(value, isEncrypted, null)
|
||||
{
|
||||
}
|
||||
|
||||
public SecureString(string value, bool isEncrypted, ICrypter crypter)
|
||||
{
|
||||
Crypter = crypter;
|
||||
|
||||
if (isEncrypted)
|
||||
EncryptedValue = value;
|
||||
else
|
||||
Value = value;
|
||||
}
|
||||
|
||||
private ICrypter GetCrypter()
|
||||
{
|
||||
if (Crypter == null)
|
||||
{
|
||||
DefaultCrypter ??= new SimpleStringCrypter(string.Empty);
|
||||
Crypter = DefaultCrypter;
|
||||
}
|
||||
return Crypter;
|
||||
}
|
||||
|
||||
public override string ToString() => Value;
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
var @string = obj as SecureString;
|
||||
return @string != null &&
|
||||
EncryptedValue == @string.EncryptedValue;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return -2303024 + EqualityComparer<string>.Default.GetHashCode(EncryptedValue);
|
||||
}
|
||||
|
||||
public static implicit operator string(SecureString value) => value?.Value;
|
||||
public static implicit operator SecureString(string value) => new(value, false);
|
||||
|
||||
public static bool operator ==(SecureString left, SecureString right) => left?.EncryptedValue == right?.EncryptedValue;
|
||||
public static bool operator !=(SecureString left, SecureString right) => left?.EncryptedValue != right?.EncryptedValue;
|
||||
}
|
||||
|
||||
@@ -1,40 +1,34 @@
|
||||
using Newtonsoft.Json;
|
||||
using Pilz.Cryptography;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Pilz.Json.Converters
|
||||
namespace Pilz.Json.Converters;
|
||||
|
||||
public class SecureStringJsonConverter : JsonConverter
|
||||
{
|
||||
public class SecureStringJsonConverter : JsonConverter
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
public override bool CanConvert(Type objectType)
|
||||
return typeof(SecureString).IsAssignableFrom(objectType);
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
var idString = serializer.Deserialize<string>(reader);
|
||||
SecureString id;
|
||||
|
||||
if (existingValue is SecureString)
|
||||
{
|
||||
return typeof(SecureString).IsAssignableFrom(objectType);
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
var idString = serializer.Deserialize<string>(reader);
|
||||
SecureString id;
|
||||
|
||||
if (existingValue is object)
|
||||
id = (SecureString)existingValue;
|
||||
else
|
||||
id = new SecureString();
|
||||
|
||||
id = (SecureString)existingValue;
|
||||
id.EncryptedValue = idString;
|
||||
|
||||
return id;
|
||||
}
|
||||
else
|
||||
id = new SecureString(idString, true);
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
serializer.Serialize(writer, ((SecureString)value).EncryptedValue);
|
||||
}
|
||||
return id;
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
serializer.Serialize(writer, ((SecureString)value).EncryptedValue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,77 +1,77 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Security.Cryptography;
|
||||
using System.IO;
|
||||
|
||||
namespace Pilz.Cryptography
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace Pilz.Cryptography;
|
||||
|
||||
public class SimpleStringCrypter : ICrypter
|
||||
{
|
||||
public class SimpleStringCrypter : ICrypter
|
||||
private readonly TripleDES TripleDes;
|
||||
public Encoding TextEncoding { get; private set; } = Encoding.Default;
|
||||
|
||||
public SimpleStringCrypter() : this(string.Empty)
|
||||
{
|
||||
private TripleDESCryptoServiceProvider TripleDes;
|
||||
public Encoding TextEncoding { get; private set; } = Encoding.Default;
|
||||
}
|
||||
|
||||
public SimpleStringCrypter() : this(string.Empty)
|
||||
{
|
||||
}
|
||||
public SimpleStringCrypter(string key) : this(key, Encoding.Default)
|
||||
{
|
||||
}
|
||||
|
||||
public SimpleStringCrypter(string key) : this(key, Encoding.Default)
|
||||
{
|
||||
}
|
||||
public SimpleStringCrypter(string key, Encoding textEncoding)
|
||||
{
|
||||
TextEncoding = textEncoding;
|
||||
TripleDes = TripleDES.Create();
|
||||
TripleDes.Key = TruncateHash(key, TripleDes.KeySize / 8);
|
||||
TripleDes.IV = TruncateHash(string.Empty, TripleDes.BlockSize / 8);
|
||||
}
|
||||
|
||||
public SimpleStringCrypter(string key, Encoding textEncoding)
|
||||
{
|
||||
TextEncoding = textEncoding;
|
||||
TripleDes = new TripleDESCryptoServiceProvider();
|
||||
TripleDes.Key = TruncateHash(key,TripleDes.KeySize / 8);
|
||||
TripleDes.IV = TruncateHash(string.Empty, TripleDes.BlockSize / 8);
|
||||
}
|
||||
private byte[] TruncateHash(string key, int length)
|
||||
{
|
||||
SHA1 sha1CryptoServiceProvider = SHA1.Create();
|
||||
var bytes = TextEncoding.GetBytes(key);
|
||||
var array = sha1CryptoServiceProvider.ComputeHash(bytes);
|
||||
|
||||
private byte[] TruncateHash(string key, int length)
|
||||
{
|
||||
SHA1CryptoServiceProvider sha1CryptoServiceProvider = new SHA1CryptoServiceProvider();
|
||||
byte[] bytes = TextEncoding.GetBytes(key);
|
||||
byte[] array = sha1CryptoServiceProvider.ComputeHash(bytes);
|
||||
var output = new byte[length];
|
||||
var lowerLength = Math.Min(array.Length, output.Length);
|
||||
|
||||
var output = new byte[checked(length - 1 + 1)];
|
||||
array.CopyTo(output, 0);
|
||||
for (int i = 0; i < lowerLength; i++)
|
||||
output[i] = array[i];
|
||||
|
||||
return array;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
|
||||
private string EncryptData(string plaintext)
|
||||
{
|
||||
byte[] bytes = TextEncoding.GetBytes(plaintext);
|
||||
MemoryStream memoryStream = new MemoryStream();
|
||||
CryptoStream cryptoStream = new CryptoStream(memoryStream, TripleDes.CreateEncryptor(), CryptoStreamMode.Write);
|
||||
cryptoStream.Write(bytes, 0, bytes.Length);
|
||||
cryptoStream.FlushFinalBlock();
|
||||
return Convert.ToBase64String(memoryStream.ToArray());
|
||||
}
|
||||
private string EncryptData(string plaintext)
|
||||
{
|
||||
var bytes = TextEncoding.GetBytes(plaintext);
|
||||
using var memoryStream = new MemoryStream();
|
||||
using var cryptoStream = new CryptoStream(memoryStream, TripleDes.CreateEncryptor(), CryptoStreamMode.Write);
|
||||
cryptoStream.Write(bytes, 0, bytes.Length);
|
||||
cryptoStream.FlushFinalBlock();
|
||||
return Convert.ToBase64String(memoryStream.ToArray());
|
||||
}
|
||||
|
||||
private string DecryptData(string encryptedtext)
|
||||
{
|
||||
byte[] array = Convert.FromBase64String(encryptedtext);
|
||||
MemoryStream memoryStream = new MemoryStream();
|
||||
CryptoStream cryptoStream = new CryptoStream(memoryStream, TripleDes.CreateDecryptor(), CryptoStreamMode.Write);
|
||||
cryptoStream.Write(array, 0, array.Length);
|
||||
cryptoStream.FlushFinalBlock();
|
||||
return TextEncoding.GetString(memoryStream.ToArray());
|
||||
}
|
||||
private string DecryptData(string encryptedtext)
|
||||
{
|
||||
var array = Convert.FromBase64String(encryptedtext);
|
||||
using var memoryStream = new MemoryStream();
|
||||
using var cryptoStream = new CryptoStream(memoryStream, TripleDes.CreateDecryptor(), CryptoStreamMode.Write);
|
||||
cryptoStream.Write(array, 0, array.Length);
|
||||
cryptoStream.FlushFinalBlock();
|
||||
return TextEncoding.GetString(memoryStream.ToArray());
|
||||
}
|
||||
|
||||
public string Encrypt(string plainValue)
|
||||
{
|
||||
return EncryptData(plainValue);
|
||||
}
|
||||
public string Encrypt(string plainValue)
|
||||
{
|
||||
return EncryptData(plainValue ?? string.Empty);
|
||||
}
|
||||
|
||||
public string Decrypt(string encryptedValue)
|
||||
{
|
||||
if (string.IsNullOrEmpty(encryptedValue))
|
||||
return string.Empty;
|
||||
else
|
||||
return DecryptData(encryptedValue);
|
||||
}
|
||||
public string Decrypt(string encryptedValue)
|
||||
{
|
||||
if (string.IsNullOrEmpty(encryptedValue))
|
||||
return string.Empty;
|
||||
else
|
||||
return DecryptData(encryptedValue);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,40 +0,0 @@
|
||||
using Newtonsoft.Json;
|
||||
using Pilz.Cryptography;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Pilz.Json.Converters
|
||||
{
|
||||
public class UniquiIDStringJsonConverter<TargetType> : JsonConverter
|
||||
{
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
return typeof(UniquieID<TargetType>).IsAssignableFrom(objectType);
|
||||
}
|
||||
|
||||
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
|
||||
{
|
||||
var idString = serializer.Deserialize<string>(reader);
|
||||
UniquieID<TargetType> id;
|
||||
|
||||
if (existingValue is object)
|
||||
id = (UniquieID<TargetType>)existingValue;
|
||||
else
|
||||
id = new UniquieID<TargetType>();
|
||||
|
||||
id.ID = idString;
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
|
||||
{
|
||||
serializer.Serialize(writer, ((UniquieID<TargetType>)value).ID);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,110 +1,140 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Management;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Pilz.Cryptography
|
||||
namespace Pilz.Cryptography;
|
||||
|
||||
[JsonConverter(typeof(Json.Converters.UniquieIDStringJsonConverter))]
|
||||
public class UniquieID : IUniquieID
|
||||
{
|
||||
public class UniquieID<TargetType>
|
||||
protected static ulong currentSimpleID = 0;
|
||||
|
||||
[JsonProperty(nameof(ID))]
|
||||
protected string _iD;
|
||||
|
||||
[JsonIgnore]
|
||||
public virtual bool SimpleMode { get; }
|
||||
|
||||
[JsonIgnore]
|
||||
public virtual bool GenerateOnGet { get; }
|
||||
|
||||
[JsonIgnore]
|
||||
public virtual bool HasID => !string.IsNullOrEmpty(_iD);
|
||||
|
||||
[JsonIgnore]
|
||||
public virtual string ID
|
||||
{
|
||||
private static int currentSimpleID = 0;
|
||||
|
||||
[JsonProperty(nameof(ID))]
|
||||
private string _iD;
|
||||
|
||||
[JsonIgnore]
|
||||
public string ID
|
||||
get
|
||||
{
|
||||
get
|
||||
{
|
||||
if (GenerateOnGet)
|
||||
GenerateIfNull();
|
||||
return _iD;
|
||||
}
|
||||
internal set
|
||||
=> _iD = value;
|
||||
}
|
||||
|
||||
[JsonIgnore]
|
||||
public bool HasID { get => !string.IsNullOrEmpty(_iD); }
|
||||
[JsonIgnore]
|
||||
public bool SimpleMode { get; set; } = false;
|
||||
[JsonIgnore]
|
||||
public bool GenerateOnGet { get; set; } = false;
|
||||
|
||||
public UniquieID() : this(false)
|
||||
{
|
||||
}
|
||||
|
||||
public UniquieID(bool autoGenerate)
|
||||
{
|
||||
if (autoGenerate)
|
||||
if (GenerateOnGet)
|
||||
GenerateIfNull();
|
||||
return _iD;
|
||||
}
|
||||
|
||||
public void Generate()
|
||||
{
|
||||
if (SimpleMode)
|
||||
ID = typeof(TargetType).ToString() + currentSimpleID++.ToString();
|
||||
else
|
||||
ID = GenerateUniquieID<TargetType>(string.Empty);
|
||||
}
|
||||
public void GenerateIfNull()
|
||||
{
|
||||
if (!HasID) Generate();
|
||||
}
|
||||
|
||||
private static string GenerateUniquieID<T>(string var)
|
||||
{
|
||||
var sn = TryGetSerialNumberOfFirstHardDrive();
|
||||
var dateTime = DateTime.UtcNow.ToString("yyyyMMddHHmmssfffffff");
|
||||
var type = typeof(T).ToString();
|
||||
var together = sn + dateTime + type + var;
|
||||
|
||||
var md5 = MD5.Create();
|
||||
var hash = BitConverter.ToString(md5.ComputeHash(Encoding.Default.GetBytes(together))).Replace("-", string.Empty);
|
||||
md5.Dispose();
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
private static string TryGetSerialNumberOfFirstHardDrive()
|
||||
{
|
||||
var searcher = new ManagementObjectSearcher("SELECT * FROM Win32_PhysicalMedia");
|
||||
var sn = string.Empty;
|
||||
|
||||
foreach (ManagementObject wmi_HD in searcher.Get())
|
||||
{
|
||||
if (string.IsNullOrEmpty(sn) && wmi_HD["SerialNumber"] != null)
|
||||
sn = wmi_HD["SerialNumber"].ToString().Trim();
|
||||
}
|
||||
|
||||
return sn;
|
||||
}
|
||||
|
||||
public override string ToString() => ID;
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
var iD = obj as UniquieID<TargetType>;
|
||||
return iD != null &&
|
||||
_iD == iD._iD;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return -1430039477 + EqualityComparer<string>.Default.GetHashCode(_iD);
|
||||
}
|
||||
|
||||
public static implicit operator string(UniquieID<TargetType> id) => id.ID;
|
||||
public static implicit operator UniquieID<TargetType>(string id) => new UniquieID<TargetType>() { ID = id };
|
||||
public static implicit operator UniquieID<TargetType>(int id) => new UniquieID<TargetType>() { ID = Convert.ToString(id) };
|
||||
|
||||
public static bool operator ==(UniquieID<TargetType> left, UniquieID<TargetType> right) => left.ID == right.ID;
|
||||
public static bool operator !=(UniquieID<TargetType> left, UniquieID<TargetType> right) => left.ID != right.ID;
|
||||
internal set
|
||||
=> _iD = value;
|
||||
}
|
||||
|
||||
public UniquieID() : this(UniquieIDGenerationMode.None)
|
||||
{
|
||||
}
|
||||
|
||||
public UniquieID(UniquieIDGenerationMode mode) : this(mode, false)
|
||||
{
|
||||
}
|
||||
|
||||
public UniquieID(UniquieIDGenerationMode mode, bool simpleMode)
|
||||
{
|
||||
SimpleMode = simpleMode;
|
||||
|
||||
if (mode == UniquieIDGenerationMode.GenerateOnInit)
|
||||
GenerateIfNull();
|
||||
else if (mode == UniquieIDGenerationMode.GenerateOnGet)
|
||||
GenerateOnGet = true;
|
||||
}
|
||||
|
||||
[Obsolete("Use the enum 'UniquieIDGenerationMode' instead of a simple boolean.")]
|
||||
public UniquieID(bool autoGenerate) : this(autoGenerate ? UniquieIDGenerationMode.GenerateOnInit : UniquieIDGenerationMode.None)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual void Generate()
|
||||
{
|
||||
if (SimpleMode)
|
||||
ID = GenerateSimple();
|
||||
else
|
||||
ID = GenerateDefault();
|
||||
}
|
||||
|
||||
protected virtual string GenerateSimple()
|
||||
{
|
||||
return new Random().Next().ToString() + DateTime.Now.ToString("yyyyMMddHHmmssfffffff") + currentSimpleID++.ToString();
|
||||
}
|
||||
|
||||
protected virtual string GenerateDefault()
|
||||
{
|
||||
return Helpers.GenerateUniquieID<UniquieID>(currentSimpleID++.ToString());
|
||||
}
|
||||
|
||||
public virtual void GenerateIfNull()
|
||||
{
|
||||
if (!HasID) Generate();
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return ID;
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
return -1430039477 + EqualityComparer<string>.Default.GetHashCode(_iD);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (obj is UniquieID iD)
|
||||
{
|
||||
if (ReferenceEquals(obj, iD))
|
||||
return true;
|
||||
else
|
||||
{
|
||||
var leftHasID = iD.HasID;
|
||||
var rightHasID = HasID;
|
||||
|
||||
if (!leftHasID && iD.GenerateOnGet)
|
||||
{
|
||||
iD.Generate();
|
||||
leftHasID = iD.HasID;
|
||||
}
|
||||
|
||||
if (!rightHasID && GenerateOnGet)
|
||||
{
|
||||
Generate();
|
||||
rightHasID = HasID;
|
||||
}
|
||||
|
||||
if (leftHasID && rightHasID)
|
||||
return _iD.Equals(iD._iD);
|
||||
}
|
||||
}
|
||||
|
||||
return base.Equals(obj);
|
||||
}
|
||||
|
||||
public static UniquieID GenerateNew()
|
||||
{
|
||||
return new UniquieID(UniquieIDGenerationMode.GenerateOnInit);
|
||||
}
|
||||
|
||||
public static UniquieID GenerateNew(bool simpleMode)
|
||||
{
|
||||
return new UniquieID(UniquieIDGenerationMode.GenerateOnInit, simpleMode);
|
||||
}
|
||||
|
||||
public static implicit operator string(UniquieID id) => id.ID;
|
||||
public static implicit operator UniquieID(string id) => new() { ID = id };
|
||||
public static implicit operator UniquieID(int id) => new() { ID = Convert.ToString(id) };
|
||||
|
||||
public static bool operator ==(UniquieID left, UniquieID right) => left.ID.Equals(right.ID);
|
||||
public static bool operator !=(UniquieID left, UniquieID right) => !left.ID.Equals(right.ID);
|
||||
}
|
||||
|
||||
8
Pilz.Cryptography/UniquieIDGenerationMode.cs
Normal file
8
Pilz.Cryptography/UniquieIDGenerationMode.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Pilz.Cryptography;
|
||||
|
||||
public enum UniquieIDGenerationMode
|
||||
{
|
||||
None,
|
||||
GenerateOnGet,
|
||||
GenerateOnInit
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
Imports System.Windows.Forms
|
||||
Imports OpenTK
|
||||
|
||||
Imports OpenTK.Mathematics
|
||||
|
||||
Namespace CameraN
|
||||
|
||||
@@ -119,7 +120,7 @@ Namespace CameraN
|
||||
|
||||
Private Sub OrientateCam(ang As Single, ang2 As Single)
|
||||
Dim CamLX As Single = CSng(Math.Sin(ang)) * CSng(Math.Sin(-ang2))
|
||||
Dim CamLY As Single = CSng(Math.Cos(ang2))
|
||||
Dim CamLY As Single = Math.Cos(ang2)
|
||||
Dim CamLZ As Single = CSng(-Math.Cos(ang)) * CSng(Math.Sin(-ang2))
|
||||
|
||||
myLookat.X = pos.X + (-CamLX) * 100.0F
|
||||
@@ -130,11 +131,11 @@ Namespace CameraN
|
||||
Private Sub OffsetCam(xAmt As Integer, yAmt As Integer, zAmt As Integer)
|
||||
Dim pitch_Renamed As Double = CamAngleY - (Math.PI / 2)
|
||||
Dim CamLX As Single = CSng(Math.Sin(CamAngleX)) * CSng(Math.Cos(-pitch_Renamed))
|
||||
Dim CamLY As Single = CSng(Math.Sin(pitch_Renamed))
|
||||
Dim CamLY As Single = Math.Sin(pitch_Renamed)
|
||||
Dim CamLZ As Single = CSng(-Math.Cos(CamAngleX)) * CSng(Math.Cos(-pitch_Renamed))
|
||||
pos.X = pos.X + xAmt * (CamLX) * CamSpeedMultiplier
|
||||
pos.Y = pos.Y + yAmt * (CamLY) * CamSpeedMultiplier
|
||||
pos.Z = pos.Z + zAmt * (CamLZ) * CamSpeedMultiplier
|
||||
pos.X += xAmt * (CamLX) * CamSpeedMultiplier
|
||||
pos.Y += yAmt * (CamLY) * CamSpeedMultiplier
|
||||
pos.Z += zAmt * (CamLZ) * CamSpeedMultiplier
|
||||
End Sub
|
||||
|
||||
Public Sub Move(y As Single, ByRef camMtx As Matrix4)
|
||||
@@ -153,7 +154,7 @@ Namespace CameraN
|
||||
Dim x_diff As Single = myLookat.X - pos.X
|
||||
Dim y_diff As Single = myLookat.Y - pos.Y
|
||||
Dim z_diff As Single = myLookat.Z - pos.Z
|
||||
Dim dist As Single = CSng(Math.Sqrt(x_diff * x_diff + y_diff * y_diff + z_diff * z_diff))
|
||||
Dim dist As Single = Math.Sqrt(x_diff * x_diff + y_diff * y_diff + z_diff * z_diff)
|
||||
If z_diff = 0 Then
|
||||
z_diff = 0.001F
|
||||
End If
|
||||
@@ -209,32 +210,32 @@ Namespace CameraN
|
||||
currentLookDirection = dir
|
||||
Select Case currentLookDirection
|
||||
Case LookDirection.Top
|
||||
pos = lookPositions(CInt(LookDirection.Top))
|
||||
pos = lookPositions(LookDirection.Top)
|
||||
myLookat = New Vector3(pos.X, -25000, pos.Z - 1)
|
||||
UpdateMatrix(cameraMatrix)
|
||||
SetRotationFromLookAt()
|
||||
Case LookDirection.Bottom
|
||||
pos = lookPositions(CInt(LookDirection.Bottom))
|
||||
pos = lookPositions(LookDirection.Bottom)
|
||||
myLookat = New Vector3(pos.X, 25000, pos.Z + 1)
|
||||
UpdateMatrix(cameraMatrix)
|
||||
SetRotationFromLookAt()
|
||||
Case LookDirection.Left
|
||||
pos = lookPositions(CInt(LookDirection.Left))
|
||||
pos = lookPositions(LookDirection.Left)
|
||||
myLookat = New Vector3(25000, pos.Y, pos.Z)
|
||||
UpdateMatrix(cameraMatrix)
|
||||
SetRotationFromLookAt()
|
||||
Case LookDirection.Right
|
||||
pos = lookPositions(CInt(LookDirection.Right))
|
||||
pos = lookPositions(LookDirection.Right)
|
||||
myLookat = New Vector3(-25000, pos.Y, pos.Z)
|
||||
UpdateMatrix(cameraMatrix)
|
||||
SetRotationFromLookAt()
|
||||
Case LookDirection.Front
|
||||
pos = lookPositions(CInt(LookDirection.Front))
|
||||
pos = lookPositions(LookDirection.Front)
|
||||
myLookat = New Vector3(pos.X, pos.Y, -25000)
|
||||
UpdateMatrix(cameraMatrix)
|
||||
SetRotationFromLookAt()
|
||||
Case LookDirection.Back
|
||||
pos = lookPositions(CInt(LookDirection.Back))
|
||||
pos = lookPositions(LookDirection.Back)
|
||||
myLookat = New Vector3(pos.X, pos.Y, 25000)
|
||||
UpdateMatrix(cameraMatrix)
|
||||
SetRotationFromLookAt()
|
||||
@@ -312,9 +313,9 @@ Namespace CameraN
|
||||
|
||||
Dim pitch_Renamed As Double = CamAngleY - (Math.PI / 2)
|
||||
Dim yaw_Renamed As Double = CamAngleX - (Math.PI / 2)
|
||||
Dim CamLX As Single = CSng(Math.Sin(yaw_Renamed))
|
||||
Dim CamLY As Single = CSng(Math.Cos(pitch_Renamed))
|
||||
Dim CamLZ As Single = CSng(-Math.Cos(yaw_Renamed))
|
||||
Dim CamLX As Single = Math.Sin(yaw_Renamed)
|
||||
Dim CamLY As Single = Math.Cos(pitch_Renamed)
|
||||
Dim CamLZ As Single = -Math.Cos(yaw_Renamed)
|
||||
|
||||
Dim m As Single = 8.0F
|
||||
|
||||
@@ -323,36 +324,36 @@ Namespace CameraN
|
||||
pos.X = orgPos.X - ((MousePosX * CamSpeedMultiplier) * (CamLX) * m) - ((MousePosY * CamSpeedMultiplier) * (CamLZ) * m)
|
||||
pos.Z = orgPos.Z - ((MousePosX * CamSpeedMultiplier) * (CamLZ) * m) - ((MousePosY * CamSpeedMultiplier) * (CamLX) * m)
|
||||
cameraMatrix = Matrix4.LookAt(pos.X, pos.Y, pos.Z, pos.X, pos.Y - 1000, pos.Z - 1, 0, 1, 0)
|
||||
lookPositions(CInt(currentLookDirection)) = pos
|
||||
lookPositions(currentLookDirection) = pos
|
||||
Case LookDirection.Bottom
|
||||
pos.X = orgPos.X - ((MousePosX * CamSpeedMultiplier) * (CamLX) * m) + ((MousePosY * CamSpeedMultiplier) * (CamLZ) * m)
|
||||
pos.Z = orgPos.Z - ((MousePosX * CamSpeedMultiplier) * (CamLZ) * m) + ((MousePosY * CamSpeedMultiplier) * (CamLX) * m)
|
||||
cameraMatrix = Matrix4.LookAt(pos.X, pos.Y, pos.Z, pos.X, pos.Y + 1000, pos.Z + 1, 0, 1, 0)
|
||||
lookPositions(CInt(currentLookDirection)) = pos
|
||||
lookPositions(currentLookDirection) = pos
|
||||
Case LookDirection.Left
|
||||
pos.X = orgPos.X - ((MousePosX * CamSpeedMultiplier) * (CamLX) * m)
|
||||
pos.Y = orgPos.Y - ((MousePosY * CamSpeedMultiplier) * (-1.0F) * m)
|
||||
pos.Z = orgPos.Z - ((MousePosX * CamSpeedMultiplier) * (CamLZ) * m)
|
||||
cameraMatrix = Matrix4.LookAt(pos.X, pos.Y, pos.Z, pos.X + 12500, pos.Y, pos.Z, 0, 1, 0)
|
||||
lookPositions(CInt(currentLookDirection)) = pos
|
||||
lookPositions(currentLookDirection) = pos
|
||||
Case LookDirection.Right
|
||||
pos.X = orgPos.X - ((MousePosX * CamSpeedMultiplier) * (CamLX) * m)
|
||||
pos.Y = orgPos.Y - ((MousePosY * CamSpeedMultiplier) * (-1.0F) * m)
|
||||
pos.Z = orgPos.Z - ((MousePosX * CamSpeedMultiplier) * (CamLZ) * m)
|
||||
cameraMatrix = Matrix4.LookAt(pos.X, pos.Y, pos.Z, pos.X - 12500, pos.Y, pos.Z, 0, 1, 0)
|
||||
lookPositions(CInt(currentLookDirection)) = pos
|
||||
lookPositions(currentLookDirection) = pos
|
||||
Case LookDirection.Front
|
||||
pos.X = orgPos.X - ((MousePosX * CamSpeedMultiplier) * (CamLX) * m)
|
||||
pos.Y = orgPos.Y - ((MousePosY * CamSpeedMultiplier) * (-1.0F) * m)
|
||||
pos.Z = orgPos.Z - ((MousePosX * CamSpeedMultiplier) * (CamLZ) * m)
|
||||
cameraMatrix = Matrix4.LookAt(pos.X, pos.Y, pos.Z, pos.X, pos.Y, pos.Z - 12500, 0, 1, 0)
|
||||
lookPositions(CInt(currentLookDirection)) = pos
|
||||
lookPositions(currentLookDirection) = pos
|
||||
Case LookDirection.Back
|
||||
pos.X = orgPos.X - ((MousePosX * CamSpeedMultiplier) * (CamLX) * m)
|
||||
pos.Y = orgPos.Y - ((MousePosY * CamSpeedMultiplier) * (-1.0F) * m)
|
||||
pos.Z = orgPos.Z - ((MousePosX * CamSpeedMultiplier) * (CamLZ) * m)
|
||||
cameraMatrix = Matrix4.LookAt(pos.X, pos.Y, pos.Z, pos.X, pos.Y, pos.Z + 12500, 0, 1, 0)
|
||||
lookPositions(CInt(currentLookDirection)) = pos
|
||||
lookPositions(currentLookDirection) = pos
|
||||
End Select
|
||||
|
||||
RaisePerspectiveChanged()
|
||||
@@ -371,7 +372,7 @@ Namespace CameraN
|
||||
End If
|
||||
Dim MousePosX As Integer = mouseX - lastMouseX
|
||||
Dim MousePosY As Integer = mouseY - lastMouseY
|
||||
CamAngleX = CamAngleX + (0.01F * MousePosX)
|
||||
CamAngleX += (0.01F * MousePosX)
|
||||
' This next part isn't neccessary, but it keeps the Yaw rotation value within [0, 2*pi] which makes debugging simpler.
|
||||
If CamAngleX > TAU Then
|
||||
CamAngleX -= TAU
|
||||
@@ -418,9 +419,9 @@ Namespace CameraN
|
||||
'Console.WriteLine(MousePosX+","+ MousePosY);
|
||||
Dim pitch_Renamed As Double = CamAngleY - (Math.PI / 2)
|
||||
Dim yaw_Renamed As Double = CamAngleX - (Math.PI / 2)
|
||||
Dim CamLX As Single = CSng(Math.Sin(yaw_Renamed))
|
||||
Dim CamLX As Single = Math.Sin(yaw_Renamed)
|
||||
' float CamLY = (float)Math.Cos(pitch);
|
||||
Dim CamLZ As Single = CSng(-Math.Cos(yaw_Renamed))
|
||||
Dim CamLZ As Single = -Math.Cos(yaw_Renamed)
|
||||
pos.X += ((horz_amount * CamSpeedMultiplier) * (CamLX))
|
||||
pos.Y += ((vert_amount * CamSpeedMultiplier) * (-1.0F))
|
||||
pos.Z += ((horz_amount * CamSpeedMultiplier) * (CamLZ))
|
||||
|
||||
@@ -22,7 +22,7 @@ Namespace My.Resources
|
||||
'''<summary>
|
||||
''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
|
||||
'''</summary>
|
||||
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0"), _
|
||||
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0"), _
|
||||
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
|
||||
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
|
||||
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<MyType>Windows</MyType>
|
||||
<TargetFramework>net48</TargetFramework>
|
||||
<TargetFrameworks>net8.0-windows</TargetFrameworks>
|
||||
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||
<DocumentationFile>Pilz.Drawing.Drawing3D.OpenGLFactory.xml</DocumentationFile>
|
||||
<DefineTrace>true</DefineTrace>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DefineDebug>true</DefineDebug>
|
||||
@@ -24,18 +25,16 @@
|
||||
<PropertyGroup>
|
||||
<OptionInfer>On</OptionInfer>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<Version>2.0.4</Version>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
|
||||
<PackageReference Include="System.Net.Http" Version="4.3.4" />
|
||||
<PackageReference Include="OpenTK.Input" Version="4.9.4" />
|
||||
<PackageReference Include="OpenTK.GLControl" Version="4.0.2" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="OpenTK" Version="3.2" />
|
||||
<PackageReference Include="OpenTK.GLControl" Version="3.1.0" />
|
||||
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="Microsoft.VisualBasic" />
|
||||
<Reference Include="System.Windows.Forms" />
|
||||
<PackageReference Include="OpenTK" Version="4.9.4" />
|
||||
<PackageReference Include="System.Numerics.Vectors" Version="4.6.1" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Import Include="Microsoft.VisualBasic" />
|
||||
@@ -52,9 +51,7 @@
|
||||
<Compile Update="Preview\ModelPreview.Designer.vb">
|
||||
<DependentUpon>ModelPreview.vb</DependentUpon>
|
||||
</Compile>
|
||||
<Compile Update="Preview\ModelPreview.vb">
|
||||
<SubType>Form</SubType>
|
||||
</Compile>
|
||||
<Compile Update="Preview\ModelPreview.vb" />
|
||||
<Compile Update="My Project\Application.Designer.vb">
|
||||
<AutoGen>True</AutoGen>
|
||||
<DependentUpon>Application.myapp</DependentUpon>
|
||||
@@ -94,6 +91,7 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Pilz.Simple3DFileParser\Pilz.Simple3DFileParser.vbproj" />
|
||||
<ProjectReference Include="..\Pilz.Win32\Pilz.Win32.csproj" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Remove="ModelPreview.Designer.vb" />
|
||||
|
||||
@@ -1,15 +1,30 @@
|
||||
Imports System.Drawing
|
||||
' Nicht gemergte Änderung aus Projekt "Pilz.Drawing.Drawing3D.OpenGLFactory (net6.0-windows)"
|
||||
' Vor:
|
||||
' Imports System.Windows.Forms
|
||||
' Imports Pilz.Drawing.Drawing3D.OpenGLFactory.CameraN
|
||||
' Nach:
|
||||
' Imports System.Windows.Forms
|
||||
'
|
||||
' Imports OpenTK
|
||||
' Imports OpenTK.Graphics.OpenGL
|
||||
' Imports OpenTK.Mathematics
|
||||
' Imports OpenTK.WinForms
|
||||
'
|
||||
' Imports Pilz.Drawing.Drawing3D.OpenGLFactory.CameraN
|
||||
Imports System.Windows.Forms
|
||||
|
||||
Imports OpenTK.GLControl
|
||||
Imports OpenTK.Graphics.OpenGL
|
||||
Imports OpenTK.Mathematics
|
||||
|
||||
Imports Pilz.Drawing.Drawing3D.OpenGLFactory.CameraN
|
||||
Imports Pilz.Drawing.Drawing3D.OpenGLFactory.RenderingN
|
||||
Imports OpenTK
|
||||
Imports OpenTK.Graphics.OpenGL
|
||||
Imports Pilz.S3DFileParser
|
||||
Imports Point = System.Drawing.Point
|
||||
Imports KeyboardState = OpenTK.Input.KeyboardState
|
||||
Imports Keyboard = OpenTK.Input.Keyboard
|
||||
Imports Key = OpenTK.Input.Key
|
||||
Imports Pilz.Win32.Mapped
|
||||
|
||||
Imports Color = System.Drawing.Color
|
||||
Imports Point = System.Drawing.Point
|
||||
|
||||
Namespace PreviewN
|
||||
|
||||
@@ -81,15 +96,13 @@ Namespace PreviewN
|
||||
|
||||
Private ReadOnly Property IsStrgPressed As Boolean
|
||||
Get
|
||||
Dim state As KeyboardState = Keyboard.GetState()
|
||||
Return state(Key.ControlLeft) OrElse state(Key.ControlRight)
|
||||
Return Keyboard.IsKeyDown(Keys.Control)
|
||||
End Get
|
||||
End Property
|
||||
|
||||
Private ReadOnly Property IsShiftPressed As Boolean
|
||||
Get
|
||||
Dim state As KeyboardState = Keyboard.GetState()
|
||||
Return state(Key.ShiftLeft) OrElse state(Key.ShiftRight)
|
||||
Return Keyboard.IsKeyDown(Keys.Shift)
|
||||
End Get
|
||||
End Property
|
||||
|
||||
@@ -122,17 +135,17 @@ Namespace PreviewN
|
||||
DoubleBuffered = True
|
||||
|
||||
'glControl1
|
||||
Me.glControl1 = New GLControl
|
||||
Me.glControl1.BackColor = Color.Black
|
||||
Me.glControl1.Location = New Point(0, 0)
|
||||
Me.glControl1.MinimumSize = New Size(600, 120)
|
||||
Me.glControl1.Name = "glControl1"
|
||||
Me.glControl1.Anchor = AnchorStyles.Left Or AnchorStyles.Top Or AnchorStyles.Right Or AnchorStyles.Bottom
|
||||
Me.glControl1 = New GLControl With {
|
||||
.BackColor = Color.Black,
|
||||
.Location = New Point(0, 0),
|
||||
.MinimumSize = New Size(600, 120),
|
||||
.Name = "glControl1",
|
||||
.Anchor = AnchorStyles.Left Or AnchorStyles.Top Or AnchorStyles.Right Or AnchorStyles.Bottom
|
||||
}
|
||||
Me.glControl1.Location = New Point(0, 0)
|
||||
Me.glControl1.Size = Me.ClientSize
|
||||
Me.glControl1.TabIndex = 0
|
||||
Me.glControl1.TabStop = False
|
||||
Me.glControl1.VSync = False
|
||||
Me.Controls.Add(Me.glControl1)
|
||||
Me.ResumeLayout(False)
|
||||
|
||||
@@ -247,7 +260,7 @@ Namespace PreviewN
|
||||
End Sub
|
||||
|
||||
Private Sub glControl1_Resize(sender As Object, e As EventArgs) Handles glControl1.Resize
|
||||
glControl1.Context.Update(glControl1.WindowInfo)
|
||||
'glControl1.Context.Update(glControl1.WindowInfo)
|
||||
GL.Viewport(0, 0, glControl1.Width, glControl1.Height)
|
||||
ProjMatrix = Matrix4.CreatePerspectiveFieldOfView(FOV, glControl1.Width / glControl1.Height, 100.0F, 100000.0F)
|
||||
glControl1.Invalidate()
|
||||
@@ -255,7 +268,7 @@ Namespace PreviewN
|
||||
|
||||
Private Sub glControl1_Wheel(sender As Object, e As MouseEventArgs)
|
||||
MyCamera.ResetMouseStuff()
|
||||
MyCamera.UpdateCameraMatrixWithScrollWheel(CInt(Math.Truncate(e.Delta * (If(IsShiftPressed, 3.5F, 1.5F)))), camMtx)
|
||||
MyCamera.UpdateCameraMatrixWithScrollWheel(Math.Truncate(e.Delta * (If(IsShiftPressed, 3.5F, 1.5F))), camMtx)
|
||||
savedCamPos = MyCamera.Position
|
||||
glControl1.Invalidate()
|
||||
End Sub
|
||||
@@ -286,32 +299,24 @@ Namespace PreviewN
|
||||
Dim allowCamMove As Boolean = Not (IsMouseDown AndAlso IsShiftPressed)
|
||||
|
||||
If allowCamMove Then
|
||||
Dim state As KeyboardState = Keyboard.GetState
|
||||
|
||||
If state(Key.W) Then
|
||||
'camera.Move(moveSpeed, moveSpeed, camMtx)
|
||||
If Keyboard.IsKeyDown(Keys.W) Then
|
||||
MyCamera.UpdateCameraMatrixWithScrollWheel(moveSpeed, camMtx)
|
||||
savedCamPos = MyCamera.Position
|
||||
End If
|
||||
If state(Key.S) Then
|
||||
'camera.Move(-moveSpeed, -moveSpeed, camMtx)
|
||||
If Keyboard.IsKeyDown(Keys.S) Then
|
||||
MyCamera.UpdateCameraMatrixWithScrollWheel(-moveSpeed, camMtx)
|
||||
savedCamPos = MyCamera.Position
|
||||
End If
|
||||
If state(Key.A) Then
|
||||
'camera.Move(-moveSpeed, 0, camMtx)
|
||||
If Keyboard.IsKeyDown(Keys.A) Then
|
||||
MyCamera.UpdateCameraOffsetDirectly(-moveSpeed, 0, camMtx)
|
||||
End If
|
||||
If state(Key.D) Then
|
||||
'camera.Move(moveSpeed, 0, camMtx)
|
||||
If Keyboard.IsKeyDown(Keys.D) Then
|
||||
MyCamera.UpdateCameraOffsetDirectly(moveSpeed, 0, camMtx)
|
||||
End If
|
||||
If state(Key.E) Then
|
||||
'camera.Move(0, -moveSpeed, camMtx)
|
||||
If Keyboard.IsKeyDown(Keys.E) Then
|
||||
MyCamera.UpdateCameraOffsetDirectly(0, -moveSpeed, camMtx)
|
||||
End If
|
||||
If state(Key.Q) Then
|
||||
'camera.Move(0, moveSpeed, camMtx)
|
||||
If Keyboard.IsKeyDown(Keys.Q) Then
|
||||
MyCamera.UpdateCameraOffsetDirectly(0, moveSpeed, camMtx)
|
||||
End If
|
||||
End If
|
||||
|
||||
@@ -1,5 +1,14 @@
|
||||
Imports System.Drawing
|
||||
Imports OpenTK
|
||||
|
||||
' Nicht gemergte Änderung aus Projekt "Pilz.Drawing.Drawing3D.OpenGLFactory (net6.0-windows)"
|
||||
' Vor:
|
||||
' Imports System.Drawing
|
||||
' Imports OpenTK
|
||||
' Nach:
|
||||
' Imports System.Drawing
|
||||
'
|
||||
' Imports OpenTK
|
||||
Imports System.Drawing
|
||||
|
||||
Imports OpenTK.Graphics.OpenGL
|
||||
|
||||
Namespace RenderingN
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
Imports System
|
||||
Imports OpenTK
|
||||
Imports OpenTK.Graphics.OpenGL
|
||||
Imports System.Drawing
|
||||
Imports System.Drawing
|
||||
Imports System.Drawing.Imaging
|
||||
|
||||
Imports OpenTK.Graphics.OpenGL
|
||||
|
||||
Imports Bitmap = System.Drawing.Bitmap
|
||||
|
||||
Namespace RenderingN
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
Imports System.Drawing
|
||||
Imports System.Threading
|
||||
Imports System.Windows.Forms
|
||||
Imports OpenTK
|
||||
Imports OpenTK.Graphics.OpenGL
|
||||
Imports OpenTK.Graphics.OpenGL
|
||||
Imports OpenTK.Mathematics
|
||||
|
||||
Imports Pilz.S3DFileParser
|
||||
|
||||
Imports Bitmap = System.Drawing.Bitmap
|
||||
Imports Color = System.Drawing.Color
|
||||
Imports Image = System.Drawing.Image
|
||||
@@ -137,6 +136,14 @@ Namespace RenderingN
|
||||
''' Creates the Buffers and store the requied Data.
|
||||
''' </summary>
|
||||
Public Sub RenderModel()
|
||||
RenderModel(BufferUsageHint.StaticDraw)
|
||||
End Sub
|
||||
|
||||
''' <summary>
|
||||
''' Creates the Buffers and store the requied Data.
|
||||
''' </summary>
|
||||
''' <param name="bufferUsage">The hint how the graphics card should handle the data.</param>
|
||||
Public Sub RenderModel(bufferUsage As BufferUsageHint)
|
||||
ReleaseBuffers()
|
||||
|
||||
For Each mesh As Mesh In obj3d.Meshes
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
Imports System.Drawing
|
||||
Imports System.Drawing.Drawing2D
|
||||
|
||||
Public Module HelpfulDrawingFunctions
|
||||
|
||||
Public Function IsPointInRectangle(p As PointF, rect As RectangleF) As Boolean
|
||||
Dim bList As New List(Of Boolean)
|
||||
|
||||
bList.Add(p.X > rect.Left)
|
||||
bList.Add(p.X < rect.Right)
|
||||
bList.Add(p.Y > rect.Top)
|
||||
bList.Add(p.Y < rect.Bottom)
|
||||
Dim bList As New List(Of Boolean) From {
|
||||
p.X > rect.Left,
|
||||
p.X < rect.Right,
|
||||
p.Y > rect.Top,
|
||||
p.Y < rect.Bottom
|
||||
}
|
||||
|
||||
Return Not bList.Contains(False)
|
||||
End Function
|
||||
|
||||
2
Pilz.Drawing/My Project/Resources.Designer.vb
generated
2
Pilz.Drawing/My Project/Resources.Designer.vb
generated
@@ -22,7 +22,7 @@ Namespace My.Resources
|
||||
'''<summary>
|
||||
''' Eine stark typisierte Ressourcenklasse zum Suchen von lokalisierten Zeichenfolgen usw.
|
||||
'''</summary>
|
||||
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "15.0.0.0"), _
|
||||
<Global.System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0"), _
|
||||
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
|
||||
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
|
||||
Global.Microsoft.VisualBasic.HideModuleNameAttribute()> _
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<MyType>Windows</MyType>
|
||||
<TargetFramework>net48</TargetFramework>
|
||||
<TargetFrameworks>net8.0-windows</TargetFrameworks>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<NoWarn>42016,41999,42017,42018,42019,42032,42036,42020,42021,42022</NoWarn>
|
||||
<DocumentationFile>Pilz.Drawing.xml</DocumentationFile>
|
||||
<DefineTrace>true</DefineTrace>
|
||||
<UseWindowsForms>true</UseWindowsForms>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
|
||||
<DefineDebug>true</DefineDebug>
|
||||
@@ -24,10 +26,9 @@
|
||||
<PropertyGroup>
|
||||
<OptionInfer>On</OptionInfer>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="System.Data.DataSetExtensions" Version="4.5.0" />
|
||||
<PackageReference Include="System.Net.Http" Version="4.3.4" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup>
|
||||
<Version>2.0.2</Version>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<Import Include="Microsoft.VisualBasic" />
|
||||
<Import Include="System" />
|
||||
|
||||
18
Pilz.Extensions/Collections/IEnumerableExtensions.cs
Normal file
18
Pilz.Extensions/Collections/IEnumerableExtensions.cs
Normal file
@@ -0,0 +1,18 @@
|
||||
namespace Pilz.Extensions.Collections;
|
||||
|
||||
public static class IEnumerableExtensions
|
||||
{
|
||||
public static IEnumerable<T> ForEach<T>(this IEnumerable<T> @this, Action<T> action)
|
||||
{
|
||||
foreach (var t in @this)
|
||||
action(t);
|
||||
return @this;
|
||||
}
|
||||
|
||||
public static IQueryable<T> ForEach<T>(this IQueryable<T> @this, Action<T> action)
|
||||
{
|
||||
foreach (var t in @this)
|
||||
action(t);
|
||||
return @this;
|
||||
}
|
||||
}
|
||||
30
Pilz.Extensions/Collections/IListExtensions.cs
Normal file
30
Pilz.Extensions/Collections/IListExtensions.cs
Normal file
@@ -0,0 +1,30 @@
|
||||
namespace Pilz.Extensions.Collections;
|
||||
|
||||
public static class IListExtensions
|
||||
{
|
||||
public static bool Move<T>(this IList<T> @this, T item, int amount)
|
||||
{
|
||||
var oldIndex = @this.IndexOf(item);
|
||||
|
||||
if (oldIndex == -1)
|
||||
return false;
|
||||
|
||||
var newIndex = oldIndex + amount;
|
||||
|
||||
if (newIndex < 0)
|
||||
newIndex = 0;
|
||||
else if (newIndex >= @this.Count)
|
||||
newIndex = @this.Count;
|
||||
|
||||
if (newIndex == oldIndex)
|
||||
return false;
|
||||
|
||||
if (newIndex > 0 && newIndex > oldIndex)
|
||||
newIndex -= 1;
|
||||
|
||||
@this.RemoveAt(oldIndex);
|
||||
@this.Insert(newIndex, item);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
14
Pilz.Extensions/Pilz.Extensions.csproj
Normal file
14
Pilz.Extensions/Pilz.Extensions.csproj
Normal file
@@ -0,0 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net8.0</TargetFrameworks>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<Version>2.1.2</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
24
Pilz.Extensions/Reflection/MethodInfoExtensions.cs
Normal file
24
Pilz.Extensions/Reflection/MethodInfoExtensions.cs
Normal file
@@ -0,0 +1,24 @@
|
||||
using System.Linq.Expressions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Pilz.Extensions.Reflection;
|
||||
|
||||
public static class MethodInfoExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Source: https://stackoverflow.com/questions/940675/getting-a-delegate-from-methodinfo
|
||||
/// </summary>
|
||||
/// <param name="methodInfo"></param>
|
||||
/// <param name="target"></param>
|
||||
/// <returns></returns>
|
||||
public static Delegate CreateDelegate(this MethodInfo methodInfo, object? target)
|
||||
{
|
||||
var parmTypes = methodInfo.GetParameters().Select(parm => parm.ParameterType);
|
||||
var parmAndReturnTypes = parmTypes.Append(methodInfo.ReturnType).ToArray();
|
||||
var delegateType = Expression.GetDelegateType(parmAndReturnTypes);
|
||||
|
||||
if (methodInfo.IsStatic)
|
||||
return methodInfo.CreateDelegate(delegateType);
|
||||
return methodInfo.CreateDelegate(delegateType, target);
|
||||
}
|
||||
}
|
||||
3
Pilz.Features/Delegates.cs
Normal file
3
Pilz.Features/Delegates.cs
Normal file
@@ -0,0 +1,3 @@
|
||||
namespace Pilz.Features;
|
||||
|
||||
public delegate void PluginFeatureExecuteEventHandler(object sender, PluginFeatureExecuteEventArgs e);
|
||||
5
Pilz.Features/Exceptions/PluginFeatureExceptions.cs
Normal file
5
Pilz.Features/Exceptions/PluginFeatureExceptions.cs
Normal file
@@ -0,0 +1,5 @@
|
||||
namespace Pilz.Features.Exceptions;
|
||||
|
||||
public class PluginFeatureException : Exception;
|
||||
|
||||
public class PluginFeatureNotFoundException : PluginFeatureException;
|
||||
34
Pilz.Features/Extensions.cs
Normal file
34
Pilz.Features/Extensions.cs
Normal file
@@ -0,0 +1,34 @@
|
||||
namespace Pilz.Features;
|
||||
|
||||
public static class Extensions
|
||||
{
|
||||
public static T? ExecuteIfEnabled<T>(this PluginFunction @this, params object?[]? @params)
|
||||
{
|
||||
return @this.Enabled ? @this.Execute<T>(@params) : default;
|
||||
}
|
||||
|
||||
public static object? ExecuteIfEnabled(this PluginFunction @this, params object?[]? @params)
|
||||
{
|
||||
return @this.Enabled ? @this.Execute(@params) : default;
|
||||
}
|
||||
|
||||
public static T? ExecuteIfEnabled<T>(this PluginFunction @this, PluginFunctionSimpleParamter? @params)
|
||||
{
|
||||
return @this.Enabled ? @this.Execute<T>(@params) : default;
|
||||
}
|
||||
|
||||
public static object? ExecuteIfEnabled(this PluginFunction @this, PluginFunctionParameter? @params)
|
||||
{
|
||||
return @this.Enabled ? @this.Execute(@params) : default;
|
||||
}
|
||||
|
||||
public static IEnumerable<T> Enabled<T>(this IEnumerable<T> @this) where T : PluginFeature
|
||||
{
|
||||
return @this.Where(n => n.Enabled);
|
||||
}
|
||||
|
||||
public static IEnumerable<T> Ordered<T>(this IEnumerable<T> @this) where T : PluginFeature
|
||||
{
|
||||
return @this.OrderByDescending(n => n.Prioritization);
|
||||
}
|
||||
}
|
||||
8
Pilz.Features/FeaturePrioritization.cs
Normal file
8
Pilz.Features/FeaturePrioritization.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
namespace Pilz.Features;
|
||||
|
||||
public enum FeaturePrioritization
|
||||
{
|
||||
Low = -1,
|
||||
Default = 0,
|
||||
High = 1,
|
||||
}
|
||||
5
Pilz.Features/IPluginFeatureConstructor.cs
Normal file
5
Pilz.Features/IPluginFeatureConstructor.cs
Normal file
@@ -0,0 +1,5 @@
|
||||
namespace Pilz.Features;
|
||||
|
||||
public interface IPluginFeatureConstructor
|
||||
{
|
||||
}
|
||||
12
Pilz.Features/IPluginFeatureProvider.cs
Normal file
12
Pilz.Features/IPluginFeatureProvider.cs
Normal file
@@ -0,0 +1,12 @@
|
||||
namespace Pilz.Features;
|
||||
|
||||
public interface IPluginFeatureProvider
|
||||
{
|
||||
static abstract PluginFeature Instance { get; }
|
||||
}
|
||||
|
||||
public interface IPluginFeatureProvider<T> : IPluginFeatureProvider where T : PluginFeature, IPluginFeatureProvider<T>
|
||||
{
|
||||
static new abstract T Instance { get; }
|
||||
static PluginFeature IPluginFeatureProvider.Instance => T.Instance;
|
||||
}
|
||||
6
Pilz.Features/IPluginFeaturesProvider.cs
Normal file
6
Pilz.Features/IPluginFeaturesProvider.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace Pilz.Features;
|
||||
|
||||
public interface IPluginFeaturesProvider
|
||||
{
|
||||
static abstract PluginFeature[] GetFeatures();
|
||||
}
|
||||
14
Pilz.Features/Pilz.Features.csproj
Normal file
14
Pilz.Features/Pilz.Features.csproj
Normal file
@@ -0,0 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net8.0</TargetFrameworks>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<Version>2.13.1</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
110
Pilz.Features/PluginFeature.cs
Normal file
110
Pilz.Features/PluginFeature.cs
Normal file
@@ -0,0 +1,110 @@
|
||||
namespace Pilz.Features;
|
||||
|
||||
public abstract class PluginFeature
|
||||
{
|
||||
/// <summary>
|
||||
/// Fires when the plugin feature gets used.
|
||||
/// <br/>- For <see cref="PluginFunction"/> this fires on <see cref="PluginFunction.ExecuteFunction(PluginFunctionParameter?)"/>.
|
||||
/// <br/>- For <see cref="T:PluginModule"/> this fires on <see cref="T:PluginModule.CreateNewUI(PluginFunctionParameter?)"/>.
|
||||
/// <br/>- For any other custom feature implementation this may variate.
|
||||
/// </summary>
|
||||
public static event PluginFeatureExecuteEventHandler? OnExecute;
|
||||
|
||||
/// <summary>
|
||||
/// The type of the feature defines where the feature get integrated.
|
||||
/// </summary>
|
||||
public string Type { get; init; }
|
||||
/// <summary>
|
||||
/// The identifier of the feature should be uniquie for the current <see cref="Type"/>.
|
||||
/// It defines a feature within a type.
|
||||
/// </summary>
|
||||
public string Identifier { get; init; }
|
||||
/// <summary>
|
||||
/// The full identifier of the feature should be uniquie and is the combination of <see cref="Type"/> and <see cref="Identifier"/>.
|
||||
/// It defines a feature across all types.
|
||||
/// </summary>
|
||||
public string FullIdentifier => GetFullIdentifier(Type, Identifier);
|
||||
/// <summary>
|
||||
/// The (display) name of the feature.
|
||||
/// </summary>
|
||||
public virtual string? Name { get; init; }
|
||||
/// <summary>
|
||||
/// The (display) description of the feature.
|
||||
/// </summary>
|
||||
public virtual string? Description { get; init; }
|
||||
/// <summary>
|
||||
/// The symbol for the feature.
|
||||
/// </summary>
|
||||
public virtual object? Icon { get; set; }
|
||||
/// <summary>
|
||||
/// Sets the prioritization of the feature.
|
||||
/// This will be respected on abfragen features and on inserting as items using the extension methods"/>.
|
||||
/// Some applications might implement a way to regonize feature prioritization via its own way.
|
||||
/// </summary>
|
||||
public virtual FeaturePrioritization Prioritization { get; set; }
|
||||
/// <summary>
|
||||
/// Defines if the feature is enabled/visible.
|
||||
/// </summary>
|
||||
public virtual bool Enabled { get; set; } = true;
|
||||
|
||||
protected PluginFeature(string type, string identifier)
|
||||
{
|
||||
Identifier = identifier;
|
||||
Type = type;
|
||||
}
|
||||
|
||||
protected PluginFeature(string type, string identifier, string? name) : this(type, identifier)
|
||||
{
|
||||
Name = name;
|
||||
}
|
||||
|
||||
public static string GetFullIdentifier(string featureType, string identifier)
|
||||
{
|
||||
return $"{featureType}:{identifier}";
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fires the <see cref="OnExecute"/> event with the status <see cref="PluginFeatureExecuteEventType.PostEvent"/>.
|
||||
/// </summary>
|
||||
/// <param name="params">The present <see cref="PluginFunctionParameter"/>.</param>
|
||||
/// <param name="result">The resulting object that will be returned.</param>
|
||||
/// <returns>Returns true if the original function should be executed.</returns>
|
||||
protected bool OnPreExecute(PluginFunctionParameter? @params, ref object? result)
|
||||
{
|
||||
if (OnExecute != null)
|
||||
{
|
||||
var args = new PluginFeatureExecuteEventArgs(PluginFeatureExecuteEventType.PreEvent, @params);
|
||||
|
||||
OnExecute.Invoke(this, args);
|
||||
|
||||
if (args.Handled)
|
||||
{
|
||||
result = args.Result;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Fires the <see cref="OnExecute"/> event with the status <see cref="PluginFeatureExecuteEventType.PostEvent"/>.
|
||||
/// </summary>
|
||||
/// <param name="params">The present <see cref="PluginFunctionParameter"/>.</param>
|
||||
/// <param name="result">The resulting object that will be returned.</param>
|
||||
protected void OnPostExecute(PluginFunctionParameter? @params, ref object? result)
|
||||
{
|
||||
if (OnExecute != null)
|
||||
{
|
||||
var args = new PluginFeatureExecuteEventArgs(PluginFeatureExecuteEventType.PostEvent, @params)
|
||||
{
|
||||
Result = result
|
||||
};
|
||||
|
||||
OnExecute.Invoke(this, args);
|
||||
|
||||
if (args.Handled)
|
||||
result = args.Result;
|
||||
}
|
||||
}
|
||||
}
|
||||
302
Pilz.Features/PluginFeatureController.cs
Normal file
302
Pilz.Features/PluginFeatureController.cs
Normal file
@@ -0,0 +1,302 @@
|
||||
using Pilz.Features.Exceptions;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Pilz.Features;
|
||||
|
||||
public class PluginFeatureController
|
||||
{
|
||||
// D e l e g a t e s
|
||||
|
||||
public delegate void PluginFeatureEventHandler(PluginFeatureController controller, PluginFeature feature);
|
||||
|
||||
// S t a t i c E v e n t s
|
||||
|
||||
/// <summary>
|
||||
/// Fires when a new <see cref="PluginFeature"/> has been registred.
|
||||
/// </summary>
|
||||
public static event PluginFeatureEventHandler? OnPluginFeatureReistred;
|
||||
|
||||
/// <summary>
|
||||
/// Fires when a <see cref="PluginFeature"/> has been unregistred.
|
||||
/// </summary>
|
||||
public static event PluginFeatureEventHandler? OnPluginFeatureUnregistred;
|
||||
|
||||
// S t a t i c M e m b e r s
|
||||
|
||||
protected static readonly string nameGetFeatures = $"{nameof(IPluginFeaturesProvider.GetFeatures)}";
|
||||
protected static readonly string nameGetFeaturesExplicit = $"{typeof(IPluginFeaturesProvider).FullName}.{nameof(IPluginFeaturesProvider.GetFeatures)}";
|
||||
protected static readonly string nameInstance = $"get_{nameof(IPluginFeatureProvider.Instance)}";
|
||||
protected static readonly string nameInstnaceExplicit = $"{typeof(IPluginFeaturesProvider).FullName}.get_{nameof(IPluginFeatureProvider.Instance)}";
|
||||
|
||||
/// <summary>
|
||||
/// The default public instance that can be used by plugins and the interface providing software.
|
||||
/// </summary>
|
||||
public static PluginFeatureController Instance { get; private set; } = new();
|
||||
|
||||
// I n s t a n c e M e m e b e r s
|
||||
|
||||
private readonly HashSet<PluginFeature> features = [];
|
||||
|
||||
/// <summary>
|
||||
/// A wrapper of all registred <see cref="PluginFeature"/> instances.
|
||||
/// </summary>
|
||||
public FeatureController Features { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// A wrapper for all registred <see cref="PluginModule"/> instances.
|
||||
/// </summary>
|
||||
public ModuleController Modules { get; init; }
|
||||
|
||||
/// <summary>
|
||||
/// A wrapper for all registred <see cref="PluginFunction"/> instances.
|
||||
/// </summary>
|
||||
public FunctionController Functions { get; init; }
|
||||
|
||||
public PluginFeatureController()
|
||||
{
|
||||
Features = new(this);
|
||||
Functions = new(this);
|
||||
Modules = new(this);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers all features found in the currently executing Assembly via <see cref="IPluginFeatureProvider"/>, <see cref="IPluginFeatureProvider{T}"/> and <see cref="IPluginFeaturesProvider"/>.
|
||||
/// <para><b>Note:</b><br/>Explicit implementations of <see cref="IPluginFeatureProvider{T}.Instance"/> can not be detected. For this case just implement <see cref="IPluginFeatureProvider.Instance"/> instead.</para>
|
||||
/// </summary>
|
||||
public void RegisterAllOwn(string? @namespace = null)
|
||||
{
|
||||
RegisterAll(Assembly.GetCallingAssembly());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers all features found in the given <see cref="Assembly[]"/> via <see cref="IPluginFeatureProvider"/>, <see cref="IPluginFeatureProvider{T}"/> and <see cref="IPluginFeaturesProvider"/>.
|
||||
/// <para><b>Note:</b><br/>Explicit implementations of <see cref="IPluginFeatureProvider{T}.Instance"/> can not be detected. For this case just implement <see cref="IPluginFeatureProvider.Instance"/> instead.</para>
|
||||
/// </summary>
|
||||
/// <param name="assemblies">The assemblies to query for types.</param>
|
||||
/// <param name="namespace">If not null, only types within the given namespace will be registered.</param>
|
||||
public void RegisterAll(Assembly[] assemblies, string? @namespace = null)
|
||||
{
|
||||
foreach (var assembly in assemblies)
|
||||
RegisterAll(assembly);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers all features found in the given <see cref="Assembly"/> via <see cref="IPluginFeatureProvider"/>, <see cref="IPluginFeatureProvider{T}"/> and <see cref="IPluginFeaturesProvider"/>.
|
||||
/// <para><b>Note:</b><br/>Explicit implementations of <see cref="IPluginFeatureProvider{T}.Instance"/> can not be detected. For this case just implement <see cref="IPluginFeatureProvider.Instance"/> instead.</para>
|
||||
/// </summary>
|
||||
/// <param name="assembly">The assembly to query for types.</param>
|
||||
/// <param name="namespace">If not null, only types within the given namespace will be registered.</param>
|
||||
public void RegisterAll(Assembly assembly, string? @namespace = null)
|
||||
{
|
||||
RegisterAll(assembly.GetTypes());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers all features found from the given <see cref="Type[]"/> via <see cref="IPluginFeatureProvider"/>, <see cref="IPluginFeatureProvider{T}"/> and <see cref="IPluginFeaturesProvider"/>.
|
||||
/// <para><b>Note:</b><br/>Explicit implementations of <see cref="IPluginFeatureProvider{T}.Instance"/> can not be detected. For this case just implement <see cref="IPluginFeatureProvider.Instance"/> instead.</para>
|
||||
/// </summary>
|
||||
/// <param name="types">The types to query for providers.</param>
|
||||
/// <param name="namespace">If not null, the types will only be processed if they're within the given namespace.</param>
|
||||
public void RegisterAll(Type[] types, string? @namespace = null)
|
||||
{
|
||||
foreach (var type in types)
|
||||
RegisterAll(type);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers all features found from the given <see cref="Type"/> via <see cref="IPluginFeatureProvider"/>, <see cref="IPluginFeatureProvider{T}"/> and <see cref="IPluginFeaturesProvider"/>.
|
||||
/// <para><b>Note:</b><br/>Explicit implementations of <see cref="IPluginFeatureProvider{T}.Instance"/> can not be detected. For this case just implement <see cref="IPluginFeatureProvider.Instance"/> instead.</para>
|
||||
/// </summary>
|
||||
/// <param name="type">The type to query for providers.</param>
|
||||
/// <param name="namespace">If not null, the type will only be processed if it's within the given namespace.</param>
|
||||
public void RegisterAll(Type type, string? @namespace = null)
|
||||
{
|
||||
if (@namespace != null && type.Namespace != null && type.Namespace != @namespace && !type.Namespace.StartsWith(@namespace + ".") || type.IsAbstract)
|
||||
return;
|
||||
|
||||
if (type.IsAssignableTo(typeof(IPluginFeaturesProvider)))
|
||||
{
|
||||
var methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
var method = methods.FirstOrDefault(n => n.Name == nameGetFeaturesExplicit || n.Name == nameGetFeatures);
|
||||
|
||||
if (method != null && method.Invoke(null, null) is PluginFeature[] features)
|
||||
{
|
||||
foreach (var feature in features)
|
||||
Register(feature);
|
||||
}
|
||||
}
|
||||
else if (type.IsAssignableTo(typeof(IPluginFeatureProvider)))
|
||||
{
|
||||
var methods = type.GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic);
|
||||
var method = methods.FirstOrDefault(n => n.Name == nameInstnaceExplicit || n.Name == nameInstance);
|
||||
|
||||
if (method != null && method.Invoke(null, null) is PluginFeature feature)
|
||||
Register(feature);
|
||||
}
|
||||
else if (type.IsAssignableTo(typeof(IPluginFeatureConstructor)))
|
||||
{
|
||||
if (type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, [typeof(PluginFeatureController)]) is ConstructorInfo ctor1)
|
||||
{
|
||||
if (ctor1.Invoke([this]) is PluginFeature feature)
|
||||
Register(feature);
|
||||
}
|
||||
else if (type.GetConstructor(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic, []) is ConstructorInfo ctor)
|
||||
{
|
||||
if (ctor.Invoke([]) is PluginFeature feature)
|
||||
Register(feature);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers a feature via the given <see cref="IPluginFeatureProvider"/> or <see cref="IPluginFeatureProvider{T}"/>.
|
||||
/// </summary>
|
||||
public void Register<TProvider>() where TProvider : IPluginFeatureProvider
|
||||
{
|
||||
Register(TProvider.Instance);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers all features via the given <see cref="IPluginFeaturesProvider"/>.
|
||||
/// </summary>
|
||||
public void RegisterAll<TProvider>() where TProvider : IPluginFeaturesProvider
|
||||
{
|
||||
foreach (var feature in TProvider.GetFeatures())
|
||||
Register(feature);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Registers the given feature.
|
||||
/// </summary>
|
||||
/// <param name="module"></param>
|
||||
public void Register(PluginFeature module)
|
||||
{
|
||||
if (features.Add(module))
|
||||
OnPluginFeatureReistred?.Invoke(this, module);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unregisters the given feature.
|
||||
/// </summary>
|
||||
/// <param name="module"></param>
|
||||
public void Unregister(PluginFeature module)
|
||||
{
|
||||
features.Remove(module);
|
||||
OnPluginFeatureUnregistred?.Invoke(this, module);
|
||||
}
|
||||
|
||||
public class FeatureController(PluginFeatureController controller)
|
||||
{
|
||||
protected readonly PluginFeatureController controller = controller;
|
||||
|
||||
public virtual IEnumerable<PluginFeature> GetAll()
|
||||
{
|
||||
return [.. controller.features];
|
||||
}
|
||||
|
||||
public virtual IEnumerable<T> GetAll<T>() where T : PluginFeature
|
||||
{
|
||||
return controller.features.OfType<T>();
|
||||
}
|
||||
|
||||
public virtual T? Get<T>() where T : PluginFeature
|
||||
{
|
||||
return GetAll<T>().FirstOrDefault();
|
||||
}
|
||||
|
||||
public virtual T EnsureGet<T>() where T : PluginFeature
|
||||
{
|
||||
if (Get<T>() is T feature)
|
||||
return feature;
|
||||
throw new PluginFeatureNotFoundException();
|
||||
}
|
||||
|
||||
public virtual IEnumerable<PluginFeature> Get(string featureType)
|
||||
{
|
||||
return controller.features.Where(n => n.Type == featureType);
|
||||
}
|
||||
|
||||
public virtual PluginFeature? GetFirst(string featureType)
|
||||
{
|
||||
return controller.features.FirstOrDefault(n => n.Type == featureType);
|
||||
}
|
||||
|
||||
public virtual PluginFeature? GetByIdentifier(string fullIdentifier)
|
||||
{
|
||||
return controller.features.FirstOrDefault(n => n.FullIdentifier == fullIdentifier);
|
||||
}
|
||||
|
||||
public virtual PluginFeature? GetByIdentifier(string featureType, string identifier)
|
||||
{
|
||||
return controller.features.FirstOrDefault(n => n.Type == featureType && n.Identifier == identifier);
|
||||
}
|
||||
}
|
||||
|
||||
public class FeatureController<T>(PluginFeatureController controller) : FeatureController(controller) where T : PluginFeature
|
||||
{
|
||||
public override IEnumerable<T> GetAll()
|
||||
{
|
||||
return GetAll<T>();
|
||||
}
|
||||
|
||||
public override IEnumerable<T> Get(string moduleType)
|
||||
{
|
||||
return GetAll().Where(n => n.Type == moduleType);
|
||||
}
|
||||
|
||||
public override T? GetFirst(string moduleType)
|
||||
{
|
||||
return base.GetFirst(moduleType) as T;
|
||||
}
|
||||
|
||||
public override T? GetByIdentifier(string fullIdentifier)
|
||||
{
|
||||
return base.GetByIdentifier(fullIdentifier) as T;
|
||||
}
|
||||
|
||||
public override T? GetByIdentifier(string featureType, string identifier)
|
||||
{
|
||||
return base.GetByIdentifier(featureType, identifier) as T;
|
||||
}
|
||||
}
|
||||
|
||||
public class ModuleController(PluginFeatureController controller) : FeatureController<PluginModuleBase>(controller)
|
||||
{
|
||||
}
|
||||
|
||||
public class FunctionController(PluginFeatureController controller) : FeatureController<PluginFunction>(controller)
|
||||
{
|
||||
public void ExecuteAll(string functionType)
|
||||
{
|
||||
foreach (var function in Get(functionType))
|
||||
function.Execute();
|
||||
}
|
||||
|
||||
public void ExecuteAll(string functionType, params object?[]? @params)
|
||||
{
|
||||
foreach (var function in Get(functionType))
|
||||
function.Execute(@params);
|
||||
}
|
||||
|
||||
public void ExecuteAll(string functionType, PluginFunctionParameter @params)
|
||||
{
|
||||
foreach (var function in Get(functionType))
|
||||
function.Execute(@params);
|
||||
}
|
||||
|
||||
public IEnumerable<object?> ExcuteAndGetResults(string functionType)
|
||||
{
|
||||
return Get(functionType).Select(n => n.Execute());
|
||||
}
|
||||
|
||||
public IEnumerable<object?> ExcuteAndGetResults(string functionType, params object?[]? @params)
|
||||
{
|
||||
return Get(functionType).Select(n => n.Execute(@params));
|
||||
}
|
||||
|
||||
public IEnumerable<object?> ExcuteAndGetResults(string functionType, PluginFunctionParameter @params)
|
||||
{
|
||||
return Get(functionType).Select(n => n.Execute(@params));
|
||||
}
|
||||
}
|
||||
}
|
||||
9
Pilz.Features/PluginFeatureExecuteEventArgs.cs
Normal file
9
Pilz.Features/PluginFeatureExecuteEventArgs.cs
Normal file
@@ -0,0 +1,9 @@
|
||||
namespace Pilz.Features;
|
||||
|
||||
public class PluginFeatureExecuteEventArgs(PluginFeatureExecuteEventType eventType, PluginFunctionParameter? parameters) : EventArgs
|
||||
{
|
||||
public PluginFeatureExecuteEventType EventType { get; } = eventType;
|
||||
public PluginFunctionParameter? Parameters { get; } = parameters;
|
||||
public bool Handled { get; set; }
|
||||
public object? Result { get; set; }
|
||||
}
|
||||
7
Pilz.Features/PluginFeatureExecuteEventType.cs
Normal file
7
Pilz.Features/PluginFeatureExecuteEventType.cs
Normal file
@@ -0,0 +1,7 @@
|
||||
namespace Pilz.Features;
|
||||
|
||||
public enum PluginFeatureExecuteEventType
|
||||
{
|
||||
PreEvent,
|
||||
PostEvent,
|
||||
}
|
||||
90
Pilz.Features/PluginFunction.cs
Normal file
90
Pilz.Features/PluginFunction.cs
Normal file
@@ -0,0 +1,90 @@
|
||||
namespace Pilz.Features;
|
||||
|
||||
public abstract class PluginFunction : PluginFeature
|
||||
{
|
||||
protected PluginFunction(string type, string identifier) : base(type, identifier)
|
||||
{
|
||||
}
|
||||
|
||||
protected PluginFunction(string type, string identifier, string? name) : base(type, identifier, name)
|
||||
{
|
||||
}
|
||||
|
||||
public virtual object? Execute()
|
||||
{
|
||||
return Execute((PluginFunctionParameter?)null);
|
||||
}
|
||||
|
||||
public virtual T? Execute<T>(params object?[]? @params)
|
||||
{
|
||||
return Execute<T>(new PluginFunctionSimpleParamter(@params));
|
||||
}
|
||||
|
||||
public virtual object? Execute(params object?[]? @params)
|
||||
{
|
||||
return Execute(new PluginFunctionSimpleParamter(@params));
|
||||
}
|
||||
|
||||
public virtual T? Execute<T>(PluginFunctionSimpleParamter? @params)
|
||||
{
|
||||
if (Execute(@params) is T result)
|
||||
return result;
|
||||
return default;
|
||||
}
|
||||
|
||||
public virtual object? Execute(PluginFunctionParameter? @params)
|
||||
{
|
||||
object? result = null;
|
||||
|
||||
if (OnPreExecute(@params, ref result))
|
||||
result = ExecuteFunction(@params);
|
||||
|
||||
OnPostExecute(@params, ref result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
public virtual Task<object?> ExecuteAsync()
|
||||
{
|
||||
return ExecuteAsync((PluginFunctionParameter?)null);
|
||||
}
|
||||
|
||||
public virtual Task<T?> ExecuteAsync<T>(params object?[]? @params)
|
||||
{
|
||||
return ExecuteAsync<T>(new PluginFunctionSimpleParamter(@params));
|
||||
}
|
||||
|
||||
public virtual Task<object?> ExecuteAsync(params object?[]? @params)
|
||||
{
|
||||
return ExecuteAsync(new PluginFunctionSimpleParamter(@params));
|
||||
}
|
||||
|
||||
public virtual async Task<T?> ExecuteAsync<T>(PluginFunctionSimpleParamter? @params)
|
||||
{
|
||||
if (await ExecuteAsync(@params) is T result)
|
||||
return result;
|
||||
return default;
|
||||
}
|
||||
|
||||
public virtual async Task<object?> ExecuteAsync(PluginFunctionParameter? @params)
|
||||
{
|
||||
object? result = null;
|
||||
|
||||
if (OnPreExecute(@params, ref result))
|
||||
result = await ExecuteFunctionAsync(@params);
|
||||
|
||||
OnPostExecute(@params, ref result);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
protected virtual object? ExecuteFunction(PluginFunctionParameter? @params)
|
||||
{
|
||||
return ExecuteFunctionAsync(@params).GetAwaiter().GetResult();
|
||||
}
|
||||
|
||||
protected virtual Task<object?> ExecuteFunctionAsync(PluginFunctionParameter? @params)
|
||||
{
|
||||
return Task.FromResult(ExecuteFunction(@params));
|
||||
}
|
||||
}
|
||||
5
Pilz.Features/PluginFunctionParameter.cs
Normal file
5
Pilz.Features/PluginFunctionParameter.cs
Normal file
@@ -0,0 +1,5 @@
|
||||
namespace Pilz.Features;
|
||||
|
||||
public class PluginFunctionParameter
|
||||
{
|
||||
}
|
||||
11
Pilz.Features/PluginFunctionSimpleParamter.cs
Normal file
11
Pilz.Features/PluginFunctionSimpleParamter.cs
Normal file
@@ -0,0 +1,11 @@
|
||||
namespace Pilz.Features;
|
||||
|
||||
public sealed class PluginFunctionSimpleParamter : PluginFunctionParameter
|
||||
{
|
||||
public object?[]? Params { get; init; }
|
||||
|
||||
public PluginFunctionSimpleParamter(params object?[]? @params)
|
||||
{
|
||||
Params = @params;
|
||||
}
|
||||
}
|
||||
15
Pilz.Features/PluginModuleBase.cs
Normal file
15
Pilz.Features/PluginModuleBase.cs
Normal file
@@ -0,0 +1,15 @@
|
||||
using System.ComponentModel;
|
||||
|
||||
namespace Pilz.Features;
|
||||
|
||||
[EditorBrowsable(EditorBrowsableState.Never)]
|
||||
public abstract class PluginModuleBase : PluginFeature
|
||||
{
|
||||
protected PluginModuleBase(string type, string identifier) : base(type, identifier)
|
||||
{
|
||||
}
|
||||
|
||||
protected PluginModuleBase(string type, string identifier, string? name) : base(type, identifier, name)
|
||||
{
|
||||
}
|
||||
}
|
||||
14
Pilz.Gaming.Minecraft/Pilz.Gaming.Minecraft.csproj
Normal file
14
Pilz.Gaming.Minecraft/Pilz.Gaming.Minecraft.csproj
Normal file
@@ -0,0 +1,14 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFrameworks>net8.0</TargetFrameworks>
|
||||
<LangVersion>latest</LangVersion>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup>
|
||||
<Version>2.0.1</Version>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
40
Pilz.Gaming.Minecraft/Utils.cs
Normal file
40
Pilz.Gaming.Minecraft/Utils.cs
Normal file
@@ -0,0 +1,40 @@
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
|
||||
namespace Pilz.Gaming.Minecraft;
|
||||
|
||||
public static class Utils
|
||||
{
|
||||
public static string GetUUID(string value)
|
||||
{
|
||||
//extracted from the java code:
|
||||
//new GameProfile(UUID.nameUUIDFromBytes(("OfflinePlayer:" + name).getBytes(Charsets.UTF_8)), name));
|
||||
var data = MD5.HashData(Encoding.ASCII.GetBytes(value));
|
||||
//set the version to 3 -> Name based md5 hash
|
||||
data[6] = Convert.ToByte(data[6] & 0x0f | 0x30);
|
||||
//IETF variant
|
||||
data[8] = Convert.ToByte(data[8] & 0x3f | 0x80);
|
||||
|
||||
//example: 069a79f4-44e9-4726-a5be-fca90e38aaf5
|
||||
var striped = Convert.ToHexString(data);
|
||||
var components = new string[] {
|
||||
striped[..].Remove(8),
|
||||
striped[8..].Remove(4),
|
||||
striped[12..].Remove(4),
|
||||
striped[16..].Remove(4),
|
||||
striped[20..]
|
||||
};
|
||||
|
||||
return string.Join('-', components).ToLower();
|
||||
}
|
||||
|
||||
public static string GetPlayerUUID(string username, bool offlineMode)
|
||||
{
|
||||
using var md5 = MD5.Create();
|
||||
|
||||
if (!offlineMode)
|
||||
throw new NotSupportedException("Getting player's online UUID via the Mojang API is not supported at this time.");
|
||||
|
||||
return GetUUID("OfflinePlayer:" + username);
|
||||
}
|
||||
}
|
||||
@@ -1,174 +1,167 @@
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.IO.Compression;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Pilz.IO
|
||||
namespace Pilz.IO;
|
||||
|
||||
public class EmbeddedFilesContainer
|
||||
{
|
||||
public class EmbeddedFilesContainer
|
||||
[JsonProperty("CompressedFiles")]
|
||||
private readonly Dictionary<string, byte[]> compressedFiles = [];
|
||||
|
||||
/// <summary>
|
||||
/// Returns the names of all embedded files.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public IEnumerable<string> AllFileNames
|
||||
{
|
||||
[JsonProperty("CompressedFiles")]
|
||||
private readonly Dictionary<string, byte[]> compressedFiles = new Dictionary<string, byte[]>();
|
||||
get => compressedFiles.Keys;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the names of all embedded files.
|
||||
/// </summary>
|
||||
[JsonIgnore]
|
||||
public IEnumerable<string> AllFileNames
|
||||
{
|
||||
get => compressedFiles.Keys;
|
||||
}
|
||||
/// <summary>
|
||||
/// Embeds a file to this container.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name how it should be called in this container.</param>
|
||||
/// <param name="filePath">The file path to the file that should be embedded.</param>
|
||||
/// <returns>Returns a <see cref="bool"/> that defines if the file as been embedded successfully.</returns>
|
||||
public Task<bool> AddFileAsync(string fileName, string filePath)
|
||||
{
|
||||
return Task.Run(() => AddFile(fileName, filePath));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Embeds a file to this container.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name how it should be called in this container.</param>
|
||||
/// <param name="filePath">The file path to the file that should be embedded.</param>
|
||||
/// <returns>Returns a <see cref="bool"/> that defines if the file as been embedded successfully.</returns>
|
||||
public Task<bool> AddFileAsync(string fileName, string filePath)
|
||||
{
|
||||
return Task.Run(() => AddFile(fileName, filePath));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Embeds a file to this container.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name how it should be called in this container.</param>
|
||||
/// <param name="filePath">The file path to the file that should be embedded.</param>
|
||||
/// <returns>Returns a <see cref="bool"/> that defines if the file as been embedded successfully.</returns>
|
||||
public bool AddFile(string fileName, string filePath)
|
||||
{
|
||||
bool success;
|
||||
FileStream fs = null;
|
||||
MemoryStream compressed = null;
|
||||
/// <summary>
|
||||
/// Embeds a file to this container.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name how it should be called in this container.</param>
|
||||
/// <param name="filePath">The file path to the file that should be embedded.</param>
|
||||
/// <returns>Returns a <see cref="bool"/> that defines if the file as been embedded successfully.</returns>
|
||||
public bool AddFile(string fileName, string filePath)
|
||||
{
|
||||
bool success;
|
||||
FileStream fs = null;
|
||||
MemoryStream compressed = null;
|
||||
|
||||
#if !DEBUG
|
||||
try
|
||||
{
|
||||
try
|
||||
{
|
||||
#endif
|
||||
fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
|
||||
compressed = new MemoryStream();
|
||||
using (var compressor = new DeflateStream(compressed, CompressionLevel.Optimal, true))
|
||||
fs.CopyTo(compressor);
|
||||
success = true;
|
||||
fs = new FileStream(filePath, FileMode.Open, FileAccess.Read);
|
||||
compressed = new MemoryStream();
|
||||
using (var compressor = new DeflateStream(compressed, CompressionLevel.Optimal, true))
|
||||
fs.CopyTo(compressor);
|
||||
success = true;
|
||||
#if !DEBUG
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
success = false;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (success)
|
||||
{
|
||||
var compressedBytes = compressed.ToArray();
|
||||
if (compressedFiles.ContainsKey(fileName))
|
||||
compressedFiles[fileName] = compressedBytes;
|
||||
else
|
||||
compressedFiles.Add(fileName, compressedBytes);
|
||||
}
|
||||
|
||||
compressed?.Close();
|
||||
fs?.Close();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a file from this container.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name how the file is called.</param>
|
||||
public void RemoveFile(string fileName)
|
||||
if (success)
|
||||
{
|
||||
var compressedBytes = compressed.ToArray();
|
||||
if (compressedFiles.ContainsKey(fileName))
|
||||
compressedFiles.Remove(fileName);
|
||||
compressedFiles[fileName] = compressedBytes;
|
||||
else
|
||||
compressedFiles.Add(fileName, compressedBytes);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the given file exists in this container.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name how the file is called.</param>
|
||||
/// <returns>Returns if the given file exists in this container.</returns>
|
||||
public bool HasFile(string fileName)
|
||||
compressed?.Close();
|
||||
fs?.Close();
|
||||
|
||||
return success;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes a file from this container.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name how the file is called.</param>
|
||||
public void RemoveFile(string fileName)
|
||||
{
|
||||
if (compressedFiles.ContainsKey(fileName))
|
||||
compressedFiles.Remove(fileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the given file exists in this container.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name how the file is called.</param>
|
||||
/// <returns>Returns if the given file exists in this container.</returns>
|
||||
public bool HasFile(string fileName)
|
||||
{
|
||||
return compressedFiles.ContainsKey(fileName);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a file from this container as stream.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name how the file is called.</param>
|
||||
/// <returns>Returns a stream of the file with the given name.</returns>
|
||||
public Task<Stream> GetStreamAsync(string fileName)
|
||||
{
|
||||
return Task.Run(() => GetStream(fileName));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a file from this container as stream.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name how the file is called.</param>
|
||||
/// <returns>Returns a stream of the file with the given name.</returns>
|
||||
public Stream GetStream(string fileName)
|
||||
{
|
||||
Stream decompressed = null;
|
||||
|
||||
if (compressedFiles.ContainsKey(fileName))
|
||||
{
|
||||
return compressedFiles.ContainsKey(fileName);
|
||||
decompressed = new MemoryStream();
|
||||
DecompressToStream(decompressed, compressedFiles[fileName]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a file from this container as stream.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name how the file is called.</param>
|
||||
/// <returns>Returns a stream of the file with the given name.</returns>
|
||||
public Task<Stream> GetStreamAsync(string fileName)
|
||||
return decompressed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves a given file to the users temp directory.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name how the file is called.</param>
|
||||
/// <returns>Returns the file path to the temp file.</returns>
|
||||
public Task<string> GetLocalFilePathAsync(string fileName)
|
||||
{
|
||||
return Task.Run(() => GetLocalFilePath(fileName));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Saves a given file to the users temp directory.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name how the file is called.</param>
|
||||
/// <returns>Returns the file path to the temp file.</returns>
|
||||
public string GetLocalFilePath(string fileName)
|
||||
{
|
||||
string filePath = string.Empty;
|
||||
|
||||
if (compressedFiles.ContainsKey(fileName))
|
||||
{
|
||||
return Task.Run(() => GetStream(fileName));
|
||||
filePath = Path.GetTempFileName();
|
||||
|
||||
if (Path.HasExtension(fileName))
|
||||
filePath = Path.ChangeExtension(filePath, Path.GetExtension(fileName));
|
||||
|
||||
var decompressed = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite);
|
||||
DecompressToStream(decompressed, compressedFiles[fileName]);
|
||||
decompressed.Flush();
|
||||
decompressed.Close();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a file from this container as stream.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name how the file is called.</param>
|
||||
/// <returns>Returns a stream of the file with the given name.</returns>
|
||||
public Stream GetStream(string fileName)
|
||||
{
|
||||
Stream decompressed = null;
|
||||
return filePath;
|
||||
}
|
||||
|
||||
if (compressedFiles.ContainsKey(fileName))
|
||||
{
|
||||
decompressed = new MemoryStream();
|
||||
DecompressToStream(decompressed, compressedFiles[fileName]);
|
||||
}
|
||||
|
||||
return decompressed;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Saves a given file to the users temp directory.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name how the file is called.</param>
|
||||
/// <returns>Returns the file path to the temp file.</returns>
|
||||
public Task<string> GetLocalFilePathAsync(string fileName)
|
||||
{
|
||||
return Task.Run(() => GetLocalFilePath(fileName));
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Saves a given file to the users temp directory.
|
||||
/// </summary>
|
||||
/// <param name="fileName">The name how the file is called.</param>
|
||||
/// <returns>Returns the file path to the temp file.</returns>
|
||||
public string GetLocalFilePath(string fileName)
|
||||
{
|
||||
string filePath = string.Empty;
|
||||
|
||||
if (compressedFiles.ContainsKey(fileName))
|
||||
{
|
||||
filePath = Path.GetTempFileName();
|
||||
|
||||
if (Path.HasExtension(fileName))
|
||||
filePath = Path.ChangeExtension(filePath, Path.GetExtension(fileName));
|
||||
|
||||
var decompressed = new FileStream(filePath, FileMode.Create, FileAccess.ReadWrite);
|
||||
DecompressToStream(decompressed, compressedFiles[fileName]);
|
||||
decompressed.Flush();
|
||||
decompressed.Close();
|
||||
}
|
||||
|
||||
return filePath;
|
||||
}
|
||||
|
||||
private void DecompressToStream(Stream decompressed, byte[] compressedData)
|
||||
{
|
||||
var compressed = new MemoryStream(compressedData);
|
||||
var decompressor = new DeflateStream(compressed, CompressionMode.Decompress, true);
|
||||
decompressor.CopyTo(decompressed);
|
||||
decompressor.Close();
|
||||
compressed.Close();
|
||||
}
|
||||
private void DecompressToStream(Stream decompressed, byte[] compressedData)
|
||||
{
|
||||
var compressed = new MemoryStream(compressedData);
|
||||
var decompressor = new DeflateStream(compressed, CompressionMode.Decompress, true);
|
||||
decompressor.CopyTo(decompressed);
|
||||
decompressor.Close();
|
||||
compressed.Close();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +0,0 @@
|
||||
using System;
|
||||
|
||||
namespace Pilz.IO
|
||||
{
|
||||
public class DataEventArgs : EventArgs
|
||||
{
|
||||
public readonly byte[] Data;
|
||||
|
||||
public DataEventArgs(byte[] bytes) : base()
|
||||
{
|
||||
Data = bytes;
|
||||
}
|
||||
}
|
||||
}
|
||||
6
Pilz.IO/EventArguments/DataEventargs.cs
Normal file
6
Pilz.IO/EventArguments/DataEventargs.cs
Normal file
@@ -0,0 +1,6 @@
|
||||
namespace Pilz.IO.EventArguments;
|
||||
|
||||
public class DataEventArgs(byte[] data) : EventArgs()
|
||||
{
|
||||
public byte[] Data { get; } = data;
|
||||
}
|
||||
@@ -1,118 +1,114 @@
|
||||
using System;
|
||||
using System.IO;
|
||||
namespace Pilz.IO;
|
||||
|
||||
namespace Pilz.IO
|
||||
public partial class FileLocker : IDisposable
|
||||
{
|
||||
public partial class FileLocker : IDisposable
|
||||
private FileStream fsLock = null;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the file path to the file that should be locked.
|
||||
/// </summary>
|
||||
public string FilePath { get; private set; }
|
||||
/// <summary>
|
||||
/// Defines the file path to the lock file that is used to identify the file lock.
|
||||
/// </summary>
|
||||
public string LockFile { get; private set; }
|
||||
/// <summary>
|
||||
/// Defines if the file is locked privatly by this instance.
|
||||
/// </summary>
|
||||
public bool LockedPrivate { get; private set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Defines if the file is locked by an other instance/program/user.
|
||||
/// </summary>
|
||||
public bool LockedExternal
|
||||
{
|
||||
private FileStream fsLock = null;
|
||||
|
||||
/// <summary>
|
||||
/// Defines the file path to the file that should be locked.
|
||||
/// </summary>
|
||||
public string FilePath { get; private set; }
|
||||
/// <summary>
|
||||
/// Defines the file path to the lock file that is used to identify the file lock.
|
||||
/// </summary>
|
||||
public string LockFile { get; private set; }
|
||||
/// <summary>
|
||||
/// Defines if the file is locked privatly by this instance.
|
||||
/// </summary>
|
||||
public bool LockedPrivate { get; private set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Defines if the file is locked by an other instance/program/user.
|
||||
/// </summary>
|
||||
public bool LockedExternal
|
||||
{
|
||||
get
|
||||
{
|
||||
if (LockedPrivate)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
string lockFile = FilePath + ".lock";
|
||||
bool isLocked = false;
|
||||
|
||||
if (File.Exists(lockFile))
|
||||
{
|
||||
try
|
||||
{
|
||||
var fs = new FileStream(lockFile, FileMode.Open, FileAccess.Read);
|
||||
fs.Close();
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
isLocked = true;
|
||||
}
|
||||
}
|
||||
|
||||
return isLocked;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a new instance of <see cref="FileLocker"/> and locks the given file automatically.
|
||||
/// </summary>
|
||||
/// <param name="filePath">The file path to the file that should be locked.</param>
|
||||
public FileLocker(string filePath) : this(filePath, true)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a new instance of <see cref="FileLocker"/>
|
||||
/// </summary>
|
||||
/// <param name="filePath">The file path to the file that should be locked.</param>
|
||||
/// <param name="autoLock">Defines if the file should be locked automatically right after creating this instance.</param>
|
||||
public FileLocker(string filePath, bool autoLock)
|
||||
{
|
||||
FilePath = filePath;
|
||||
LockFile = filePath + ".lock";
|
||||
if (autoLock) Lock();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Locks the file, if not already locked privatly.
|
||||
/// </summary>
|
||||
public void Lock()
|
||||
{
|
||||
if (!LockedPrivate)
|
||||
{
|
||||
fsLock = new FileStream(LockFile, FileMode.Create, FileAccess.ReadWrite);
|
||||
LockedPrivate = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unlocks the file, if locked privatly.
|
||||
/// </summary>
|
||||
public void Unlock()
|
||||
get
|
||||
{
|
||||
if (LockedPrivate)
|
||||
return false;
|
||||
else
|
||||
{
|
||||
fsLock.Close();
|
||||
fsLock.Dispose();
|
||||
fsLock = null;
|
||||
File.Delete(LockFile);
|
||||
LockedPrivate = false;
|
||||
string lockFile = FilePath + ".lock";
|
||||
bool isLocked = false;
|
||||
|
||||
if (File.Exists(lockFile))
|
||||
{
|
||||
try
|
||||
{
|
||||
var fs = new FileStream(lockFile, FileMode.Open, FileAccess.Read);
|
||||
fs.Close();
|
||||
}
|
||||
catch (IOException)
|
||||
{
|
||||
isLocked = true;
|
||||
}
|
||||
}
|
||||
|
||||
return isLocked;
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable
|
||||
private bool disposedValue;
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposedValue)
|
||||
Unlock();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
disposedValue = true;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a new instance of <see cref="FileLocker"/> and locks the given file automatically.
|
||||
/// </summary>
|
||||
/// <param name="filePath">The file path to the file that should be locked.</param>
|
||||
public FileLocker(string filePath) : this(filePath, true)
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Generate a new instance of <see cref="FileLocker"/>
|
||||
/// </summary>
|
||||
/// <param name="filePath">The file path to the file that should be locked.</param>
|
||||
/// <param name="autoLock">Defines if the file should be locked automatically right after creating this instance.</param>
|
||||
public FileLocker(string filePath, bool autoLock)
|
||||
{
|
||||
FilePath = filePath;
|
||||
LockFile = filePath + ".lock";
|
||||
if (autoLock) Lock();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Locks the file, if not already locked privatly.
|
||||
/// </summary>
|
||||
public void Lock()
|
||||
{
|
||||
if (!LockedPrivate)
|
||||
{
|
||||
fsLock = new FileStream(LockFile, FileMode.Create, FileAccess.ReadWrite);
|
||||
LockedPrivate = true;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Unlocks the file, if locked privatly.
|
||||
/// </summary>
|
||||
public void Unlock()
|
||||
{
|
||||
if (LockedPrivate)
|
||||
{
|
||||
fsLock.Close();
|
||||
fsLock.Dispose();
|
||||
fsLock = null;
|
||||
File.Delete(LockFile);
|
||||
LockedPrivate = false;
|
||||
}
|
||||
}
|
||||
|
||||
#region IDisposable
|
||||
private bool disposedValue;
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!disposedValue)
|
||||
Unlock();
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
Dispose(true);
|
||||
disposedValue = true;
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
@@ -1,67 +1,64 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
using Pilz.IO.EventArguments;
|
||||
|
||||
namespace Pilz.IO
|
||||
namespace Pilz.IO.ManagedPipes;
|
||||
|
||||
/// <summary>
|
||||
/// stellt den Erben "Server" und "Client" 2 verschiedene
|
||||
/// Message-Events zur Verfügung, und ein Event-Raisendes Dispose
|
||||
/// </summary>
|
||||
public abstract class ManagedPipe : IDisposable
|
||||
{
|
||||
public delegate void EventHandlerWithOneArgument<T0>(T0 Sender);
|
||||
|
||||
/// <summary>
|
||||
/// stellt den Erben "Server" und "Client" 2 verschiedene
|
||||
/// Message-Events zur Verfügung, und ein Event-Raisendes Dispose
|
||||
/// Zur Ausgabe chat-verwaltungstechnischer Status-Informationen
|
||||
/// </summary>
|
||||
public abstract class ManagedPipe : IDisposable
|
||||
public event EventHandler<DataEventArgs> StatusMessage;
|
||||
/// <summary>Zur Ausgabe von Chat-Messages</summary>
|
||||
public event EventHandler<DataEventArgs> RetriveData;
|
||||
public event EventHandlerWithOneArgument<ManagedPipe> Disposed;
|
||||
|
||||
private bool _IsDisposed = false;
|
||||
|
||||
protected abstract void Dispose(bool disposing);
|
||||
public abstract void Send(byte[] bytes);
|
||||
public abstract Task SendAsnyc(byte[] bytes);
|
||||
|
||||
protected void OnStatusMessage(DataEventArgs e)
|
||||
{
|
||||
public delegate void EventHandlerWithOneArgument<T0>(T0 Sender);
|
||||
StatusMessage?.Invoke(this, e);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Zur Ausgabe chat-verwaltungstechnischer Status-Informationen
|
||||
/// </summary>
|
||||
public event EventHandler<DataEventArgs> StatusMessage;
|
||||
/// <summary>Zur Ausgabe von Chat-Messages</summary>
|
||||
public event EventHandler<DataEventArgs> RetriveData;
|
||||
public event EventHandlerWithOneArgument<ManagedPipe> Disposed;
|
||||
protected void OnRetriveData(DataEventArgs e)
|
||||
{
|
||||
RetriveData?.Invoke(this, e);
|
||||
}
|
||||
|
||||
private bool _IsDisposed = false;
|
||||
public void RemoveFrom<T>(ICollection<T> Coll) where T : ManagedPipe
|
||||
{
|
||||
Coll.Remove((T)this);
|
||||
}
|
||||
|
||||
protected abstract void Dispose(bool disposing);
|
||||
public abstract void Send(byte[] bytes);
|
||||
public abstract Task SendAsnyc(byte[] bytes);
|
||||
|
||||
protected void OnStatusMessage(DataEventArgs e)
|
||||
public bool IsDisposed
|
||||
{
|
||||
get
|
||||
{
|
||||
StatusMessage?.Invoke(this, e);
|
||||
}
|
||||
|
||||
protected void OnRetriveData(DataEventArgs e)
|
||||
{
|
||||
RetriveData?.Invoke(this, e);
|
||||
}
|
||||
|
||||
public void RemoveFrom<T>(ICollection<T> Coll) where T : ManagedPipe
|
||||
{
|
||||
Coll.Remove((T)this);
|
||||
}
|
||||
|
||||
public bool IsDisposed
|
||||
{
|
||||
get
|
||||
{
|
||||
return _IsDisposed;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddTo<T>(ICollection<T> Coll) where T : ManagedPipe
|
||||
{
|
||||
Coll.Add((T)this);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_IsDisposed)
|
||||
return;
|
||||
_IsDisposed = true;
|
||||
Dispose(true); // rufe die erzwungenen Überschreibungen von Sub Dispose(Boolean)
|
||||
Disposed?.Invoke(this);
|
||||
GC.SuppressFinalize(this);
|
||||
return _IsDisposed;
|
||||
}
|
||||
}
|
||||
|
||||
public void AddTo<T>(ICollection<T> Coll) where T : ManagedPipe
|
||||
{
|
||||
Coll.Add((T)this);
|
||||
}
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
if (_IsDisposed)
|
||||
return;
|
||||
_IsDisposed = true;
|
||||
Dispose(true); // rufe die erzwungenen Überschreibungen von Sub Dispose(Boolean)
|
||||
Disposed?.Invoke(this);
|
||||
GC.SuppressFinalize(this);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user