[openbeos] Re: Networks Preferences

  • From: Stephan Assmus <superstippi@xxxxxx>
  • To: openbeos@xxxxxxxxxxxxx
  • Date: Tue, 06 May 2008 21:15:39 +0200

Casalinuovo Dario wrote:
> hi,
> i returned from rome 1 hours ago : ), the file attached is the patch for 
> NetworkStatus but this don't work because the mime-type 
> "application/x-vnd.Haiku-Network" don't exist in the database, and when i 
> try to create the type, and then i add the network preflet as the default 
> application, filetypes says me "could not retrieve application signature" 
> i tried with another preference like keymap and work well.

Your patch is nice and I will apply it shortly. Here is one issue I will 
need to correct:

+void
+NetworkStatusView::_OpenNetworksPreferences()
+{
+       BRoster* launchNetworks = new BRoster();
+       launchNetworks->Launch("application/x-vnd.Haiku-Network");
+}

This will leak the BRoster instance. When you create instances of classes 
such as above via "new", the memory they need to store their member 
variables will be allocated in the application's heap. Whenever you use 
new, you need to follow up with a corresponding "delete". In the above 
code, it would look like this:

+void
+NetworkStatusView::_OpenNetworksPreferences()
+{
+       BRoster* launchNetworks = new BRoster();
+       launchNetworks->Launch("application/x-vnd.Haiku-Network");
+       delete launchNetworks;
+}

But much easier is allocating objects on the stack:

+void
+NetworkStatusView::_OpenNetworksPreferences()
+{
+       BRoster launchNetworks;
+       launchNetworks.Launch("application/x-vnd.Haiku-Network");
+}

Objects allocated on the stack are automatically free'd when they "go out 
of scope", in the above case when the function returns.

Besides this, BRoster is a little special. I have not looked up the BeBook 
documentation myself right now, I don't remember off hand if you are even 
supposed to create your own instances of this special class. In any case, 
there is a global instance already created for your whenever you use a 
BApplication object in your code. This is accessible via the global 
"be_roster" pointer. So the code would become this:

+void
+NetworkStatusView::_OpenNetworksPreferences()
+{
+       be_roster->Launch("application/x-vnd.Haiku-Network");
+}

I don't know if this would already fix your problem with launching the 
preflet. In any case, it is a good example for when it makes sense to 
handle the error case, like so:

+void
+NetworkStatusView::_OpenNetworksPreferences()
+{
+       status_t ret = be_roster->Launch("application/x-vnd.Haiku-Network");
+       if (ret < B_OK) {
+               BString errorMessage("Launching the Network preflet failed.\n\n"
+                       "Error: ");
+               errorMessage << strerror(ret);
+               BAlert* alert = new BAlert("launch error", 
errorMessage.String(),
+                       "Ok");
+               // asynchronous alert in order to not block replicant host
+               // application
+               alert->Go(NULL);
+       }
+}

Above, I am allocating BAlert via "new" but do not use "delete". BAlert is 
one of the rare cases where the object deletes itself. This happens because 
in BeOS, every window runs in it's own thread, and BWindow deletes itself 
when it quits the message processing thread. Similarily, you don't use 
"delete" on BWindow objects you create with "new" but instead either do 
this:

if (window->Lock())
        window->Quit();

or simply post a B_QUIT_REQUESTED message:

window->PostMessage(B_QUIT_REQUESTED);

But BAlert will take care of this itself, you should never use the object 
anymore after you called BAlert::Go(). In any case, thanks for your patch!

Best regards,
-Stephan


Other related posts: