I'm writing an application using C and ncurses library. My program is intensively exchanging data with some sensors (sends and receives some data). There are many sensors (up to 500). Now I want to display information about each of the sensor in the 'user-friendly' way: it has to be kinda of scrollable list with items, each of which the user can choose. My best idea now is to use ncurses 'Menus library'. The steps are following:
Create list of items (actually some array of strings, where each string contains sensor number, type and other information.
Create menu and add these items to menu
Display menu
It might sound ok, but the problem is that information (actually state) of each sensor is dynamically updated. Ok, I can implement some 'hot-button' for updating information, but it might be very very time consuming: rebuilding and redisplaying all items is not a good idea.
So how would you do this?
You basically have a view of a data source and the data source is being updated and modified and you need to signal to the viewer that a particular data item has been modified so that the viewer can update its view.
Typically what I do in a situation like this is to have an event pathway so that when the data source that is shared between the viewer, the consumer of the data, and the producer, your sensor threads, the shared data is updated and then an event message is sent to the viewer.
The event messages are usually sent using some kind of a FIFO queuing mechanism so that the viewer will receive the events in the order in which they are sent by the producer.
With an event driven windowing system such as Windows, there is usually a PostMessage() function that allows you to post a message to a particular window or to a particular thread.
So the basic window design is to accept the messages which have a message identifier indicating that the source data has been updated along with some identifier or index to indicate which of the items was updated. The Viewer would then access the storage area to pull that particular data item from the area and then use that data to update the specific item text in the view.
This is pretty much standard MVC pattern. The nasty bit is how you communicate the source data update event to the viewer.
Related
I am currently working on my first backbone.js app. The concept of events is quite familiar to me but I am in question if I should use a central event dispatcher or not. Generally I see these two approaches:
Directly wire event publishers and event receivers together. (I started with this approach.)
Use an event bus and wire publishers and receivers to this bus.
Is it favorable to use an event bus in terms of e. g. long time maintainability of the app and traceability of events?
Whether to use a central event bus or to directly wire events together should be assessed on a case by case basis. Depending on the circumstance, there are times where you will favour one over the other.
I will use a central event bus whenever I can due to the fact that the publisher and receiver are not tightly coupled. In my opinion, this makes your code more maintainable and flexible.
I find central event buses very useful when you have:
A single event publishing instance and numerous event receivers.
Many event publishing instances and a single event receiver
The benefits of the central event bus in the above cases becomes even more apparent when the event receiver instances or publisher instances are dynamic and thus being created and destroyed over the life of the Application. As an example, consider the following single page app:
The single page app must stretch to fit the browser window width.
The single page app is primarily a tabbed set of views, however the number of tabs is dynamic as they are created and destroyed by users
The contents of the tabs are all different with the exception that they have a main area of content that must be stretched to fit the available width after accounting for the width of other sibling elements
Resizing needs to occur at many different points due to the contents of tabs continually changing.
In the above case, regardless of the specific scenario, the central bus model works really well. A code example would be:
Application Level
var App = {
init: function () {
// Event to resize width of element to remaining width
App.Events.on("fitRemainingWidth:app", this.fitRemainingWidth);
},
// event pub sub for the app.
Events: _.extend({}, Backbone.Events),
// function that expands an element, or elements to the remaining width in the window.
fitRemainingWidth: function(targetEls) {
var els = $(targetEls);
_.each(els, function (e) {
var el = $(e);
var cont = el.parent();
newWidth = cont.innerWidth();
otherElements = cont.children().not(el);
otherElementsWidth = 0;
otherElements.each(function () {
otherElementsWidth += $(this).outerWidth();
});
el.width(newWidth - otherElementsWidth);
});
}
}
In your views
Whenever a something needs to be resized, you trigger the event, for example:
App.Events.trigger("fitRemainingWidth:app", this.$(".main-content"), this);
As you can see, this is really useful, because the fitRemainingWidth function can apply to anything at all and you never know which views may want to use it in the future or when it will need to be called.
So I guess I should move onto when I find not using a central event bus preferable. I am sure there are other cases, however the main one for me is when the receiver needs to be wired to a specific instance of the publisher. For example, if we continue on with the tabbed application example, lets say that the contents of each tab is a split view of a particular person's mailbox. In each split view is a list pane showing a collection of emails and a reading pane showing the content of the currently selected message in the list.
In this case we want to trigger a "selected:email" event when an email is clicked and have the appropriate reading pane bound to it so it can display the email's contents.
Say we have ten mailbox tabs open, each with their own email list pane and reading pane. That makes ten email lists and ten reading panes. If I was to use a central event bus for this scenario when I triggered a "selected:email" from one of the lists, the reading panes that are receiving these events from the event bus would need to have their own smarts to try and work out whether the selected email was something they need to display or not. It's not really desirable for each reading pane to try and work this out and there is uneccesary logic involved. Its far better for a reading pane to just receive a "selected:email" event with the email object as it's payload and just display it.
So in this scenario, its better to to make each mailbox tab view responsible for wiring the events of it's specific child view instances and their models and collections. In our example this means a specific instance of an email list view with it's collection and a specific associated instance of a reading pane view.
In summary, I am suggesting there are use cases for each and that you should try to be judicious on choosing the right approach for each circumstance that you come across. Use both and learn to see what fits in which circumstances.
Lastly, in regards to the traceability of events, you can always write a wrapper for the On and Off functions in your event bus that both calls the normal On and Off functions but also adds/removes information to a register containing which objects are bound to which events. You could use this for debugging and write to the console information about these objects so you can have a clear picture of the state of your event bus and its listeners at any point in time. I've not ever thought about doing this, but there is no reason why you couldn't ;)
Post Edit: The comment by tsiki regarding using Local Event buses is a good one. In the above example I made with many tabbed mailboxes, you could use a local event bus for each user mailbox tab view. You might want to do this if each mailbox tab view became quite complicated in its own right containing many nested child views and large amounts of events to be generated/handled.
I have a client-server VB.NET/SQL2008 application which, among other things, keeps track of people who are waiting in a queue. The records for the queue are all updated via the application but they are added/removed on different workstations.
I need to display the queue of people in a grid (could do a multi column listbox if it would add any benefit) and have it automagically update when the queue changes. I don't need it to be real-real-time but I would like the people to show up within a few seconds. I currently have a datagrid bound to the data and I have a timer which is refreshing the datagrid every few seconds. However I'm thinking there must be a better way to do it.
The one thing I don't like is how the grid flickers when it refreshes and if someone double-clicks to select a record exactly as it's refreshing it selects the first person in the list and not the one selected.
I've done some research and it seems like one option is SQL Dependency - however from what I've seen people say it's difficult to set up and get working and "fragile".
Any help is appreciated!
I've got the following problem: in our teams software you can navigate to a site (journal) which loads a individual history (journal entries). The history entries are currently shown in a grid. If you change the SelectedItem, additional data (details of the journal entry) is shown below the grid.
Now my team finds this Silverlight Timeline Control (Silverlight Documentation) pretty good for displaying historical data. I think this either.
My problem is that the only way to put data onto this timeline control is via XML files. That's not a viable solution for our project. Do you see a way to "bind" this to something like ItemsSource? The reason for this is that we have lots of "journals". And every journal you open shows a different history of journal entries. You also can add/edit/delete entries.
You can do this through ResetEvents method. Timeline control calculates event positions, so it needs all events to calculate position of any. It loads them quickly, though, so 10k of events should not be a problem. Please use timeline forum http://timeline.codeplex.com/discussions for more help.
Yes, add propery which calls reset events. This could be observable collection, subscribe to events of this collection and call reset events from there also. Makes sense?
Please am still new to MVVM, and am using it with Sivlerlight. I run into a scenario where I have a Main UserControl containing one DataGrid, Employees forexample. User can double click any datagrid record to Show the EditEmployeeWindow (non blocking) so users can at the same time edit more than one employee. The only problem I have is that (one of our requirements) that when the users click save on any Edit,New window the data has to be saved to the database directly, and with one model a Save operation will save all the changes.
So one of the solutions on my head is to create an EditorViewModel that has it's own Model (new Instance of the model) and take id of edited record. In the EditorViewModel I will load this single record freshly and would direclty save changes only to that record. Also to use MVVM-Light Messenger to send message to the MainViewModel to refresh it's data since it they'll not be the same anymore.
Please could you guide me! Am I on the right track?
Thanks in advance
It looks OK, but I strongly recommend you to store the list of editing records somewhere in the main view model to not allow multiple windows on same record. Also, as you already going to use messenger to communicate with main view model, when main v.m. will receive it's child window closed message, send message to other windows, forcing them to close, and then call refresh method on main v.m.
It actually may be a little bit tricky to identify when all windows are closed (as you do work async), there are a lot of ways to do this, but I recommend you following:
1) Track a state of the main view model (is it has opened window, waiting for all windows to close, etc)
2) When window commit operation finished notify main v.m. and remove id form the list of active records.
3) When there no more records left in the list, refresh data.
Eventually when you will have to add more logic related to popup windows, I recommend to extract popup related code to the class named something like PopupService, it should be singleton, but I strongly recommend you to get it instance through one of the IoC containers (Unity, MvvmLight one, or event MEF).
Background
WinForms application using NHibernate. Application is in MDI style and each MDI child form opens a new NHibernate session at Load which remains open for the life of the form.
Question
My application is basically an "order management" or "purchasing" system. One particular form uses a lot of "lookup" lists. Like a list of products, a list of vendors, a list of locations, a list of UnitsOfMeasurement, a list of PriceQuotes, etc.
Lots of lists, that all get loaded when the form is constructed.
Problem: I need the lookup lists, but I need the form to be a bit faster to load. The form is taking too long to perform all the lookups. How can I get better performance and keep my lookup lists?
My Thoughts
Can I load the lookup lists once and hold on to them for the life of the application, and periodically check to see if the lists are stale?
Can I load just the text description for the lists, and instead of holding a bunch of IList, IList, etc, I could hold a bunch of IList, and then when I save, perform the Gets against NHibernate to get the real object.
Is there some other approach that I just haven't thought of?
You should definitely cache slowly changing data to improve performance. How often you need to check for stale data depends on the type of data and your business, e.g. units of measure probably doesn't change as frequently as a list of products. You should also provide a method for manually refreshing lists so that the user can refresh them if something appears to be missing.
If you need the business objects in the list in order to perform a database operation, you can call ISession.Lock(obj) to lock the object into the current ISession. One thing to be aware of is that the lock doesn't automatically cascade to child objects: I think there's a mapping setting to do that or you can do it manually.
Are you sending lists of full objects to your UI? I recently worked on an app using DTO's between the data layer and the UI so I'm not sending the full object, just a description and an identifier. That could help you trim out some unneeded data. So basically when the screen loads a service call is made, nhibernate gets all of the objects I want for my list box, then the UI binds to the list. I bound my listbox display member to the description and the value member to the identifier.