I am designing a game that includes a world map widget; this widget has 100+ region widgets as its children. There is also a separate information panel widget. When I click on a region, I want that information to be sent and displayed on the information panel. My thoughts so far give me 2 options:
Connect each of the 100+ regions to the information panel. This seems ugly to me as I feel like the information panel should only know about the world map widget, not its internal workings (such as children).
Connect each of the 100+ regions to the map widget, and then have the map
send another signal to be picked up by other widgets in the game such as the information panel. This seems nicer as far as having independent widgets goes, but requires 2 signals instead of 1.
Is one of these methods preferable to the other? Or is there another solution I am missing entirely?
I used to work for a company which made its own geospatial information system (GIS) product and we had this exact use case using Qt as well.
From my experience we would use option #2 as it encapsulated the details and relationships between the information panel (i.e. a view) and the world map (i.e. a model).
In the future maybe your world map will contain more than selectable regions and the information panel may not want to have to start knowing about all of the different entities in your world map to display them. So yes while #2 results in some additional signals it can be better from an encapsulation and expansion standpoint.
For example connect the information panel to a signal from your world map regarding a selected entity rather than a region. Sure a region is an entity and using region directly could work but again in the future maybe your world map will have selectable buildings, markers, vehicles, etc...
i.e.
connect( mapWidget, SIGNAL( selectedEntityChanged( MapEntity* ) ),
infoPanel, SLOT( onSelectedEntityChanged( MapEntity* ) ) );
This way your information panel could be designed to generically display information about an entity, again from which a region is derived. If you want to add say a vehicle to your map and make it so the information panel can display it, all you'll have to do is derive your vehicle from entity and you'll be good to go.
Great question welcome to StackOverflow!
Remember that each QObject comes with a property system - a general purpose, Python-like key-value store. The keys are strings, and the values are variants. Since QWidget is a QObject, you can leverage that. Just by itself this makes QSignalMapper quite redundant.
You can also use the undocumented, but slightly faster userData mechanism - it uses integer keys instead of string keys. The unique key ids are obtained through registerUserData(), with semantics otherwise identical to QEvent::registerEventType.
Related
I need to write a QAbstractItemModel class that represents a hierarchy of different object types. I want to be able at some point, show a table/list containing only level 1 elements, only level 2, and so on.
I am working on a network protocol analyzer tool, something like wireshark. I am capturing socket.recv and socket.send events from a process. In my model those events are called NetworkEvent. Each network event may contain one or more Packet. Each packet has one or more Message, where a message, based on its code, is parsed as a defined struct.
Here is an image of the program class hierarchy:
The main window has a list and a tree. I expect to be able to show:
a table/list containing only network events including its attributes.
a table/list containing only packets including its attributes.
a table/list containing only packets based on a network event.
a tree containing a packet/message hierarchy (with fields and sub structures)
a table/list containing only messages
a table/list containing only messages based on a packet
a tree containing a message hierarchy (with fields and sub structures).
So I thought the best idea was to model the QAbstractItemModel as a tree. First problem I encountered is that while each class has the concept of "children", each one has a different field that represents childrens, so I have to take care of that inside the QAbstractItemModel.
Also, because a table/list of EventNetworkdoesn't have same columns as table/list of Packet, nor Message, I can't properly use the same model to define all possible ways to show the data. I suppose the correct way to do this would be defining proxy models for each kind of view.
Is there any better or easy way to approach this? Or is this the way to go?
So you create a common base family of polymorphic classes, and use a base pointer as the data source for the model. One single role - the data object, from then individual delegates can access their specific data fields without having to bother implementing everything using roles. The role-centric use-case is really only applicable for isomorphic data sets.
Then you can customize the visual representation based on the actual individual object and view type.
I wouldn't marry to any particular representation. I'd only implement a list interface, this gives more flexibility how to represent the structure, you can draw simple lists as list view or table view, and you can also have tables or trees that are made of lists of lists.
In programming, it is always a tree, which is very obvious if you structure your application well, so it is a simple manner of choosing how you visualize each node and its contents. It is common to even have different ways of visualizing the same data, both in terms of visual structure and actual delegates.
You will have a tremendously easier time implementing this in QML, especially the actual visual representation, using the generic object model outlined here. Although if your object count is very high, you might want to implement it as a single abstract item model rather than have every object be a list model to avoid the overhead. But unless you deal with millions and millions of items, the overhead is well worth the return.
I think you are on the right course with thinking of using multiple proxy models, one for each table. I would suggest starting with QSortFilterProxyModel and implement your own filtering algorithm.
I will also suggest you might want to identify the type of data with using custom Qt::ItemDataRole enumerations, one for each type. I think it will make the filtering easier.
You may want to experiment with List, Table, and Tree Views to see which suits your purpose the best. The beauty of the Model-View system is you can easily change the View once you have the model(s) down.
I just got back into XNA and i started creating a map editor. The game will be a 2D editor that will contain both a Animation, Map, Level, entity, and crafting editor. So far it's going pretty swell right now; but, I think i am missing some key things within the editor
Here let me explain the game I'm trying to make:
I really want to figure out how to craft a particle editor
I also want to know how to use farseer phsyics engine (tried getting started on XNATutorial.com, but it's not working correctly).
Thank you in advance for any help you can give me, I'm just trying to see what would be the best things to enter into the game for a 2D action platformer.
To craft a particle editor decide on what you want to be able to do first, then come back with more specific problems, or questions.
Maybe you want to be able to design a particle template. This could define a particle's appearence and behavour.
Then you'd edit a particle emitter template. This would define what particle template to spawn, and what initial properties a particle instance would have.
Then you'd create a particle emitter object in your editor. You could maybe override specific properties in the particle emitter templates.
You could event have a particle emitter template that was a list of particle emitters to spawn, so you could emit different particles from a single editor object.
This would allow you to create lets say a fire-outside particle template, which was a yellow circle, a fire-inside particle template which was a red partcile, with a shorter life than for former. You'd then define 2 particle emitters, one for each one. Giving spawned particles upwards, but slightly random directions. Then create a multi-emitter called Fire or something. Then in the level editor you'd just have to place your Fire emitter and in-game you'd get a nice fire effect.
Posting a specific problem you have with setting up the physics engine would help.
The overall idea is that you have your game object representation, and you need to create and link them to the physics objects so you can simulate those objects and then update your game objects (for rendering and game logic).
So, when you load your level you'd loop through every physical object and create an equivalent in your physics engine, being sure you can link your game object to the physical one later. Obviously you'd need to keep both systems in sync by adding/removing physical objects as the game progressed and game objects where created/destroyed.
Then in your game loop you'd run your game logic, which might update their positions directly. Then update the physics objects so their position was the equivalent to the game object's. Then run a physics update. Then update your game object's positions according to the physical object's positions.
I have several graphs. The breadth and depth of each graph can vary and will undergo changes and alterations during runtime. See example graph.
There is a root node to get a hold on the whole graph (i.e. tree). A node can have several children and each child serves a special purpose. Furthermore a node can access all its direct children in order to retrieve certain informations. On the other hand a child node may not be aware of its own parent node, nor other siblings. Nothing spectacular so far.
Storing each graph and updating it with an object database (in this case DB4O) looks pretty straightforward. I could have used a relational database to accomplish data persistence (including database triggers, etc.) but I wanted to realize it with an object database instead.
There is one peculiar thing with my graphs. See another example graph.
To properly perform calculations some nodes require informations from other nodes. These other nodes may be siblings, children/grandchildren or related in some other kind. In this case a specific node knows the other relevant nodes as well (and thus can get the required informations directly from them). For the sake of simplicity the first image didn't show all potential connections.
If one node has a change of state (e.g. triggered by an internal timer or triggered by some other node) it will inform other nodes (interested obsevers, see also observer pattern) about the change. Each informed node will then take appropriate actions to update its own state (and in turn inform other observers as needed). A root node will not know about every change that occurs, since only the involved nodes will know that something has changed. If such a chain of events is triggered by the root node then of course it's not much of an issue.
The aim is to assure data persistence with an object database. Data in memory should be in sync with data stored within the database. What adds to the complexity is the fact that the graphs don't consist of simple (and stupid) data nodes, but that lots of functionality is integrated in each node (i.e. events that trigger state changes throughout a graph).
I have several rough ideas on how to cope with the presented issue (e.g. (1) stronger separation of data and functionality or (2) stronger integration of the database or (3) set an arbitrary time interval to update data and accept that data may be out of synch for a period of time). I'm looking for some more input and options concerning such a key issue (which will definitely leave significant footprints on a concrete implementation).
(edited)
There is another aspect I forgot to mention. A graph should not reside all the time in memory. Graphs that are not needed will be only present in the database and thus put in a state of suspension. This is another issue which needs consideration. While in suspension the update mechanisms will probably be put to sleep as well and this is not intended.
In the case of db4o check out "transparent activation" to automatically load objects on demand as you traverse the graph (this way the graph doesn't have to be all in memory) and check out "transparent persistence" to allow each node to persist itself after a state change.
http://www.gamlor.info/wordpress/2009/12/db4o-transparent-persistence/
Moreover you can use db4o "callbacks" to trigger custom behavior during db4o operations.
HTH
German
What's the exact question? Here a few comments:
As #German already mentioned: For complex object graphs you probably want to use transparent persistence.
Also as #German mentione: Callback can help you to do additional stuff when objects are read/written etc on the database.
To the Observer-Pattern. Are you on .NET or Java? Usually you don't want to store the observers in the database, since the observers are usually some parts of your business-logic, GUI etc. On .NET events are automatically not stored. On Java make sure that you mark the field holding the observer-references as transient.
In case you actually want to store observers, for example because they are just other elements in your object-graph. On .NET, you cannot store delegates / closures. So you need to introduce a interface for calling the observer. On Java: Often we use anonymous inner classes as listener: While db4o can store those, I would NOT recommend that. Because a anonymous inner class gets generated name which can change. Then db4o will not find that class later if you've changed your code.
Thats it. Ask more detailed questions if you want to know more.
its said that 1 ViewModel has 1 View.
1 View is for me a UserControl. What if my UserControl has different areas filled with data from different entities, do I have then several Views and need to build several ViewModels?
e.g: I display in a UserControl 3 entities: customer(listbox),order(datagrid),product(datagrid). Each of those "data areas" has add+remove buttons and textboxes to enter data.
Actually each of those "data areas" are put in its own GRID having so the posibility to set a individual datacontext.
1.) Should I now create 3 ViewModels CustomerVM,OrderVM and ProductVM?
2.) Are those 3 "data areas" seen as an own sort of separated View, although I have not put them in 3 UserControls.xaml files ???
3.) When this one UserControl is inside a TabControl`s tabpage where do I load the 3 entities related data? Inside the MainViewModel? I want to show/load that data only when the user clicks the tabheader.
No, you can do all that in the one viewmodel. The job of the viewmodel is to hold the data for the view, and if necessary transform that data so the view can consume it. There is nothing that says a viewmodel has to hold specific types of information, i.e. there are no rules that state "it may only hold customer info and not order info".
Having said that, there is also no reason why the viewmodel cannot be consumed by several different views (give them all different instances, of course) - this would show that you have a good separation of concerns between your views and viewmodel. Personally, i code my viewmodels so that they have no idea that the view exists. There is also no reason why the view has to consume everything that the viewmodel exposes, although binding a CustomerView to a CustomerOrderProductViewModel is going a little too far.
Edit: let me explain that last paragraph a little more.
Example 1: i have a new V which shows customer information, and i have an existing VM which has customer info AND order info
I would be reluctant to use this VM for this V, because while it does have the client info i need, it has too much info - i'm using the VM out of the context is was originally intended for.
Example 2: i have a VM that contains full client info, like their postal and residential address, their phone numbers, their girlfriend's names*, and a bunch of other client type info. I have a V which shows the client's name, birthday, and maybe two other properties.
I would consider using that VM for that V, this illustrates my point that the V doesn't have to show all the info contained within the VM. This concept becomes more apparent when you change the V (as in, do some maintenance and change the UI of the view, because someone has decided that they want a bunch of fields removed and now they want to represent the client's age as an image) - i can still use the same VM, and just change the V (i could use a ValueConverter to represent the age as an image, thus avoiding a change to the VM).
At what point would i stop using the current ClientViewModel, and write a new one that was more specific to the needs of the modified ClientView?
There is no clear cut answer to that - it depends on the amount of time i have available to do the changes, the amount of time available for testing, and the trade-off in complexity between using a full blown Client object for the VM, and writing a new leaner version of the Client object while still retaining the old one.
*that should be a collection of independant objects incorporated in the client object, but just work with me here it's a made up example :)
I am building a tabbed interface for switching between various similar layers. Each layer will have a number of graphs. By dragging with the mouse the graphs can be rearranged or even moved between layers. My question is, is it best practice to register a unique mediator for each layer that keeps track of the layers content / organization, or should i keep track of it all with one central mediator.
some considerations:
the layer contents and organization will be saved(in a db) so that it can be restored when a user comes back to the app.
the layers themselves are functionally identical.
the user can add and remove layers at will.
thanks!
For this sort of use I will generally mediate each screen in a tabbed interface individually by passing in a unique identifier with the constructor of the mediator. The layers won't require different mediator classes, just different mediator instances with unique names that are easy to retrieve. I typically override getMediatorName and return NAME + uniqueId.