Project

General

Profile

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

library / src / main / java / org / distorted / library / main / InternalChildrenList.java @ 3272cfb8

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2019 Leszek Koltunski                                                               //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// Distorted is free software: you can redistribute it and/or modify                             //
7
// 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
// Distorted 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                                 //
14
// GNU General Public License for more details.                                                  //
15
//                                                                                               //
16
// You should have received a copy of the GNU General Public License                             //
17
// along with Distorted.  If not, see <http://www.gnu.org/licenses/>.                            //
18
///////////////////////////////////////////////////////////////////////////////////////////////////
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
class InternalChildrenList implements InternalMaster.Slave
30
  {
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
  private static class Job
37
    {
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 final ArrayList<Job> mJobs;
49
  private final InternalChildrenList.Parent mParent;
50
  private ArrayList<DistortedNode> mChildren;
51
  private int mNumChildren;
52

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

    
58
///////////////////////////////////////////////////////////////////////////////////////////////////
59

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

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

    
94
    mChildren.add(i,child);
95
    }
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
  private void addSortingByBuckets(DistortedNode newChild)
104
    {
105
    int i;
106
    long bucket = newChild.getBucket();
107
    boolean sameBucket = false;
108

    
109
    for(i=0; i<mNumChildren; i++)
110
      {
111
      if( mChildren.get(i).getBucket() == bucket )
112
        {
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
    node.resetLastTime();
130
    mJobs.add(new Job(ATTACH,node));
131
    InternalMaster.newSlave(this);
132
    }
133

    
134
///////////////////////////////////////////////////////////////////////////////////////////////////
135

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

    
144
///////////////////////////////////////////////////////////////////////////////////////////////////
145

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

    
152
///////////////////////////////////////////////////////////////////////////////////////////////////
153

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

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

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

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

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

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

    
193
///////////////////////////////////////////////////////////////////////////////////////////////////
194

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

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

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

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

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

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

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

    
(8-8/16)