Project

General

Profile

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

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

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski  leszek@koltunski.pl                                          //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// 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
//                                                                                               //
11
// This library is distributed in the hope that it will be useful,                               //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU                             //
14
// Lesser General Public License for more details.                                               //
15
//                                                                                               //
16
// 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
///////////////////////////////////////////////////////////////////////////////////////////////////
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
class InternalChildrenList implements InternalMaster.Slave
31
  {
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
  private static class Job
38
    {
39
    int type;
40
    DistortedNode node;
41

    
42
    Job(int t, DistortedNode n)
43
      {
44
      type = t;
45
      node = n;
46
      }
47
    }
48

    
49
  private final ArrayList<Job> mJobs;
50
  private final InternalChildrenList.Parent mParent;
51
  private ArrayList<DistortedNode> mChildren;
52
  private int mNumChildren;
53

    
54
  public interface Parent
55
    {
56
    void adjustIsomorphism();
57
    }
58

    
59
///////////////////////////////////////////////////////////////////////////////////////////////////
60

    
61
  InternalChildrenList(InternalChildrenList.Parent parent)
62
    {
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
  void rearrangeByBuckets(int index,long bucket)
86
    {
87
    DistortedNode child = mChildren.remove(index);
88
    int i;
89

    
90
    for(i=0; i<index; i++)
91
      {
92
      if( mChildren.get(i).getBucket() > bucket ) break;
93
      }
94

    
95
    mChildren.add(i,child);
96
    }
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
// (if possible!) We want to keep bucket=0 (i.e. the non-postprocessed children) at the beginning.
103

    
104
  private void addSortingByBuckets(DistortedNode newChild)
105
    {
106
    int i;
107
    long bucket = newChild.getBucket();
108
    boolean sameBucket = false;
109

    
110
    for(i=0; i<mNumChildren; i++)
111
      {
112
      if( mChildren.get(i).getBucket() == bucket )
113
        {
114
        sameBucket=true;
115
        }
116
      else if( sameBucket || bucket==0 )
117
        {
118
        break;
119
        }
120
      }
121

    
122
    mChildren.add(i,newChild);
123
    mNumChildren++;
124
    }
125

    
126
///////////////////////////////////////////////////////////////////////////////////////////////////
127

    
128
  void attach(DistortedNode node)
129
    {
130
    node.resetLastTime();
131
    mJobs.add(new Job(ATTACH,node));
132
    InternalMaster.newSlave(this);
133
    }
134

    
135
///////////////////////////////////////////////////////////////////////////////////////////////////
136

    
137
  DistortedNode attach(InternalSurface surface, DistortedEffects effects, MeshBase mesh)
138
    {
139
    DistortedNode node = new DistortedNode(surface,effects,mesh);
140
    mJobs.add(new Job(ATTACH,node));
141
    InternalMaster.newSlave(this);
142
    return node;
143
    }
144

    
145
///////////////////////////////////////////////////////////////////////////////////////////////////
146

    
147
  void detach(DistortedNode node)
148
    {
149
    mJobs.add(new Job(DETACH,node));
150
    InternalMaster.newSlave(this);
151
    }
152

    
153
///////////////////////////////////////////////////////////////////////////////////////////////////
154

    
155
  void detach(DistortedEffects effects)
156
    {
157
    long id = effects.getID();
158
    DistortedNode node;
159
    boolean detached = false;
160

    
161
    for(int i=0; i<mNumChildren; i++)
162
      {
163
      node = mChildren.get(i);
164

    
165
      if( node.getEffects().getID()==id )
166
        {
167
        detached = true;
168
        mJobs.add(new Job(DETACH,node));
169
        InternalMaster.newSlave(this);
170
        break;
171
        }
172
      }
173

    
174
    if( !detached )
175
      {
176
      // if we failed to detach any, it still might be the case that
177
      // there's an ATTACH job that we need to cancel.
178
      int num = mJobs.size();
179
      Job job;
180

    
181
      for(int i=0; i<num; i++)
182
        {
183
        job = mJobs.get(i);
184

    
185
        if( job.type==ATTACH && job.node.getEffects()==effects )
186
          {
187
          mJobs.remove(i);
188
          break;
189
          }
190
        }
191
      }
192
    }
193

    
194
///////////////////////////////////////////////////////////////////////////////////////////////////
195

    
196
  void detachAll()
197
    {
198
    mJobs.add(new Job(DETALL,null));
199
    InternalMaster.newSlave(this);
200
    }
201

    
202
///////////////////////////////////////////////////////////////////////////////////////////////////
203
/**
204
 * This is not really part of the public API. Has to be public only because it is a part of the
205
 * DistortedSlave interface, which should really be a class that we extend here instead but
206
 * Java has no multiple inheritance.
207
 *
208
 * @y.exclude
209
 */
210
  public void doWork()
211
    {
212
    int num = mJobs.size();
213

    
214
    if( num>0 )
215
      {
216
      Job job;
217
      int numChanges=0;
218

    
219
      for(int i=0; i<num; i++)
220
        {
221
        job = mJobs.remove(0);
222

    
223
        switch(job.type)
224
          {
225
          case ATTACH: numChanges++;
226
                       if( mChildren==null ) mChildren = new ArrayList<>(2);
227
                       job.node.setParent(mParent);
228
                       addSortingByBuckets(job.node);
229
                       break;
230
          case DETACH: numChanges++;
231
                       if( mNumChildren>0 && mChildren.remove(job.node) )
232
                         {
233
                         job.node.setParent(null);
234
                         mNumChildren--;
235
                         }
236
                       break;
237
          case DETALL: numChanges++;
238
                       if( mNumChildren>0 )
239
                         {
240
                         DistortedNode tmp;
241

    
242
                         for(int j=mNumChildren-1; j>=0; j--)
243
                           {
244
                           tmp = mChildren.remove(j);
245
                           tmp.setParent(null);
246
                           }
247

    
248
                         mNumChildren = 0;
249
                         }
250
                       break;
251
          case SORT  : mChildren.remove(job.node);
252
                       addSortingByBuckets(job.node);
253
                       break;
254
          }
255
        }
256
      if( numChanges>0 ) mParent.adjustIsomorphism();
257
      }
258
    }
259
  }
260

    
(8-8/17)