I have a fairly basic question that I cannot for the life of me find the answer to online (most definitely due to not really knowing what I am looking for).
Suppose I have multiple (for the most part static) objects that are stored inside one VBO and drawn to the screen. Each object will have images and text/external data associated with it. I need to be able to navigate this "map" of objects and on-tap, access the corresponding information.
My question is, what is the best practice when it comes to storing this corresponding data and linking it to its respective drawing? I figured you create a "parallel" array of custom objects that each references its drawing and holds all the data... Although it seems quite elementary and thought there might be a better way. Considering also that there will potentially be thousands of these objects on the "map".
You can Use model class and put all common data intro one entity than use extends. You can use yours custom object who will consider whole VBO or opengles program data. About identity make ID for each elementary object or "draws".
-I understand your problematic. In opengl/es procedural programming is actually on scene.
Remember you are still in android envelopment you can use any java/android methodology.
-When you say "tap" did you mean click? If you so than see "Raycast" thema.
-This is interest file . It is JS not android but you can use same logic methods to make your object based app.
https://github.com/zlatnaspirala/visualjs/blob/master/project/project_instance_webgl2/lib/matrix-world.js
You can see lines like this :
App.scene[squareObject.name] = squareObject;
I have a global object App.scene . I put here all object buffer data. It is a key access but works like array.
I wanna say your idea about arrays is good. But not in parallel order. Procedural part works with no problem you need draw function for each element entity.
Look at draw methods :
https://github.com/zlatnaspirala/visualjs/blob/master/project/project_instance_webgl2/lib/matrix-draws.js
For example one of my draw entity is App.operation.draws.cube function.
I use this method to draw any cube but each cube is uniq object with uniq data inside.
Related
I wonder why all Table Views (also in Android) have to have special object that provide them data ?
https://developer.apple.com/library/ios/documentation/uikit/reference/UITableView_Class/Reference/Reference.html#//apple_ref/occ/instp/UITableView/dataSource
Why Table Views can't be populated from controllers (or Activity class in the case of Android) ?
For example UILabel in iOS can be populated just by setting "text" property
https://developer.apple.com/library/ios/documentation/uikit/reference/UILabel_Class/Reference/UILabel.html#//apple_ref/occ/instp/UILabel/text
Could you explain what is the purpose of such design ?
This is a really great question.
We can break this into two reasons - a general one and a specific one that is a common example of it.
First, though, notice that it's even more than that. A UITableView can have two delegate controller objects, a UITableViewDataSourceDelegate and a UITableViewDelegate. The first provides the data; the second responds to actions taken on the displayed data. Why all these layers of abstraction? Why not just stick it in the UIViewController?
The general reason not to is suggested by the name 'UIViewController'. It's meant to control views. In iOS and I expect in android-land, there is a strong temptation to just 'stick it in the view controller' - leading to the Very Large View Controller antipattern, which you can read about a lot (eg here).
Far better for maintenance and organization for the view controller to lay out views and handle button presses, and some other controller object to handle the well-defined and really quite separate responsibility of providing the data.
It's not uncommon to have some sort of object that handles the data anyway - a shopping cart, or list of real estate properties, etc - that encapsulates additional business logic (providing subtotals, for example) but fundamentally already 'has' the data. In that case, provide a category or a lightweight controller that can 'bridge' between that data and the table view, and pass the model object, instead of an array, between view controllers.
This gets into the specific: in iOS, we have things like NSFetchedResultsController. This is a fantastic class that does a tremendous amount of data sorting, pagination, addition, deletion, slicing, dicing, folding, spindling, and mutilating for you - and it also speaks UITableView's language natively. Pass one of those around and you keep your view controllers clean and tidy and separate from your data.
TableViews do need a special or separate object but they do require an object implement the correct protocol so that it can find the data. In Apple's default implementation, it Uses a UTableViewCotnroller that is a new object responds to these methods as well as does some other things such as making the UITableView the root view of the view controller.
If you do not want to use that object for whatever reason you can still manually add a UITableView to your view controller, then sets its delegate to the view controller. Although it is a good to move it out of the view controller if possible to help keep the view controller small and the data reusable.
I am currently working on my first serious android app. It is the first time I am appliying solid patterns programing and design which I learnt during the university studies. I have come across a situation where I dont know the "correct or best" way I should implement it. The problem is as follows:
As you might already know, in Android is not a good idea to keep models with bitmaps as you can easily reach the memory heap. I got a model in my app called "Event". An event has an id, name, description, bitmap etc.. However as I have stated before, when loading events from the database I load every attributes but the bitmap. At the moment, I have got it as a bitmap attribute referencing null with a set and get methods. Thus, my question is, from the point of view of patterns, clean programing, high cohesion and low coupling paradigm etc, how is the best way to retrieve the bitmap from the database? and where should it be retrieved, into the model or when it is required somewhere in the UI (i.e. a listview) ?
Until now I have thought the following solutions:
1.- Lazy loading pattern. Which means to develop the getBitmap inside the event model as a call to the database retreiving the bitmap associated with the event.
Pros: Very easy to implement; the model knows how to find its own bitmap atribute.
Cons: High coupling between the database interface and the model; the model shouldnt have awareness from outside itself; the model wouldnt be a POJO; models shouldnt have complicated methods; many calls to the database (imagine many getBItmap calls).
2.- Getting the model id and calling the database interface from the bussiness logic everytime I need the Bitmap. The model would never have a bitmap referenced from itself.
Pros: Bussiness logic calls the database interface, low coupling and correct model implementation.
Cons: Many objects which need the model bitmap should have a database interface reference, increasing copuling between the object and the database interface along the app. Think on an Android listview adapter which needs the bitmap from the event, it should call the database interface which seems kinda ugly. Besides, shouldnt be the own event model responsible to provide its own bitmap?
3.- Your own answer :)
Thank you very much for reading and I ll appreciate your answers.
Explanation of overall architecture:
Activities and the rest of the bussiness logic call a database interface (facade pattern) which I have implemented using Parse analytics API which allows to upload files, images etc as attributes on tables. Thus, if you want to retrieve a bitmap, simply query the parse API (implemented in the facade).
A simple case of bitmap retrieval would be (as I typed before) building the event view for a listview into the adapter, which would need the title, description, bitmap, etc of each event loaded.
Existing Parcelable examples are rather trivial. If you have a complex object graph the following questions arise quickly questioning the feasibility:
Is there any way to prevent an object being written multiple time into a parcel?
Are there any best practices to limit the depth of the object graph while writing?
To give an example for the first question, object A references B, which in turn references A. This cycle leads to writes A, B, A, B, A, ... until we get an StackOverflowError because there does not seem to be a way to just reference an object that was previously written.
For the second question let's we have a long graph A->B->C->D->E, and we want to serialize A with an additional depth of 2, which would be just A->B->C. We did this by writing a custom writeToParcelDeep method, which is of course not as convenient as the standard writeToParcel.
Java serialization will preserve reference and write a object just once. Also current devices are much more powerful than the ones from the past and I'm not so sure that performance gain is justifying writing Parcelable biolerplate code especially complicated one as in your example.
I'll keep using serializable and you can read more about my findings on this topic here.
I am porting an app from Android Java to iPhone.
In Android I used Lists/ArrayLists alot.
On iPhone I plan to use NSMutableArray.
Is there any way to define or even indicate the type of objects in an NSMutableArray.
I know one can put any type of object there, but I would like to make it more visible and transparent.
Many thanks
It's not clear exactly what you're asking.
If you just want to make it clear to the reader what sorts of object of are in the array, just name it appropriately (you can't enforce it at the language level):
NSMutableArray *arrayOfMyClasses;
If, on the other hand, you want to find out the type of an object that you're reading back from the array then you can get the underlying class using:
[obj class]
Or easily compare to other class types:
if ([obj isKindOfClass:[MyClass class]) { ... }
Tim
I assume you are looking for template pattern in Objective C. Unfortunately, it is not available in Objective C (at least directly).
You might find this question of StackOverflow.com interesting
You can only indicate a type.
for(id obj in _assets) {
NSString *className = NSStringFromClass([obj class]);
NSLog(#"%#", className);
}
Arrays are ordered collections of any sort of object. For example, the
objects contained by the array in Figure 1 can be any combination of
cat and dog objects, and if the array is mutable you can add more dog
objects. The collection does not have to be homogeneous.
Collections Programming Topics - Arrays: Ordered Collections
I'm trying to build a complex form where almost all of the elements are optional. It starts with just a single field and an "add element" button. When you click add, the form shows a Spinner of the types of elements you can add to the form (location, photo, detailed note, timestamp other than "now", etc). When you select an item, it will launch an Activity, and each item has a different associated Activity.
In addition, each choice will have several bits of data, which it would be nice to store "with" the Activity somehow:
An icon and the displayed name in the Spinner
A key for storing the data in the db (as well as passing to a webservice)
A layout for how to display the result on the original form (i.e. a thumbnail for the photo, the lat/lon for the location, etc)
I was considering a set of classes that all extend an abstract FormElement class, and would have static elements for each of the above extra pieces of data. (An additional bump for this solution is how much of a pain Resources are in a static context.)
How can I make this as clean and maintainable as possible? I'd really not enjoy editing five different files to add a new type of element to this form. (Mostly because I can guarantee I'll miss one and spend hours chasing down unbugs.)
A few tips...
Unit tests will prevent "unbugs" :)
When each Activity has obtained the information it needs from the user, call Activity#setResult() with an Intent that contains your per-type data. Intent supports all the Bundle methods, so you can set different types of data as needed.
To support #2, make sure you're using Activity#startActivityForResult(Intent,int) to launch it, and listen for the result in Activity#onActivityResult(int,Intent)
I would probably maintain the list of available "element" types for use with the SpinnerAdapter (e.g., ArrayList<Class<? extends AbstractFormElement>>, and invoke static methods like .getDisplayName(), .getActivityClass(), etc, in the Adapter's getView() method, in order to determine what to display and what Activity to launch.
In this way, your list would actually contain things like { MyPhotoElement.class, MyTextElement.class, MyDateElement.class, ...}).
As each element is added to the form, add it to an ArrayList<AbstractFormElement>, which will be used to back another Adapter for a ListView. That adapter will dispatch the inflation of a custom view layout, as well as the creation of a ViewHolder, based on what type of object it is -- that will require that each distinct AbstractFormElement will have its own "view type", according to the Adapter. See BaseAdapter#getItemViewType(int) and related getViewTypeCount().
It's worth noting that these will need distinct view types only if one cannot be converted to the other... For example, if you have two "Elements" that only need to display a string of text in the list, those can both share a "text-only" view type. Likewise, two elements that only display a photo, or can easily convert one to the other (e.g., an icon with a caption, vs a photo thumbnail with no caption), can share a single "image-plus-caption" view type.
With the above in mind, you actually would end up having to modify different files to add a new type (well, I guess technically you could have them all in one file, as inner classes, but there's really no good argument for doing that), but if you've done your interface API correctly, and follow good OO practices, and implement good unit tests, you'll considerably reduce the amount of effort required to find bugs -- simply because most of the things involved in adding a new type would actually force a compiler error if you do it incorrectly. Add to that the fact that a proper unit test suite will be able to programmatically add all possible types, and ensure that everything displays properly, and you should have a pretty streamlined process for easy extensibility :)
It sounds like a lot of work, and it might seem tedious and verbose at first... But the end result is actually much more maintainable, especially if your list of element types is going to be fairly extensive.