My app reads a text file line-by-line, copies the data into an array of Card objects, and then creates SceneKit nodes for each one. Some of the Cards modify or make iterative copies of the data on earlier lines, so there is no 1:1 correspondence between line numbers and the number of SCNNodes.
I'm trying to come up with a way that I can uniquely name the nodes when they are created so that I can use childNodeWithName(_:recursively:) to find them if. Using the Cards index in the array is not useful because that might change - the user might add or remove objects or reorder them, for instance.
Is there some sort of unique ID or hash on the Card (or any) objects themselves that I can access that I might use for this task?
the answer to your question depends on what a Card represents and is completely independent of SceneKit. I guess it's up to you to find a hash function that works well for what's contained in a Card, or you can simply store a NSUUID in the Card's initializer.
Related
I was using GetChild() with the specific number as I arranged. But when the child objects started getting shuffling, I could not use GetChild().
Now I have three options.
1. Try to sort the child objects overtime they get shuffled. I need to
use this option when GetChild() is must faster compared to the
below.
2. FindGameObjectWithTag(): I read, Finding game objects with tags executes much faster than finding with names.
3. I have a total to 81 characters in the scene. Is it wise to attach all the 81 to the script upfront and access from that game
objects array?
Thanks.
If you are instantiating all the 81 characters from single point, I see it perfectly valid to store them in collection for further operations or delegating the operation to different object for processing.
It's also true that searching with tag is one of the fastest way to search around, but as you are checking for name, not for .GetComponent<T>() it's circa the same time to find what you're looking for.
From programmatical side, I'd rather stick with collection and references than gameobject names, as name can easily change for any particular reason (for ex. somebody changes name of gameobject to type of characters).
Also, please note that gameobject name can be duplicate.
Note: you are referring to attached prefabs but you should actually store gameObjects that resulted from prefabs instantiation.
A part of my program relies on recording the lengths of roads within my user interface as they are drawn out. As this requires looping , and as I want to be able to keep the name of the list all the data is stored in the same, is it possible to create lists thusly :
set list road-length X
(where X is a counter that is incremented every time a condition is met). Essentially can I tag numbers on to the ends of lists so that I can tell them apart when they need to be read later on in my program?
You can, but it is almost surely the wrong approach. (For one thing, the names will not be global unless you declare them all ahead of time.) Instead, use the table extension, create a global to hold your table, and use the table to map your id numbers to your lists. This will prove much more useful.
Supposed I have a key-value database, and I need to build a queue on top of it. How could I achieve this without getting a bad performance?
One idea might be to store the queue inside an array, and simply store the array using a fixed key. This is a quite simple implementation, but is very slow, as for every read or write access the complete array must be loaded / saved.
I could also implement a linked list, with random keys, and there is one fixed key which acts as starting point to element 1. Depending on if I prefer a fast read or a fast write access, I could let point the fixed element to the first or the last entry in the queue (so I have to travel it forward / backward).
Or, to proceed with that - I could also have two fixed pointers: One for the first, on for the last item.
Any other suggestions on how to do this effectively?
Initially, key-value structure is extremely similar to the original memory storage where the physical address in computer memory plays as the key. So any type of data structure could be modeled upon key-value storage surely, including linked list.
Originally, a linked list is a list of nodes including the index information of previous node or following node. Then the node it self should also be viewed as a sub key-value structure. With additional prefix to the key, the information in the node could be separately stored in a flat table of key-value pairs.
To proceed with that, special suffix to the key could also make it possible to get rid of redundant pointer information. This pretend list might look something like this:
pilot-last-index: 5
pilot-0: Rei Ayanami
pilot-1: Shinji Ikari
pilot-2: Soryu Asuka Langley
pilot-3: Touji Suzuhara
pilot-5: Makinami Mari
The corresponding algrithm is also imaginable, I think. If you could have a daemon thread for manipulation these keys, pilot-5 could be renamed as pilot-4 in the above example. Even though, it is not allowed to have additional thread in some special situation, the result of the queue it self is not affected. Just some overhead would exist for the break point in sequence.
However which of the two above should be applied is the problem of balance between the cost of storage space or the overhead of CPU time.
The thread safe is exactly a problem however an ancient problem. Just like the class implementing the interface of ConcurrentMap in JDK, Atomic operation on key-value data is also provided perfectly. There are similar methods featured in some key-value middleware, like memcached, as well, which could make you update key or value separately and thread safely. However these implementation is the algrithm problem rather than the key-value structure it self.
I think it depends on the kind of queue you want to implement, and no solution will be perfect because a key-value store is not the right data structure for this kind of task. There will be always some kind of hack involved.
For a simple first in first out queue you could use a few kev-value stores like the folliwing:
{
oldestIndex:5,
newestIndex:10
}
In this example there would be 6 items in the Queue (5,6,7,8,9,10). Item 0 to 4 are already done whereas there is no Item 11 or so for now. The producer worker would increment newestIndex and save his item under the key 11. The consumer takes the item under the key 5 and increments oldestIndex.
Note that this approach can lead to problems if you have multiple consumer/producers and if the queue is never empty so you cant reset the index.
But the multithreading problem is also true for linked lists etc.
I'm trying to build an iphone fitness app to allow the user to first create 1 routine. then within the routine to create exercises, and within each of those exercises to create sets. I'd like to allow the user to create as many sets/routines.
My plan is to create an array within an array within an array.
The first array will hold the exercises (represented by an array). And within the exercise array will be the sets(represented by an array). And finally the set array will actually store the information.
I guess my question is, is this possible? To dynamically create arrays based on the user? I can't seem to find any information on this subject,.
Yes, this is definitely possible: NSArray and its subclass NSMutableArray let you create and manage arrays dynamically, growing and shrinking them as needed.
Rather than using arrays of arrays of arrays, I would use special-purpose classes that hold arrays, but hide them, and present some functionality that is related to your specific application.
For example, you may want to consider creating a class for Routine and for Exercise. Routine would have methods like
-(void)addExercise:(MyExercise*)exercise;
-(MyExercise)getExerciseForIndex:(int)index;
-(void)removeExerciseAtIndex:(int)index;
and so on, with NSMutableArray serving as a storage for exercises.
I'm currently populating model objects into an NSSet (perhaps I should be using NSCountedSet). The models should be unique. What I do is pull them in from a web service, and then instantiate them on the client-side and add them to a set.
My problem is the following: There are times when I'll only pull one model and add it to the set, for instance say I have an inventory of Ferrari's. So I'll ask my server to pull me in one specific Ferrari because an individual clicks on that Ferrari's detail view from an inventory. The individual Ferrari detail view will list all of the different paints available for this model. So once the user drills into this Ferrari view, I will ask the server for all of the paints available for a particular Ferrari model.
Next, the user backs out and then goes to a view controller which asks for all of the paint colors I have available for every vehicle. I already have the Ferrari paints available in a stash. Now I'm asking for ALL of the paints from the server. What's the best way to aggregate the existing paints with all of the paints without duplicating resources?
What you need is a way to uniquely identify each object from the server. In a database an object (part or whole) can be represented as a row and the rowid is typically a monotonically increasing integer (although your data source could use something else). In any case, store this unique id in each object you create, and before creating a new object check for the existence of an object with that id. If the object already exists, return the existing object, and if it doesn't, create a new object and then store it in the cache. Using integers as ids works out nicely, because you can use NSMapTable as a cache with the rowids as the keys, and the values are the object pointers.
Maintain an NSArray* in your app which stores NSString* objects based on some hash function of your features:
hashValue = hash(color + horsepower + leatherSeating + whatever...)
For example, you might take the SHA1 hash of a collated string (example code).
Take the features you obtain from the web service and generate a hashed value from them using the same function.
Search your app's hash table for the web-service-value using -containsObject:.
If it returns YES, do X, else do Y.