开发者

Questions about a game-loop iteration data structure

So, I'm writing a 2D Java game engine based on LWJGL. (It'll be open source, but when it's a bit more polished. :P) I'm pretty far along, but as I'm trying to go through another polish I've decided I need some outside opinion on a data structu开发者_如何学Cre I'm using.


The structure is called an UpdateList<(generic)>. Basically, I want a fully dynamic list of objects to represent all objects in a game, yet be able to iterate through it with the speed of an array, as conceivably hundreds+ of objects could be referenced.

To do this, the class has 3 data members: an ArrayList<(generic)>, an array of the same type, and a boolean marking whether or not the list has changed (titled changed).

The class works fairly straightforwardly - objects are added and removed from the ArrayList as you would imagine, and doing so sets changed to true.

Then, there are two methods that involve accessing the array - updateList(T[]) and getUpdateList().

updateList passes the array to ArrayList for it's toArray(generic[]) method; the array is set to this new value (iff changed is true - if the list hasn't changed, nothing happens).

getUpdateList returns the array.


So, for use, updateList is called whenever the developer wants to update the array, and getUpdateList is used for the iteration. Not only is this a little bit faster than just using an ArrayList, but it also avoids ConcurrentModificationErrors, and the UpdateList can be edited during an iteration through itself.

So, two questions:

1:) Is this a good way of achieving the type of data structure I need? In terms of use/API, it's extremely simple, but I'm concerned about ArrayList's toArray method. How long does this take at higher numbers of entries? If it's unwieldy, is there a better dynamic class I can use?

2:) Secondly, I don't like having to call updateLists(T[0]). Is there a good way to manage the copy of the ArrayList into an array without needing this?


1:) Is this a good way of achieving the type of data structure I need?

In short, no, I think you can do better than passing arrays around. In reading your original post, it seemed that almost everything that you wanted to do would involve an O(N) operation (linear in terms of the number of objects). That would get very slow quickly.

In terms of use/API, it's extremely simple, but I'm concerned about ArrayList's toArray method. How long does this take at higher numbers of entries? If it's unwieldy, is there a better dynamic class I can use?

Yes. Consider having a set of objects that represent things in your virtual world. Instead of making an array of objects that change for each frame update, you can instead think of multiple threads of computation:

  1. One thread watches for changes and writes individual object references to a ChangedSet data structure (with a write-lock around the writing). This replaces your changed boolean with a set of changed objects. Note, also, that Sets have the uniqueness property, so you don't have to worrying about adding the same object mutiple times.

  2. Another thread waits for a signal to update screen, read-locks the ChangedSet, copies the contents out as an ArrayList (or UpdateList, if that's what you're calling it) and then empties the ChangedSet (releasing the read-lock).

Now your UpdateList can be used independently, without worrying about passing arrays back and forth.

EDIT: responding to the question in the comment

It's almost always easy to take data structures from a multithreaded architecture and bring them to a single threaded one. In this case, adapt the above to have a loop watching for changes that adds to the Set. Follow that with a loop that takes the changed set and puts it in the ArrayList.

HOWEVER, you should remember the Java is always multithreaded, whether you realize it or not. The Swing thread (AKA AWT Event Queue) is separate from your computation. SwingUtilities.invokeLater() is an excellent solution for adding deferred rendering code to an otherwise single-threaded solution.

Just remember, it's critical to create that disconnect between the rendering code and the data management. You can do that with either separate structures or proper concurrency but if you ignore the problem, you'll either have deadlock or ConcurrentModificationExceptions.

END EDIT:


An ArrayList is really an array under the hood, so there is no need to use the extra array. As for concurrency, you can make your operations thread safe.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜