Project

General

Profile

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

library / src / main / java / org / distorted / library / main / DistortedChildrenList.java @ e37d470b

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 DistortedChildrenList implements DistortedMaster.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 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 ArrayList<Job> mJobs;
49
  private ArrayList<DistortedNode> mChildren;
50
  private DistortedChildrenList.Parent mParent;
51
  private int mNumChildren;
52

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

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

    
61
  DistortedChildrenList(DistortedChildrenList.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 removeChild(DistortedNode node)
86
    {
87
    if( mChildren.remove(node) )
88
      {
89
      mNumChildren--;
90
      }
91
    }
92

    
93
///////////////////////////////////////////////////////////////////////////////////////////////////
94
// Can make this logarithmic but the typical number of children is very small anyway.
95
//
96
// We want to keep same buckets next to each other, while avoiding changes in order of the children
97
// (if possible!) We want to keep bucket=0 (i.e. the non-postprocessed children) at the beginning.
98

    
99
  void addSortingByBuckets(DistortedNode newChild)
100
    {
101
    int i;
102
    long bucket = newChild.getEffects().getPostprocess().getID();
103
    boolean sameBucket = false;
104

    
105
    for(i=0; i<mNumChildren; i++)
106
      {
107
      if( mChildren.get(i).getEffects().getPostprocess().getID() == bucket )
108
        {
109
        sameBucket=true;
110
        }
111
      else if( sameBucket || bucket==0 )
112
        {
113
        break;
114
        }
115
      }
116

    
117
    mChildren.add(i,newChild);
118
    mNumChildren++;
119
    }
120

    
121
///////////////////////////////////////////////////////////////////////////////////////////////////
122

    
123
  void attach(DistortedNode node)
124
    {
125
    mJobs.add(new Job(ATTACH,node));
126
    DistortedMaster.newSlave(this);
127
    }
128

    
129
///////////////////////////////////////////////////////////////////////////////////////////////////
130

    
131
  DistortedNode attach(DistortedSurface surface, DistortedEffects effects, MeshBase mesh)
132
    {
133
    DistortedNode node = new DistortedNode(surface,effects,mesh);
134
    mJobs.add(new Job(ATTACH,node));
135
    DistortedMaster.newSlave(this);
136
    return node;
137
    }
138

    
139
///////////////////////////////////////////////////////////////////////////////////////////////////
140

    
141
  void detach(DistortedNode node)
142
    {
143
    mJobs.add(new Job(DETACH,node));
144
    DistortedMaster.newSlave(this);
145
    }
146

    
147
///////////////////////////////////////////////////////////////////////////////////////////////////
148

    
149
  void detach(DistortedEffects effects)
150
    {
151
    long id = effects.getID();
152
    DistortedNode node;
153
    boolean detached = false;
154

    
155
    for(int i=0; i<mNumChildren; i++)
156
      {
157
      node = mChildren.get(i);
158

    
159
      if( node.getEffects().getID()==id )
160
        {
161
        detached = true;
162
        mJobs.add(new Job(DETACH,node));
163
        DistortedMaster.newSlave(this);
164
        break;
165
        }
166
      }
167

    
168
    if( !detached )
169
      {
170
      // if we failed to detach any, it still might be the case that
171
      // there's an ATTACH job that we need to cancel.
172
      int num = mJobs.size();
173
      Job job;
174

    
175
      for(int i=0; i<num; i++)
176
        {
177
        job = mJobs.get(i);
178

    
179
        if( job.type==ATTACH && job.node.getEffects()==effects )
180
          {
181
          mJobs.remove(i);
182
          break;
183
          }
184
        }
185
      }
186
    }
187

    
188
///////////////////////////////////////////////////////////////////////////////////////////////////
189

    
190
  void detachAll()
191
    {
192
    mJobs.add(new Job(DETALL,null));
193
    DistortedMaster.newSlave(this);
194
    }
195

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

    
208
    if( num>0 )
209
      {
210
      Job job;
211
      int numChanges=0;
212

    
213
      for(int i=0; i<num; i++)
214
        {
215
        job = mJobs.remove(0);
216

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

    
236
                         for(int j=mNumChildren-1; j>=0; j--)
237
                           {
238
                           tmp = mChildren.remove(j);
239
                           tmp.setParent(null);
240
                           }
241

    
242
                         mNumChildren = 0;
243
                         }
244
                       break;
245
          case SORT  : mChildren.remove(job.node);
246
                       addSortingByBuckets(job.node);
247
                       break;
248
          }
249
        }
250
      if( numChanges>0 ) mParent.adjustIsomorphism();
251
      }
252
    }
253
  }
254

    
(3-3/19)