-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathExGdata.h
410 lines (332 loc) · 14.3 KB
/
ExGdata.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
#ifndef __JBXL_CPP_EXTEND_GRAPHIC_DATA_H_
#define __JBXL_CPP_EXTEND_GRAPHIC_DATA_H_
/**
@brief メモリ管理機能付グラフィックデータ定義用ヘッダ
@file ExGdata.h
@author Fumi.Iseki
*/
#include "Gdata.h"
//
namespace jbxl {
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// メモリ管理機能付 ExMSGraph, ExCmnHead
//
/**
@file ExGdata.h
メモリ管理機能
---
@par メモリ管理を付ける事の利点:
色々な関数(クラス)から同時に使用(兼用)できるので,メモリの節約になる.メモリが沢山(無尽蔵に)
あるのなら,その都度コピーして渡した方がアルゴリズムは簡単.
@par 手法:
メモリ(データ)に対して,ペアとなるint型の参照数変数を用意し,メモリへの参照数を参照数変数に格納する.
そのため operator= をオーバーロードする.@n
メモリ管理機能の無い変数から代入される場合は,予め参照数変数を結合しておかないと,メモリ管理
機能無しの状態になる.@n
例えば,msgにメモリ管理機能を持たせるには,以下のようにする.
@code
int ref;
ExMSGraph<> msg;
msg.setRefer(&ref);
msg = vp; // vp: 管理機能無しの変数
@endcode
また,以下の場合 xpがメモリ(データ)を持つ時は注意.
@code
ExMSGraph<> msg;
msg = xp; // xp: 管理機能ありの変数
msg = vp; // vp: 管理機能無しの変数
@endcode
msgは xpの参照数変数を引き継ぎ,メモリ(データ)管理機能付変数となる.@n
msgのメモリ部(データ)が空の場合,msg = vp; では,引き続き参照数変数を使用して,
vpのメモリ(データ)を管理する.@n
msgにメモリ(データ)が存在する場合,msg = vp; でmsgはそのメモリ(データ)への参照を止め,vp をコピーする.@n
すなわち,この場合はメモリ管理機能なしになる.@n
つまり,xpがメモリ(データ)を持たなければ,xp, msgの参照数変数は 1になり,msgは vpのメモリを管理する.@n
xpがメモリを持っていれば,msgはメモリ管理機能なしになる.@n
@par 参照数変数
- 1以上 : メモリ(グラフィックデータ)が存在し,参照されている.
- 0 : メモリ(グラフィックデータ)は存在するが,どこからも参照されていない.
通常この状態は一時的であり,次のステップで 1 か -1になる.
- -1 : メモリ(グラフィックデータ)は存在しない.
- -2以下 : 通常この状態は -1 に戻される.
@attention
ディストラクタはメモリを解放しないので,必ず手動で解放すること.
*/
/**
template <typename T=uWord> class ExMSGraph : public MSGraph<T>
必ず参照数変数(refnoの実体)を指定すること.無くても動くかも知れないが,保証は無い.
関数の中からディストラクトされるメモリ(のコピー)をリターンする場合は,returnの前に
mfree()を実行させること.
*/
template <typename T=uWord> class ExMSGraph : public MSGraph<T>
{
public:
//protected:
int* refno; // メモリ領域への参照オブジェクト数
//
public:
ExMSGraph(int x, int y=1, int z=1, T v=(T)0, T b=(T)0, double rz=1.0, int* rn=NULL) { set(x, y, z, v, b, rz, rn);}
ExMSGraph(RBound<int> rb, T v=(T)0, T b=(T)0, double rz=1.0, int* rn=NULL){ set(rb, v, b, rz, rn);}
ExMSGraph(int* rn=NULL) { MSGraph<T>::init(); setRefer(rn);}
virtual ~ExMSGraph(void) {}
void set(int x, int y=1, int z=1, T v=(T)0, T b=(T)0, double rz=1.0, int*rn=NULL);
void set(RBound<int> rb, T v=(T)0, T b=(T)0, double rz=1.0, int*rn=NULL);
void mimicry(ExMSGraph<T> s) { set(s.xs, s.ys, s.zs, s.zero, s.base, s.RZxy, NULL);}
bool isNull(void); ///< グラフィックデータを持いないか?
void free(void); ///< グラフィックデータを開放する(メモリ管理なし兼用)
void mfree(bool azero=false); ///< グラフィックデータを開放する
void ffree(void); ///< グラフィックデータを強制開放する
void setRefer(int* rn);
ExMSGraph<T> operator= (ExMSGraph<T>& s);
ExMSGraph<T> operator= (MSGraph<T>& s);
};
//
template <typename T> void ExMSGraph<T>::set(RBound<int> rb, T v, T b, double rz, int* rn) {
set(rb.xmax-rb.xmin+1, rb.ymax-rb.ymin+1, rb.zmax-rb.zmin+1, v, b, rz, rn);
MSGraph<T>::rbound = rb;
return;
}
//
template <typename T> void ExMSGraph<T>::set(int x, int y, int z, T v, T b, double rz, int* rn)
{
if (z<=0) z = 1;
MSGraph<T>::getm(x, y, z, v);
if (MSGraph<T>::gp==NULL) return;
MSGraph<T>::base = b;
if (rz==0.0) MSGraph<T>::RZxy = 1.0;
else MSGraph<T>::RZxy = rz;
MSGraph<T>::rbound.set(0, x-1, 0, y-1, 0, z-1);
if (rn!=NULL) setRefer(rn);
else if (refno!=NULL) {
if (MSGraph<T>::gp==NULL) *refno = -1;
else *refno = 1;
}
return;
}
//
template <typename T> void ExMSGraph<T>::setRefer(int* rn)
{
refno = rn;
if (refno!=NULL) {
if (MSGraph<T>::gp==NULL) *refno = -1;
else *refno = 1;
}
}
// グラフィックデータを持いないか?
template <typename T> bool ExMSGraph<T>::isNull(void)
{
if (MSGraph<T>::gp==NULL) return true;
#ifdef WIN32
if (MSGraph<T>::gp==(T*)WIN_DD_NULL) return true;
#endif
if (refno!=NULL) {
if (*refno<0) return true;
else return false;
}
return false;
}
/**
template <typename T> void ExMSGraph<T>::free(void)
グラフィックデータを開放する
メモリ管理をしている場合は,参照数を減らす.
メモリ管理をしていない場合は,強制的に開放する.
*/
template <typename T> void ExMSGraph<T>::free(void)
{
if (refno==NULL) {
if (!isNull()) {
::free(MSGraph<T>::gp);
MSGraph<T>::init(); // gp = NULL;
}
}
else {
mfree();
}
return;
}
/**
template <typename T> void ExMSGraph<T>::mfree(bool azero)
グラフィックデータを開放する
メモリ管理をしている場合は,参照数を減らす.
メモリ管理をしていない場合は,何もしない.
@param azero @b true: 参照数 0 の状態を許す.
*/
template <typename T> void ExMSGraph<T>::mfree(bool azero)
{
if (refno!=NULL) {
(*refno)--;
if (!azero && *refno==0) {
::free(MSGraph<T>::gp);
*refno = -1;
MSGraph<T>::init(); // gp = NULL;
}
else if (*refno==-1) {
DEBUG_MODE PRINT_MESG("ExMSGraph<T>::mfree: [警告] 通常ありえない参照数 0\n");
}
else if (*refno<-1) {
*refno = -1;
}
}
return;
}
/**
template <typename T> void ExMSGraph<T>::ffree()
グラフィックデータを強制的に開放する
*/
template <typename T> void ExMSGraph<T>::ffree()
{
if (refno==NULL) {
if (!isNull()) {
::free(MSGraph<T>::gp);
}
}
else {
if (*refno>=0) {
::free(MSGraph<T>::gp);
*refno = -1;
}
}
MSGraph<T>::init(); // gp = NULL;
return;
}
// オペレータ
//
template <typename T> ExMSGraph<T> ExMSGraph<T>::operator= (ExMSGraph<T>& s)
{
ExMSGraph<T> dm = *this;
MSGraph<T>::xs = s.xs;
MSGraph<T>::ys = s.ys;
MSGraph<T>::zs = s.zs;
MSGraph<T>::gp = s.gp;
MSGraph<T>::zero = s.zero;
MSGraph<T>::base = s.base;
MSGraph<T>::max = s.max;
MSGraph<T>::min = s.min;
MSGraph<T>::color = s.color;
MSGraph<T>::state = s.state;
MSGraph<T>::rbound = s.rbound;
MSGraph<T>::RZxy = s.RZxy;
MSGraph<T>::norm = s.norm;
MSGraph<T>::wRateX = s.wRateX;
MSGraph<T>::wRateY = s.wRateY;
MSGraph<T>::wRateZ = s.wRateZ;
MSGraph<T>::wZeroX = s.wZeroX;
MSGraph<T>::wZeroY = s.wZeroY;
MSGraph<T>::wZeroZ = s.wZeroZ;
MSGraph<T>::wNowX = s.wNowX;
MSGraph<T>::wNowY = s.wNowY;
MSGraph<T>::wNowZ = s.wNowZ;
if (!s.isNull()) { // コピー元はデータを持っている.
if (s.refno!=NULL) { // コピー元は参照数変数を持っている.
if (*s.refno>=0) { // 相手の参照数変数を使う.
refno = s.refno;
(*refno)++;
}
else {
DEBUG_MODE PRINT_MESG("ExMSGraph<T>::= (ExMSGraph): コピー元参照数変数の不正!!\n");
}
}
else { // コピー元は参照数変数を持っていない.
if (refno!=NULL) { // 自分の参照数変数を持っている.
if (*refno<=-1) *refno = 1; // 自分の参照数変数が未使用ならそれを使う.
else refno = NULL; // 参照数変数は誰かが使っているので,自分は参照数変数無しになる.
}
}
}
else { // コピー元はデータを持っていない
MSGraph<T>::gp = NULL;
if (s.refno!=NULL) { // コピー元は参照数変数を持っている.
refno = s.refno; // 相手の参照数変数を使う.
*refno = -1; // データは無いので -1 に.
}
else { // コピー元は参照数変数を持っていない.
if (refno!=NULL) { // 自分の参照数変数を持っている.
if (*refno<=-1) *refno = -1; // 自分の参照数変数が未使用ならそれを使う.
else refno = NULL; // 参照数変数は誰かが使っているので,自分は参照数変数無しになる.
}
}
}
if (!dm.isNull()) dm.mfree();
return *this;
}
// オペレータ
//
template <typename T> ExMSGraph<T> ExMSGraph<T>::operator= (MSGraph<T>& s)
{
if (!isNull()) mfree();
MSGraph<T>::xs = s.xs;
MSGraph<T>::ys = s.ys;
MSGraph<T>::zs = s.zs;
MSGraph<T>::gp = s.gp;
MSGraph<T>::zero = s.zero;
MSGraph<T>::base = s.base;
MSGraph<T>::max = s.max;
MSGraph<T>::min = s.min;
MSGraph<T>::color = s.color;
MSGraph<T>::state = s.state;
MSGraph<T>::rbound = s.rbound;
MSGraph<T>::RZxy = s.RZxy;
MSGraph<T>::norm = s.norm;
MSGraph<T>::wRateX = s.wRateX;
MSGraph<T>::wRateY = s.wRateY;
MSGraph<T>::wRateZ = s.wRateZ;
MSGraph<T>::wZeroX = s.wZeroX;
MSGraph<T>::wZeroY = s.wZeroY;
MSGraph<T>::wZeroZ = s.wZeroZ;
MSGraph<T>::wNowX = s.wNowX;
MSGraph<T>::wNowY = s.wNowY;
if (!s.isNull()) { // コピー元はデータを持っている.
if (refno!=NULL) { // 自分の参照数変数を持っている.
if (*refno<=-1) *refno = 1; // 自分の参照数変数が未使用ならそれを使う.
else refno = NULL; // 参照数変数は誰かが使っているので,自分は参照数変数無しになる.
}
}
else { // コピー元はデータを持っていない
MSGraph<T>::gp = NULL;
if (refno!=NULL) { // 自分の参照数変数を持っている.
if (*refno<=-1) *refno = -1; // 自分の参照数変数が未使用ならそれを使う.
else refno = NULL; // 参照数変数は誰かが使っているので,自分は参照数変数無しになる.
}
}
return *this;
}
///////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// メモリ管理付 CmnHead
//
/**
class ExCmnHead : public CmnHead
必ず参照数変数(refnoの実体)を指定すること.無くても動くかも知れないが,保証は無い.
関数の中からディストラクトされるメモリ(のコピー)をリターンする場合は,returnの前に
mfree()を実行させること.
*/
class ExCmnHead : public CmnHead
{
public:
int state;
int dbyte;
//protected:
int* refno;
public:
ExCmnHead(int x, int y=1, int z=1, int d=8, int* rn=NULL) { set(x, y, z, d, rn);}
ExCmnHead(RBound<int> rb, int d=8, int* rn=NULL) { set(rb, d, rn);}
ExCmnHead(int* rn=NULL) { init(); setRefer(rn);}
ExCmnHead(ExCmnHead& cmhd) = default;
virtual ~ExCmnHead(void) {}
void init(void);
void set (RBound<int> rb, int d=8, int* rn=NULL);
void set (int x, int y=1, int z=1, int d=8, int* rn=NULL);
void getm(int x, int y=1, int z=1, int d=8); ///< グラフィックメモリを獲得する.
void clear() {memset(grptr, 0, lsize);}
uByte& point(int x, int y=0, int z=0) { return grptr[dbyte*(x+xsize*y+xsize*ysize*z)];} ///< 座標(x,y,z)の画素値の参照
bool isNull(void); ///< グラフィックデータを持いないか?
void free(void); ///< グラフィックデータを開放する(メモリ管理なし兼用)
void mfree(bool azero=false); ///< グラフィックデータを開放する
void ffree(void); ///< グラフィックデータを強制開放する
void setRefer(int* rn);
// void decRefer() { (*refno)--;} ///< 次のステップで強制的に +1される場合,予め実行する.
ExCmnHead operator= (ExCmnHead& m);
ExCmnHead operator= (CmnHead& m);
};
} // namespace
#endif //__JBXL_CPP_EXTEND_GRAPHIC_DATA_H_