Re: More Core Data Questions
Re: More Core Data Questions
- Subject: Re: More Core Data Questions
- From: Ben Trumbull <email@hidden>
- Date: Mon, 12 Oct 2009 22:34:30 -0700
The project is a game engine which has 2 graphs. The first is a tree
of events that represent the story. Each "event" in the story is an
immutable object, and there is a special event which represents a
series of events to run in order and one which represents branches
that the player has to choose from. All of these are immutable, and
the main goal is to avoid loading the whole graph which will consist
of 10k-50k events. This graph will be the same for every player.
Okay. If you build this immutable store on your dev machine and
include it in your project resources, you should see excellent
performance. Creating a store this size on the device would take a
while. Just don't go crazy with to-many relationships or database
normalization (for this many objects, on a phone).
Of course, you don't want to search across all the events all the
time. You'll want some criteria (NSPredicate) to evaluate just the
subset of relevant elements.
I also use proxies as context switches to objects in this
graph. A concrete example is the current location, which is a proxy
that pretends to be a location, and forwards all the messages it
receives to the location object where the player is currently
located. This allows events which reference locations/players/etc
that change depending on state to remain immutable.
You don't need proxies or NSProxy for this. You can just use a
delegate. Off the cuff, I might consider implementing a protocol on
your immutable objects for methods like "currentLocation" and
"currentPlayer" which vector through a semi-global context object not
unlike the app delegate. Then you can use keypaths to naturally write currentPlayer.name
and so forth. NSProxy is unnecessarily heavy weight for simple
delegation. They use memory too, ja know. And the semi-global
context allows you to avoid making all your objects larger. You might
even model the "current state" as a formal entity. That buys you
change tracking, undo, multi-writer conflict resolutions and the
ability to easily persistent and search for it. It also allows other
managed objects to work with it naturally.
The event graph is traversed from a background thread which basically
runs through events in order until it needs a user response.
Surely most of the events are not relevant most of the time, no ? By
location, if nothing else like pre-requisiste events. If you can keep
a cookie into the player's choices tree, then you can do an indexed
query on eligible events and only evaluate those in memory.
I have a
controller set up which communicates with the main thread, and the
background thread blocks until the controller gets a valid response,
at which point it starts unwinding again until it needs another
response or reaches the end. There is no run loop for this thread.
sure. don't forget an autorelease pool.
All of this works fantastically for the game, but now I have reached
the point where I can no longer put off save & load. When I started
the project Core Data was not yet available on the iPhone, so the
design did not take it into account. I was thinking that core data
might be able to help me save & load these graphs, but now I am not so
sure. My new plan is as follows:
Create a manager singleton for events which returns an event object
for a given id, and then modify the special events mentioned above to
hold an event's id instead of actual event objects,
You could do that. Probably easier to just use an
NSManagedObjectContext and the delegate I mentioned above.
and then call off to the manager with the id whenever they need to
run an event. Inside
the manager I would either call off to a small sql database with blobs
holding freeze-dried (keyedArchiving) objects & an id column,
not a great plan. No searching into blobs, no partially loading or
saving the larger freeze dried objects.
Also, you could do that trivially with Core Data and just be done.
or save each event as a file with the id in the filename.
Each event file would have to be > 8K before this even begins its
distant journey to approach making any sense at all from a performance
perspective.
I would also have a cache in the manager to avoid reallocating
objects unnecessarily.
I wouldn't worry about caching just yet. Bigger fish.
I would prefer to have something like core data do this lazy
loading for
me, but it may not work in this case.
For the objects that store state, I will just archive them into a save
file.
still no lazy loading or incremental saving.
Thoughts? Does this sound like a reasonable approach,
Not really, no. Maybe you need to do something quick & very dirty for
deadlines. c'est la vi
or will core data actually work for me?
It's not clear to me why you think it wouldn't. So far, all I get
is that you haven't used Core Data before and don't know it. Which,
btw, is a perfectly valid issue to be having as you consider bringing
a previously designed project to deployment . Major changes in
technologies are generally best saved for major versions. Also known
as the "if it's making money, don't **** with it" principle.
Unfortunately, it sounds like you don't have a ready alternative
besides to spend a considerable amount of your own engineering
resources. You'll have to decide if learning Core Data, and tuning
your app performance fits within your schedule requirements, and
whether implementing, debugging, and tuning all this yourself will
really take any less time.
You might consider mocking up a Core Data version over a few days and
seeing how far you get.
- Ben
_______________________________________________
Cocoa-dev mailing list (email@hidden)
Please do not post admin requests or moderator comments to the list.
Contact the moderators at cocoa-dev-admins(at)lists.apple.com
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden