Show Posts
|
|
Pages: [1] 2 3 ... 8
|
|
1
|
Game Development / Game Play & Game Design / Re: Game Threading
|
on: 2012-10-29 19:02:10
|
|
Disregarding the 'simple', what's the best way to profitably multithread AI on a game with multiple permanent agents on a level (assuming that the agents all run physics code, pathfinding, conversations, animations all the time the player sees them, and if he does not, they still need to run pathfinding, and at least part of the physics code (to not fall down the floor, or kill themselves with momentum for instance).
|
|
|
|
|
2
|
Discussions / General Discussions / Re: Scripting languages / DSLs?
|
on: 2012-09-14 21:59:48
|
|
I want one where i can do autocomplete one the netbeans framework and setup some 'special' global objects filled in from the larger program. Guess Janino would work except for the lack of generics (one of the 'special' objects would be a map).
Currently thinking of groovy too. The idea of the program is not some general thing, just some 'unit of code' that are executed unconditionally if the selected thing is selected, so having the declare classes and stuff like that would only be harmful.
|
|
|
|
|
4
|
Discussions / Miscellaneous Topics / Re: Things you disagree with in the java language
|
on: 2012-09-09 07:15:02
|
Am I the only one that never had NPE problems? If I ever got an NPE, even in my older n00bish days, I would go to the line number, use reasonable deduction to find out what exactly was null and where, and easily figure out my mistake. Was I special or are newbies conditioned to be dumber these days......?
It's because it's a runtime error not a compile time error like it could be if non-null was the default.
|
|
|
|
|
5
|
Discussions / Miscellaneous Topics / Re: Things you disagree with in the java language
|
on: 2012-09-07 09:42:13
|
|
I'm saying that arrays not being the good choice for the type of varargs was utterly predictable in the face of generics and the well known limitations that the type erasure workaround brought to the table - especially if you needed to transform the array. This is where lazyness (not infinite sequences) is a advantage by not requiring allocation of a new array to iterate over a 'new' sequence. By specifying the runtime type of ... as a array they mandated that any transformation that is used as input to ... needs to return [].
That you're telling that i should be 'using Haskell' doesn't make it any less the wrong choice. Common idiom? Surely less than collections, which are all iterable. Make arrays iterable too by VM wizardry for all i care.
Meanwhile, every 'framework' api in java 7 and 8 is deprecating all the array methods they can get away with in favor of generic collections (swing for instance). Terrible planning, left hand doesn't know the right stuff.
|
|
|
|
|
6
|
Discussions / Miscellaneous Topics / Re: Things you disagree with in the java language
|
on: 2012-09-07 09:22:06
|
@OP I really see no problem with var args, they are convenient in some select situations.
I never said that there is a problem with the idea, just the implementation. Using the efficiency of arrays for a 1-100 arguments magnitude is just loony. That a array introduces problems with generics, is not lazy (and this and the previous express the erasure problem and requires copies) and can be altered inside the method (uselessly by the way, since the type is constructed a runtime in both cases, and probably harmful for code clarity if you use it as a tmp) is just the cherry of crazy on top. Not to mention that collections are infinitely more flexible when ordering matters. The only 'advantage' i can see is that a array is very amenable to get into cpu cache, but a varargs iterable built over a array probably would too, not to mention that the varargs arguments by necessity tend to be a small amount (or a actual array). Also i wish java had made the Collections library have full immutable type interfaces (not super of mutable ones), so that libraries don't need no steenking copies. Rust has some ideas here (the freeze concept applied to the type system is probably a better idea than a simple type because you can thaw, add stuff and freeze as a 'protocol type' without any copies on both sides of the client-api border. Not sure how it deals with concurrency).
|
|
|
|
|
7
|
Discussions / Miscellaneous Topics / Re: Things you disagree with in the java language
|
on: 2012-09-06 02:01:16
|
|
Thought of another. If doing the language now, i think that the new type inference in generics should be the default. new ArrayList<>() would be new ArrayList(), and if you want a subclass from the left-value declare the type argument. <> goes away.
Probably wouldn't be accepted because it's not explicit.
|
|
|
|
|
8
|
Discussions / Miscellaneous Topics / Re: Things you disagree with in the java language
|
on: 2012-08-30 23:34:56
|
And then i had the problem that as varargs uses arrays it needs to have the non-generic class type (arrays being covariant and all). You can use generics: 1 2 3 4 5
| public static <T extends Component> void foo(T ... args) { for (T comp : args) { comp.invalidate() } } |
Try doing that with a method that takes a collection/array of generic type and returns a array of another generic type (ommit the factory function for the purpose of example). This to be used in a function that takes varargs arrays as a conversion step. for a iterable argument... 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public static <E, T> Iterable<E> iterable(final Iterable<T> it, final Factory<E, T> factory) { return new Iterable<E>() { @Override public Iterator<E> iterator() { final Iterator<T> itr = it.iterator(); return new Iterator<E>() { @Override public boolean hasNext() { return itr.hasNext(); }
@Override public E next() { try { return factory.create(itr.next()); } catch (Exception ex) { throw new AssertionError("factory method shouldn't throw a exception when used in iterator", ex); } }
@Override public void remove() { itr.remove(); } }; } }; } |
for a varargs argument... 1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public static <E, T> E[] map(final Collection<T> it, Class<E> classE, final Factory<E, T> factory) { E[] out = (E[]) Array.newInstance(classE, it.size()); int i = 0; for (T o : it) { try { out[i++] = factory.create(o); } catch (Exception ex) { throw new AssertionError(ex); } }
return out; } |
See the additional class argument, narrowed collection interface, allocation, reflection and copy there? All because [] is not able to be lazy. Varargs blow. There is nothing that they do currently that couldn't have been done better by making their runtime type be a iterable instead of a array except modification of the runtime array argument which i never do and it's filthy coding anyway (that remove() is bad too, assuming that it's only to be used for argument transformation). It's no accident that the most used varargs method in the jdk is something that turns it into a iterable i guess ('immutable list') - especially with lambdas around the corner i'd advice to cut off varargs from your api's.
|
|
|
|
|
9
|
Discussions / Miscellaneous Topics / Things you disagree with in the java language
|
on: 2012-08-30 22:58:23
|
|
I was just thinking of this, because of a design decision i find to be absolutely wrongheaded;
I tried to use varargs, because i really really want to make my functions take one or many without having to deal with converting to a list on the case of 'one', and besides i often have to convert.
So i tried varargs. Then i had the problem of 'conversion' or 'mapping' (functional lingo). And then i had the problem that as varargs uses arrays it needs to have the non-generic class type (arrays being covariant and all).
What i'd really like is that varargs created a iterable that could then be easily wrapped in another iterable that could do the mapping (with lambdas or whatever). However due to the fact that arrays are covariant and not lazy i need to pass a collection (for the size()), a class (to instantiate the array) and the factory 'lambda') and waste time and space copying. I've reached the conclusion that varargs do more harm than good in cases where you need to transform one-or-many into the function arguments expected, and that it's better to do 'asList' on the function arguments that are not on collection form and pass a iterable.
Varargs was implemented targeting the wrong type and is almost completely useless!
Have you got any other pet issues?
|
|
|
|
|
10
|
Game Development / Performance Tuning / Re: Designing a Collection
|
on: 2012-08-19 01:39:14
|
Ok i gave up on the 'efficient' way of subclassing the LinkedHashMap and just put in my nodes as values 3 or 4 'unneeded' references but it's clearer if not really simple  Anyway, i'd like some opinions and if anyone can spot a bug it'd be nice edit: Anyone know of a test harness for Collections that deals with the jdk interfaces? edit2: found the MOAT and fixed a few bugs found by those tests 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383
| package i3.util;
import java.util.AbstractSet; import java.util.Collection; import java.util.ConcurrentModificationException; import java.util.HashMap; import java.util.Iterator; import java.util.ListIterator; import java.util.Map; import java.util.NoSuchElementException;
public class LinkedSet<E> extends AbstractSet<E> {
private Map<E, Node> m = new HashMap<E, Node>(); protected Node head = new Node(); private int monotonicallyIncreasing = 0; private int iteratorAddStep = 10; private int modCount;
public ListIterator<E> from(E elem) { Node e = m.get(elem); if (e == null) { throw new NoSuchElementException("the given element isn't part of the set"); } return new LinkedKeyIterator(e); }
@Override public ListIterator<E> iterator() { return new LinkedKeyIterator(); }
public boolean containsBefore(E target, E limitElem) { if (isEmpty()) { return false; }
Integer targetN = m.get(target).relativeLocation; Integer highN = m.get(limitElem).relativeLocation; return targetN != null && highN != null && targetN < highN; }
public boolean containsAfter(E target, E previousElem) { if (isEmpty()) { return false; }
Integer targetN = m.get(target).relativeLocation; Integer low = m.get(previousElem).relativeLocation; return targetN != null && low != null && low < targetN; }
@Override public boolean add(E e) { if (!m.containsKey(e)) { Node n = new Node(e, monotonicallyIncreasing); monotonicallyIncreasing += iteratorAddStep; n.addBefore(head); m.put(e, n); return true; } return false; }
@Override public int size() { return m.size(); }
@Override public boolean isEmpty() { return m.isEmpty(); }
@Override public boolean contains(Object o) { return m.containsKey(o); }
@Override public Object[] toArray() { Object[] result = new Object[size()]; int i = 0; for (E e : this) { result[i++] = e; } return result; }
@Override @SuppressWarnings("unchecked") public <T> T[] toArray(T[] a) { int size = size(); if (a.length < size) { a = (T[]) java.lang.reflect.Array.newInstance(a.getClass().getComponentType(), size); } int i = 0; Object[] result = a; for (E e : this) { result[i++] = e; } if (a.length > size) { a[size] = null; } return a; }
@Override public boolean remove(Object o) { Node n = m.remove(o); if (n != null) { n.remove(); return true; } return false; }
@Override public boolean addAll(Collection<? extends E> c) { boolean changed = false; for (E e : c) { changed |= add(e); } return changed; }
@Override public boolean containsAll(Collection<?> c) { boolean all = true; for (Object e : c) { all &= m.containsKey(e); } return all; }
@Override public boolean retainAll(Collection<?> c) { boolean changed = false; Iterator<E> it = iterator(); while (it.hasNext()) { E k = it.next(); if (!c.contains(k)) { it.remove(); changed = true; } } return changed; }
@Override public void clear() { modCount++; head.after = head.before = head; m.clear(); }
@Override public String toString() { return m.keySet().toString(); }
protected final class Node {
Node before, after; int relativeLocation; E key;
private void remove() { before.after = after; after.before = before; modCount++; }
private void addBefore(Node existingEntry) { after = existingEntry; before = existingEntry.before; before.after = this; after.before = this; modCount++; }
public Node() { after = before = this; relativeLocation = 0; }
public Node(E key, int value) { this.key = key; this.relativeLocation = value; } }
protected class LinkedKeyIterator implements ListIterator<E> {
Node nextEntry; Node lastReturned; int expectedModCount = modCount;
public LinkedKeyIterator() { nextEntry = head.after; }
public LinkedKeyIterator(Node startAt) { nextEntry = startAt; }
public boolean hasPrevious() { return nextEntry.before != head; }
public boolean hasNext() { return nextEntry != head; }
public E next() { if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } if (nextEntry == head) { throw new NoSuchElementException(); }
Node e = lastReturned = nextEntry; nextEntry = e.after; return e.key; }
public E previous() { if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } if (nextEntry.before == head) { throw new NoSuchElementException(); }
Node e = lastReturned = nextEntry.before; nextEntry = e; return e.key; }
public void remove() { if (lastReturned == null) { throw new IllegalStateException(); } if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } m.remove(lastReturned.key); nextEntry = lastReturned.after; lastReturned.remove(); lastReturned = null; expectedModCount = modCount; }
@Override public void set(E e) { if (lastReturned == null) { throw new IllegalStateException(); } if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } if (lastReturned.key.equals(e)) { return; } m.remove(lastReturned.key); lastReturned.key = e; Node previousKeyOwner = m.put(e, lastReturned); if (previousKeyOwner != null) { if(nextEntry == previousKeyOwner){ nextEntry = nextEntry.after; } previousKeyOwner.remove(); } expectedModCount = ++modCount; }
@Override public void add(E e) { if (modCount != expectedModCount) { throw new ConcurrentModificationException(); } lastReturned = null; int candidateLoc = nextEntry.before.relativeLocation + 1; if (candidateLoc == nextEntry.relativeLocation) { iteratorAddStep *= 1.6; for (Node current = nextEntry; current != head; current = current.after) { current.relativeLocation = current.relativeLocation + iteratorAddStep; } }
Node n = m.get(e); if (n == null) { n = new Node(e, candidateLoc); m.put(e, n); } else { n.relativeLocation = candidateLoc; if(nextEntry == n){ nextEntry = nextEntry.after; } n.remove(); } n.addBefore(nextEntry); expectedModCount = modCount; }
@Override public int nextIndex() { throw new UnsupportedOperationException("Not supported yet."); }
@Override public int previousIndex() { throw new UnsupportedOperationException("Not supported yet."); } } } |
|
|
|
|
|
11
|
Game Development / Performance Tuning / Re: Designing a Collection
|
on: 2012-08-18 21:30:27
|
|
Can i copy and modify oracle classes into my project if it is LGPL?
Interesting ListIterator.set() and ListIterator.add() may change the iteration order of the thing
Since the set Elements are stored in the keys of a Map, ListIterator.set(K) involves removing the last entry key, adding a new one with K and the old V and inserting that new Entry in the place of the last returned one on the ListIterator.
'adding a new one with K and the old V' may move a subsequent entry in the ListIterator, but i don't really have a problem with that. I think it might be useful (although the original set is always insert order).
|
|
|
|
|
13
|
Game Development / Performance Tuning / Designing a Collection
|
on: 2012-08-18 19:49:50
|
|
Designing is another word for procrastination edit: new and better version below
This is fairly simple as you can see; just directional methods sorely lacking on the LinkedHashMap class.
Now here comes the bad part - yes, you guessed it - i want bidirectional iteration and adding elements (almost all the elements of a ListIterator)
Unfortunately LinkedHashMap sucks and the needed fields and methods are private and package protected.
My idea for the design would be to get to the linked list nodes (which are entries on the LinkedHashMap so they can be got with HashMap.getEntry) and use that (and the header and modcount...) to make a new List iterator:
ListIterator from(E elem)
Anyway, for the methods on the Set class above to continue to work, ListIterator.add (not set) would have to rebuild the Integer Values beyond when used on the Set context, that's the reason for the iteratorAddModulus.
I can't apparently reuse the LinkedHashset without copying the whole source file into my source tree (and putting it on 'java.util').
Am i being dumb and something with these characteristics - a set, which is directional, with bidirectional iterators that can set() and add(), that can check element > otherelement in O(1) and is (probably) fast already exist?
|
|
|
|
|
14
|
Discussions / General Discussions / Re: Project Jigsaw might be pushed back to Java 9
|
on: 2012-07-24 20:13:24
|
|
I wish a module system had been there from day one, i see lots of 'svn projects' with the dependencies in the repository as binaries that inevitably get out dated or their dependency unused (but still in the classpath because no one wants to 'break' things).
It's just pathetic in the age of apt-get and maven (and the advantage of being able to test the new versions of the libraries easily is not to be overlooked either).
Quite frankly i'm getting sick of the slow lumbering java api. I guess i'm going to start programming in Rust or something if a decent standard api & compiler & tools ever emerges for that.
|
|
|
|
|
15
|
Game Development / Performance Tuning / Re: Linux java shutdown io bug
|
on: 2012-07-22 03:29:18
|
|
Actually they have a sync just before
I don't know man... this sucks, it's a bug i know it. edit: the code displayed had a sync BEFORE sending SIGTERM, ie: the signal that starts the shutdownhooks.
umounting is in another place than sendsigs
edit2: actually, cat /etc/init.d/umountfs | grep sync gives nothing and the actual command seems to be fstab-decode umount -f -r -d $REG_MTPTS
actually pretty suspicious of the force, but i don't really know anything about umount
|
|
|
|
|
16
|
Game Development / Performance Tuning / Re: Linux java shutdown io bug
|
on: 2012-07-22 03:17:33
|
Ubuntu whatever the latest. Here is the 'guilty' code: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public static void writeObjects(Path objectLocation, Serializable... obj) throws IOException { FileOutputStream st = new FileOutputStream(objectLocation.toFile()); try (ObjectOutputStream s = new ObjectOutputStream(new BufferedOutputStream(st, 20000))) { for (Serializable a : obj) { s.writeObject(a); } s.flush(); int counter = 0; while (counter++ < 5) { try { st.getFD().sync(); break; } catch (SyncFailedException e) { } } } } |
I added the sync and changed from Files.newOutputStream to fileoutputstream recently, not even sure if it helps (i know syncfailedexception happens sometimes because 'paradoxically' i was able to sometimes write the exception to the log i deleted since, if i tried the sync) Also the the jvm is not being SIGKILL'ed (or halt'ed) - it's far too little time, i looked at the killing code in the init.d scripts in sendsigs and it has a 10 seconds maximum tolerance by checking for processes every second. Long before that happens the shutdown is progressing and the jvm dies a natural death. I would expect umounting would flush the goddamned operating system buffers to disk.
|
|
|
|
|
17
|
Game Development / Performance Tuning / Linux java shutdown io bug
|
on: 2012-07-22 01:49:32
|
|
I've come to suspect there is some kind of shutdown bug at the interface with the operating system on openjdk and shutdownhooks
To be clear i'm not talking about problems from the jdk (there is a hilarious one where if you try to serialize a File that came from a JFileChooser in a shutdownhook it will throw a exception because JFileChooser 'files' are a fake flyweight object that depends on a shutdown hook of the jdk to not leak memory)
I'm talking about the jvm exiting - naturally, by escaping the main or run of all threads - before the buffers are committed to disk - a outputstream.flush() is NOT the same as a disk sync.
When i tried to get the file descriptor of the corresponding fileoutputstream and force the issue with the sync method during shutdown, sometimes i would get a SyncFailedException.
I only really suspect this because actually getting information after a certain point in the shutdown turns impossible - all 'unflushed' 'unsynced' log files start to go nowhere - found this by repeated experimentation and comparing the point where the log stopped making sense - it just disappeared sometimes late in the shutdown
I suspect the shutdown init.d or upstart or systemd or whatever protocol is turning off the discs before the application shutdown hooks flush the data, therefore missing the final 'sync'. I also suspect the one sure fire way to prevent this (i already optimized what i have to write to disk by performing amortized writes) is to have a init.d|somethingelse script before umount preventing the normal shutdown sequence from going on if it detects the process still in operation and force a sync in the application at the written files in the shutdownhook.
I'm unhappy with this turn of events and i'd like to rant to whoever designed init.d And oh, i'd like systemd to do better if it can
|
|
|
|
|
18
|
Game Development / Newbie & Debugging Questions / Re: Quick questions for mechanims & optimizations.
|
on: 2012-06-25 19:41:39
|
|
Serialization is mostly used for storage (except for weird 'deep' cloning) - that's what i meant.
By the way a warning: doing what i did above (having two different files containing different serialized object graphs) may cause the same object reference that was originally in both object graphs to be != on the reconstructed application.
I avoid this by not having the same object in both graphs, ie: i only ever get my data objects from my data container which is the secondary graph.
|
|
|
|
|
19
|
Game Development / Newbie & Debugging Questions / Re: ObjectOutputStream
|
on: 2012-06-25 05:22:41
|
I just thought of another way than reading stuff in 'manually' in readObject. You still need to do the transformations (that is, taking the old object and reading what you can to the new format), but it should be easier not having to deal with readObject: http://docs.oracle.com/javase/6/docs/platform/serialization/spec/input.html#5903The readResolve method is called when ObjectInputStream has read an object from the stream and is preparing to return it to the caller. ObjectInputStream checks whether the class of the object defines the readResolve method. If the method is defined, the readResolve method is called to allow the object in the stream to designate the object to be returned. The object returned should be of a type that is compatible with all uses. If it is not compatible, a ClassCastException will be thrown when the type mismatch is discovered. So... keep old major version of the dataclass around, use interface, read replace old versions to new versions... profit? Not so sure if changing the interface would be allowed... prob not since the old versions implement it... but maybe if you delete that 'implements' and keep the serialversionUID. I dunno... Or you can just bite the bullet and use versions since there is no magic available for the actual transformations.
|
|
|
|
|
20
|
Game Development / Newbie & Debugging Questions / Re: Memoizing positions
|
on: 2012-06-25 04:47:24
|
|
Memory. Save the preprocessed hits to memory
it's a waste of processing cycles - each 'has previous' is actually recalculating the hits of the search phrase in the whole text prior to the current index (and having a cache may actually help in hasnext too).
What is making me hesitate is that i hate and fear caches because of the complexity introduced in maintaining them: The document may change, the search index may change, the search phrase may change, actually finding the cache index. Of these, only the first two look amenable to retaining part of the cached search, haven't really thought about it more than this, it makes me so mad about this inelegance, oh why didn't you make a backwards search variant mr moore, oh why do i have to deal with caching behaviour anyway for better performance ffgfgdgufgfgdgfdgdfjdkgdjfjgdjk.
|
|
|
|
|
21
|
Game Development / Newbie & Debugging Questions / Re: ObjectOutputStream
|
on: 2012-06-25 04:15:23
|
*snip*
Not really what he wants - that's the uncommon case where nothing data changes - edit: -> this is where i went off the rails (it's not actually what he wants either)  he wants (quite naturally) to avoid breaking the serialization of critical data when something in another part of the graph breaks. Java serialization doesn't really go out of it's way to help with this; but i can tell you that isolation of the unchanging data in a another file/stream is key: http://www.java-gaming.org/topics/quick-questions-for-mechanims-optimizations/26700/msg/235429/view.html#msg235429Something like that should avoid most problems (except uniqueness == issues, which it may cause because of multiple graphs). In retrospect serialization should have been position independent somehow if that was possible - as a generic protocol it's utter failure when something as dynamic as code is represented. If you try to do it as 'it is meant to be used' your major version readObject() conversions (if you don't give up on that) will be byzantine - modify the order of the fields in a holder class? Hello serializable error, goodbye user state. Now if you're actually talking about changing the (supposedly final) user data; you need to overload readObject and check a version number or something like that you wrote to the stream. You can maybe try a cascaded switch of versions, with default values on top. I don't know because i am hoping to avoid that layer of hell forever, also, f**k the users.
|
|
|
|
|
22
|
Game Development / Newbie & Debugging Questions / Memoizing positions
|
on: 2012-06-23 20:43:18
|
I've got this... iterator class. It's type doesn't really matter (it's a document find iterator) Anyway, it's logic is implemented using hasNext() as the code that actually calculates the new index... and it's hasPrevious() is: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public boolean hasPrevious() { [...already done at least once logic...] int localIndex = searchIndex; searchIndex = 0; int tmp, tmp2 = -1;
while (hasNext()) { tmp = next(); if ((tmp + 1) < localIndex) { tmp2 = tmp; } else { break; } }
if (tmp2 == -1) { searchIndex = localIndex; return false; } else { lastFound = tmp2; return true; } } |
 (so embarrassed) Anyway since the underlying search algorithms don't support backwards searching, memoization is the obvious answer to this problem, although it would introduce stale cache issues. I don't have much experience with memoization - what do you think it's the best policy: to expand the table (much harder it looks like) or just null it and let it be reconstructed from scratch?
|
|
|
|
|
23
|
Game Development / Newbie & Debugging Questions / Re: Quick questions for mechanims & optimizations.
|
on: 2012-06-23 20:03:15
|
|
Serialization is a pain if you finalize some container classes but want to also save other app state that is entangled on the broader constantly changing app classes.
What i ended up doing in this case was 'cheating': the serialization protocol works as normal until you get to your container/data class. There you replace writeobject and readobject (and add something to your constructor as you'll see).
On the write/read object you completely ignore the passed streams and create new ones of a completely different file and read/write the object into that file; this isolates the non-changing part of your program into another serialization graph. Problem is, that since the first graph can go kaputz independently of the second, you need to try to read the data in the constructor too; no big deal, just call readObject(null) there.
This will make your version upgrades a bit more consistent, so that adding a new field 'window position' doesn't nuke the 'highscore table' or something silly like that.
This might make you make a bit more of work than before on the failure case (if the state app graph serialization read fails after new-ing your container class the second graph gets read twice) - if worried about that - you really shouldn't since it's the failure case - you can use a static singleton for you class and read in a static block (that only happens once per class).
|
|
|
|
|
26
|
Game Development / Newbie & Debugging Questions / How to compress (lossly) longs into ints?
|
on: 2012-06-20 17:08:49
|
|
Upgraded to java 7, got a new problem: java 7 introduced the URLConnection.getContentLengthLong() method, which i want to use (for those wonderful 2gb+ downloads)
Anyway, the problem is that jprogressbar and all the ancillary classes is only prepared to accept ints. This is not so critical considering it's almost all view classes (taking care to be careful around the edges since we don't want it to look "not started" or "done" when it's not) - but the long needs to be compressed into a int
I was thinking of something like: 0L is int 0 1L ... (totalL -1L) is int mapping(1L) ... mapping(totalL -1L) where some number of contiguous mappings give the same int value totalL is int mapping(total) that is unique (to make JProgressBar look full only at the end)
I'm terrible at maths. Help?
|
|
|
|
|
27
|
Discussions / Miscellaneous Topics / Interfaces you'd like to see in the jdk
|
on: 2012-05-02 20:59:17
|
|
As we all know, there are plenty of good ideas that would be nice to have standardized, but don't get even get a time of day because it never would get implemented in the jdk (and maybe they shouldn't). Still, i think it's a good idea to have a well thought out interface (as if that was possible without 3 prior implementations!), so as to subtly pressure the library authors to support it, so you can change tools.
I've got a "hate-hate-love" relationship with this stuff, because it inevitably ossifies and leaks, but it does sometimes allow to change implementations. Exe: JAXP, corba, java speech api etc.
Still, i've recently thought it would be nice to have a "bug report" interface, so that i could use a library that would report to my project google page bugs on uncaught exceptions and filter duplicates with the stacktrace. Such a simple interface would be nice encouragement for library writers.
Do you have any such jdk interface longings?
//is there any library that does this stuff for google code?
|
|
|
|
|
28
|
Game Development / Shared Code / Re: Some kind of image list thing
|
on: 2011-06-11 10:07:39
|
|
I did it. It was just getting the old action with the arrow keycodes from the old inputmap and actionmap, saving it has a parameter for the new action if they aren't on the edge of the row and detecting the edge and move up or down.
It's ok i think - only problem should occur if some platform doesn't use the arrow keys (the is no left movement key or something abstract like that).
|
|
|
|
|
29
|
Game Development / Shared Code / Re: Some kind of image list thing
|
on: 2011-05-28 07:34:09
|
|
I wanted to ask: anyone knows of a way to make a Jlist like this, that has multiple cells in both rows and columns, allow for different keyboard movement with the arrow keys? Instead of only using ↑ and ↓ to move up and down also allow ← and → if the selected cell mets the west or east edges of the viewport?
|
|
|
|
|
|
Add your game by posting it in the WIP section,
or publish it in Showcase.
The first screenshot will be displayed as a thumbnail.
|
|