Project

General

Profile

Download (8.14 KB) Statistics
| Branch: | Revision:

library / src / main / java / org / distorted / library / main / InternalChildrenList.java @ 1dec66e0

1 11845a9e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
2 2e569ff6 Leszek Koltunski
// Copyright 2019 Leszek Koltunski  leszek@koltunski.pl                                          //
3 11845a9e Leszek Koltunski
//                                                                                               //
4 46b572b5 Leszek Koltunski
// This file is part of Distorted.                                                               //
5 11845a9e Leszek Koltunski
//                                                                                               //
6 2e569ff6 Leszek Koltunski
// This library is free software; you can redistribute it and/or                                 //
7
// modify it under the terms of the GNU Lesser General Public                                    //
8
// License as published by the Free Software Foundation; either                                  //
9
// version 2.1 of the License, or (at your option) any later version.                            //
10 11845a9e Leszek Koltunski
//                                                                                               //
11 2e569ff6 Leszek Koltunski
// This library is distributed in the hope that it will be useful,                               //
12 11845a9e Leszek Koltunski
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13 2e569ff6 Leszek Koltunski
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU                             //
14
// Lesser General Public License for more details.                                               //
15 11845a9e Leszek Koltunski
//                                                                                               //
16 2e569ff6 Leszek Koltunski
// You should have received a copy of the GNU Lesser General Public                              //
17
// License along with this library; if not, write to the Free Software                           //
18
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA                //
19 11845a9e Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
20
21
22
package org.distorted.library.main;
23
24
import org.distorted.library.mesh.MeshBase;
25
26
import java.util.ArrayList;
27
28
///////////////////////////////////////////////////////////////////////////////////////////////////
29
30 7602a827 Leszek Koltunski
class InternalChildrenList implements InternalMaster.Slave
31 11845a9e Leszek Koltunski
  {
32
  private static final int ATTACH = 0;
33
  private static final int DETACH = 1;
34
  private static final int DETALL = 2;
35
  private static final int SORT   = 3;
36
37 22d3c4b4 Leszek Koltunski
  private static class Job
38 11845a9e Leszek Koltunski
    {
39
    int type;
40
    DistortedNode node;
41
42
    Job(int t, DistortedNode n)
43
      {
44
      type = t;
45
      node = n;
46
      }
47
    }
48
49 3272cfb8 Leszek Koltunski
  private final ArrayList<Job> mJobs;
50
  private final InternalChildrenList.Parent mParent;
51 11845a9e Leszek Koltunski
  private ArrayList<DistortedNode> mChildren;
52
  private int mNumChildren;
53
54
  public interface Parent
55
    {
56
    void adjustIsomorphism();
57
    }
58
59
///////////////////////////////////////////////////////////////////////////////////////////////////
60
61 7602a827 Leszek Koltunski
  InternalChildrenList(InternalChildrenList.Parent parent)
62 11845a9e Leszek Koltunski
    {
63
    mParent = parent;
64
    mJobs = new ArrayList<>();
65
    mChildren = null;
66
    mNumChildren = 0;
67
    }
68
69
///////////////////////////////////////////////////////////////////////////////////////////////////
70
71
  int getNumChildren()
72
    {
73
    return mNumChildren;
74
    }
75
76
///////////////////////////////////////////////////////////////////////////////////////////////////
77
78
  DistortedNode getChild(int index)
79
    {
80
    return mChildren.get(index);
81
    }
82
83
///////////////////////////////////////////////////////////////////////////////////////////////////
84
85 d5b709df Leszek Koltunski
  void rearrangeByBuckets(int index,long bucket)
86 11845a9e Leszek Koltunski
    {
87 d5b709df Leszek Koltunski
    DistortedNode child = mChildren.remove(index);
88
    int i;
89
90
    for(i=0; i<index; i++)
91 11845a9e Leszek Koltunski
      {
92 d5b709df Leszek Koltunski
      if( mChildren.get(i).getBucket() > bucket ) break;
93 11845a9e Leszek Koltunski
      }
94 d5b709df Leszek Koltunski
95
    mChildren.add(i,child);
96 11845a9e Leszek Koltunski
    }
97
98
///////////////////////////////////////////////////////////////////////////////////////////////////
99
// Can make this logarithmic but the typical number of children is very small anyway.
100
//
101
// We want to keep same buckets next to each other, while avoiding changes in order of the children
102 178983f4 Leszek Koltunski
// (if possible!)
103
// 2022/10/25: removed keeping bucket 0 (i.e. non-postprocessed children) always in the front -
104
// we don't need it (given the fixes to renderChildren() )
105 11845a9e Leszek Koltunski
106 d5b709df Leszek Koltunski
  private void addSortingByBuckets(DistortedNode newChild)
107 11845a9e Leszek Koltunski
    {
108
    int i;
109 d5b709df Leszek Koltunski
    long bucket = newChild.getBucket();
110 178983f4 Leszek Koltunski
    boolean thisSame,lastSame = false;
111 11845a9e Leszek Koltunski
112
    for(i=0; i<mNumChildren; i++)
113
      {
114 178983f4 Leszek Koltunski
      thisSame= (mChildren.get(i).getBucket()==bucket);
115
      if( lastSame && !thisSame ) break;
116
      lastSame = thisSame;
117 11845a9e Leszek Koltunski
      }
118
119
    mChildren.add(i,newChild);
120
    mNumChildren++;
121
    }
122
123
///////////////////////////////////////////////////////////////////////////////////////////////////
124
125
  void attach(DistortedNode node)
126
    {
127 3272cfb8 Leszek Koltunski
    node.resetLastTime();
128 11845a9e Leszek Koltunski
    mJobs.add(new Job(ATTACH,node));
129 7602a827 Leszek Koltunski
    InternalMaster.newSlave(this);
130 11845a9e Leszek Koltunski
    }
131
132
///////////////////////////////////////////////////////////////////////////////////////////////////
133
134 7602a827 Leszek Koltunski
  DistortedNode attach(InternalSurface surface, DistortedEffects effects, MeshBase mesh)
135 11845a9e Leszek Koltunski
    {
136
    DistortedNode node = new DistortedNode(surface,effects,mesh);
137
    mJobs.add(new Job(ATTACH,node));
138 7602a827 Leszek Koltunski
    InternalMaster.newSlave(this);
139 11845a9e Leszek Koltunski
    return node;
140
    }
141
142
///////////////////////////////////////////////////////////////////////////////////////////////////
143
144
  void detach(DistortedNode node)
145
    {
146
    mJobs.add(new Job(DETACH,node));
147 7602a827 Leszek Koltunski
    InternalMaster.newSlave(this);
148 11845a9e Leszek Koltunski
    }
149
150
///////////////////////////////////////////////////////////////////////////////////////////////////
151
152
  void detach(DistortedEffects effects)
153
    {
154
    long id = effects.getID();
155
    DistortedNode node;
156
    boolean detached = false;
157
158
    for(int i=0; i<mNumChildren; i++)
159
      {
160
      node = mChildren.get(i);
161
162
      if( node.getEffects().getID()==id )
163
        {
164
        detached = true;
165
        mJobs.add(new Job(DETACH,node));
166 7602a827 Leszek Koltunski
        InternalMaster.newSlave(this);
167 11845a9e Leszek Koltunski
        break;
168
        }
169
      }
170
171
    if( !detached )
172
      {
173
      // if we failed to detach any, it still might be the case that
174
      // there's an ATTACH job that we need to cancel.
175
      int num = mJobs.size();
176
      Job job;
177
178
      for(int i=0; i<num; i++)
179
        {
180
        job = mJobs.get(i);
181
182
        if( job.type==ATTACH && job.node.getEffects()==effects )
183
          {
184
          mJobs.remove(i);
185
          break;
186
          }
187
        }
188
      }
189
    }
190
191
///////////////////////////////////////////////////////////////////////////////////////////////////
192
193
  void detachAll()
194
    {
195
    mJobs.add(new Job(DETALL,null));
196 7602a827 Leszek Koltunski
    InternalMaster.newSlave(this);
197 11845a9e Leszek Koltunski
    }
198
199
///////////////////////////////////////////////////////////////////////////////////////////////////
200
/**
201
 * This is not really part of the public API. Has to be public only because it is a part of the
202
 * DistortedSlave interface, which should really be a class that we extend here instead but
203
 * Java has no multiple inheritance.
204
 *
205
 * @y.exclude
206
 */
207
  public void doWork()
208
    {
209
    int num = mJobs.size();
210
211
    if( num>0 )
212
      {
213
      Job job;
214
      int numChanges=0;
215
216
      for(int i=0; i<num; i++)
217
        {
218
        job = mJobs.remove(0);
219
220
        switch(job.type)
221
          {
222
          case ATTACH: numChanges++;
223
                       if( mChildren==null ) mChildren = new ArrayList<>(2);
224
                       job.node.setParent(mParent);
225
                       addSortingByBuckets(job.node);
226
                       break;
227
          case DETACH: numChanges++;
228
                       if( mNumChildren>0 && mChildren.remove(job.node) )
229
                         {
230
                         job.node.setParent(null);
231
                         mNumChildren--;
232
                         }
233
                       break;
234
          case DETALL: numChanges++;
235
                       if( mNumChildren>0 )
236
                         {
237
                         DistortedNode tmp;
238
239
                         for(int j=mNumChildren-1; j>=0; j--)
240
                           {
241
                           tmp = mChildren.remove(j);
242
                           tmp.setParent(null);
243
                           }
244
245
                         mNumChildren = 0;
246
                         }
247
                       break;
248
          case SORT  : mChildren.remove(job.node);
249
                       addSortingByBuckets(job.node);
250
                       break;
251
          }
252
        }
253
      if( numChanges>0 ) mParent.adjustIsomorphism();
254
      }
255
    }
256
  }