Project

General

Profile

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

library / src / main / java / org / distorted / library / main / InternalObject.java @ b7074bc6

1 226144d0 leszek
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2016 Leszek Koltunski                                                               //
3
//                                                                                               //
4 46b572b5 Leszek Koltunski
// This file is part of Distorted.                                                               //
5 226144d0 leszek
//                                                                                               //
6 46b572b5 Leszek Koltunski
// Distorted is free software: you can redistribute it and/or modify                             //
7 226144d0 leszek
// 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 226144d0 leszek
// 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 226144d0 leszek
///////////////////////////////////////////////////////////////////////////////////////////////////
19
20 fe82a979 Leszek Koltunski
package org.distorted.library.main;
21 226144d0 leszek
22
import java.util.HashMap;
23
import java.util.LinkedList;
24
25
///////////////////////////////////////////////////////////////////////////////////////////////////
26
/**
27
 * Any Object which gets uploaded to GPU memory and thus needs to be re-created (transparently to
28
 * applications!) whenever we lose OpenGL context.
29
 *
30
 * Keep all objects created in a static LinkedList. The point: we need to be able to mark
31
 * Objects for deletion, and delete all marked Objects later at a convenient time (that's
32
 * because we can only delete from a thread that holds the OpenGL context so here we provide a
33
 * framework where one is able to mark for deletion at any time and actual deletion takes place
34
 * on the next render).
35
*/
36 7602a827 Leszek Koltunski
abstract class InternalObject
37 226144d0 leszek
{
38
  static final int FAILED_TO_CREATE = 1;
39
  static final int NOT_CREATED_YET  = 2;
40
  static final int DONT_CREATE      = 3;
41
  static final int CREATED          = 4;
42
43
  static final int TYPE_USER = 0;
44
  static final int TYPE_TREE = 1;
45
  static final int TYPE_SYST = 2;
46
47
  private static final int JOB_CREATE = 0;
48
  private static final int JOB_DELETE = 1;
49
50
  private class Job
51
    {
52 7602a827 Leszek Koltunski
    InternalObject object;
53 226144d0 leszek
    int action;
54
55 7602a827 Leszek Koltunski
    Job(InternalObject o, int a)
56 226144d0 leszek
      {
57
      object = o;
58
      action = a;
59
      }
60
    }
61
62
  private static boolean mToDo = false;
63 7602a827 Leszek Koltunski
  private static LinkedList<InternalObject> mDoneList = new LinkedList<>();
64 226144d0 leszek
  private static HashMap<Long,Job> mToDoMap = new HashMap<>();
65
  private static long mNextClientID = 0;
66
  private static long mNextSystemID = 0;
67
68 d2039fdd Leszek Koltunski
  private final static Object mDoneLock = new Object();
69
  private final static Object mToDoLock = new Object();
70
71 226144d0 leszek
  private long mID;
72 13981586 Leszek Koltunski
  private int mType;
73 226144d0 leszek
74
///////////////////////////////////////////////////////////////////////////////////////////////////
75
76
  abstract void create();
77
  abstract void delete();
78
  abstract void recreate();
79
  abstract String printDetails();
80
81
///////////////////////////////////////////////////////////////////////////////////////////////////
82
// must be called from a thread holding OpenGL Context
83
84 d2039fdd Leszek Koltunski
  static boolean toDo()
85 226144d0 leszek
    {
86
    if( mToDo )
87
      {
88
      Job job;
89 7602a827 Leszek Koltunski
      InternalObject object;
90 226144d0 leszek
91 d2039fdd Leszek Koltunski
      synchronized(mToDoLock)
92 226144d0 leszek
        {
93 d2039fdd Leszek Koltunski
        for(Long key: mToDoMap.keySet())
94 226144d0 leszek
          {
95 d2039fdd Leszek Koltunski
          job = mToDoMap.get(key);
96
          object = job.object;
97
98
          if( job.action==JOB_CREATE )
99
            {
100
            object.create();
101
            mDoneList.add(object);
102
            }
103
          else if( job.action==JOB_DELETE )
104
            {
105
            object.delete();
106
            }
107 226144d0 leszek
          }
108 d2039fdd Leszek Koltunski
109
        mToDoMap.clear();
110
        mToDo = false;
111 226144d0 leszek
        }
112
113
      return true;
114
      }
115
116
    return false;
117
    }
118
119
///////////////////////////////////////////////////////////////////////////////////////////////////
120
121 d2039fdd Leszek Koltunski
  static void onPause()
122 226144d0 leszek
    {
123 7602a827 Leszek Koltunski
    InternalObject object;
124 226144d0 leszek
125 d2039fdd Leszek Koltunski
    synchronized(mDoneLock)
126 040cd18c Leszek Koltunski
      {
127 d2039fdd Leszek Koltunski
      synchronized(mToDoLock)
128 040cd18c Leszek Koltunski
        {
129 d2039fdd Leszek Koltunski
        int num = mDoneList.size();
130
131
        try
132
          {
133
          for (int i = 0; i < num; i++)
134
            {
135
            object = mDoneList.removeFirst();
136
            mToDoMap.put(object.mID, object.new Job(object, JOB_CREATE));
137
            object.recreate();
138
            }
139
          }
140
        catch( Exception ex )
141
          {
142
          // something else removed an object in the meantime; ignore
143
          }
144 040cd18c Leszek Koltunski
        }
145
      }
146 226144d0 leszek
147
    mToDo = true;
148
    }
149
150
///////////////////////////////////////////////////////////////////////////////////////////////////
151
152 d2039fdd Leszek Koltunski
  static void onDestroy()
153 226144d0 leszek
    {
154 d2039fdd Leszek Koltunski
    synchronized(mToDoLock)
155
      {
156
      synchronized(mDoneLock)
157
        {
158
        mToDoMap.clear();
159
        mDoneList.clear();
160 226144d0 leszek
161 d2039fdd Leszek Koltunski
        mToDo = true;
162
        mNextClientID = 0;
163
        }
164
      }
165 226144d0 leszek
    }
166
167
///////////////////////////////////////////////////////////////////////////////////////////////////
168
169
  @SuppressWarnings("unused")
170
  static void debugLists()
171
    {
172
    android.util.Log.e("Object", "Done list:");
173
174 7602a827 Leszek Koltunski
    for(InternalObject object : mDoneList)
175 226144d0 leszek
      {
176
      object.print("");
177
      }
178
179
    android.util.Log.e("Object", "ToDo list:");
180
181
    Job job;
182
183
    for(Long key: mToDoMap.keySet())
184
      {
185
      job = mToDoMap.get(key);
186
      job.object.print(job.action==JOB_CREATE ? " create":" delete");
187
      }
188
    }
189
190
///////////////////////////////////////////////////////////////////////////////////////////////////
191
192
  private void print(String msg)
193
    {
194
    String str = "ID:"+mID;
195
196
    switch(mType)
197
      {
198
      case TYPE_SYST: str+=" SYSTEM "; break;
199
      case TYPE_USER: str+=" USER   "; break;
200
      case TYPE_TREE: str+=" TREE   "; break;
201
      default       : str+=" ERROR? ";
202
      }
203
204
    android.util.Log.e("Object", str+printDetails()+msg);
205
    }
206
207
///////////////////////////////////////////////////////////////////////////////////////////////////
208
209 7602a827 Leszek Koltunski
  InternalObject(int type)
210 226144d0 leszek
    {
211
    mID  = type==TYPE_SYST ? --mNextSystemID : ++mNextClientID;
212
    mType= type;
213
    }
214
215 22e60fba Leszek Koltunski
///////////////////////////////////////////////////////////////////////////////////////////////////
216
217
  void markWasCreatedImmediately()
218
    {
219
    mDoneList.add(this);
220
    }
221
222 226144d0 leszek
///////////////////////////////////////////////////////////////////////////////////////////////////
223
224 d2039fdd Leszek Koltunski
  void markForCreation()
225 226144d0 leszek
    {
226 d2039fdd Leszek Koltunski
    synchronized(mDoneLock)
227
      {
228
      mDoneList.remove(this);
229
      }
230
231
    synchronized(mToDoLock)
232
      {
233
      mToDoMap.put(mID, new Job(this,JOB_CREATE) );
234
      mToDo = true;
235
      }
236 226144d0 leszek
    }
237
238
///////////////////////////////////////////////////////////////////////////////////////////////////
239
// PUBLIC API
240
///////////////////////////////////////////////////////////////////////////////////////////////////
241
/**
242
 * Mark the underlying OpenGL object for deletion. Actual deletion will take place on the next render.
243
 */
244 d2039fdd Leszek Koltunski
  public void markForDeletion()
245 226144d0 leszek
    {
246 d2039fdd Leszek Koltunski
    synchronized(mDoneLock)
247
      {
248
      mDoneList.remove(this);
249
      }
250
251
    synchronized(mToDoLock)
252
      {
253
      mToDoMap.put(mID, new Job(this,JOB_DELETE) );
254
      mToDo = true;
255
      }
256 226144d0 leszek
    }
257
258
////////////////////////////////////////////////////////////////////////////////////////////////////
259
/**
260
 * Return unique ID of this Object.
261
 */
262
  public long getID()
263
    {
264
    return mID;
265
    }
266
267
}