Project

General

Profile

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

library / src / main / java / org / distorted / library / main / InternalChildrenList.java @ eff6e3d3

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