[haiku-commits] r34368 - haiku/trunk/src/kits/interface

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Mon, 30 Nov 2009 12:40:20 +0100 (CET)

Author: bonefish
Date: 2009-11-30 12:40:20 +0100 (Mon, 30 Nov 2009)
New Revision: 34368
Changeset: http://dev.haiku-os.org/changeset/34368/haiku

Modified:
   haiku/trunk/src/kits/interface/Shelf.cpp
Log:
Turned the loaded images map into a singleton.


Modified: haiku/trunk/src/kits/interface/Shelf.cpp
===================================================================
--- haiku/trunk/src/kits/interface/Shelf.cpp    2009-11-30 11:25:13 UTC (rev 
34367)
+++ haiku/trunk/src/kits/interface/Shelf.cpp    2009-11-30 11:40:20 UTC (rev 
34368)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2001-2009, Haiku.
+ * Copyright 2001-2009, Haiku, Inc.
  * Distributed under the terms of the MIT License.
  *
  * Authors:
@@ -12,6 +12,10 @@
 
 /*!    BShelf stores replicant views that are dropped onto it */
 
+#include <Shelf.h>
+
+#include <pthread.h>
+
 #include <AutoLock.h>
 #include <Beep.h>
 #include <Dragger.h>
@@ -24,7 +28,6 @@
 #include <Point.h>
 #include <PropertyInfo.h>
 #include <Rect.h>
-#include <Shelf.h>
 #include <String.h>
 #include <View.h>
 
@@ -39,32 +42,78 @@
 #include <utility>
 
 
+namespace {
+
 typedef std::map<BString, std::pair<image_id, int32> > LoadedImageMap;
-static LoadedImageMap  sLoadedImages;
-static BLocker                 sLoadedImageMapLocker("BShelf loaded image 
map");
 
+struct LoadedImages {
+       LoadedImageMap                  images;
+
+       LoadedImages()
+               :
+               fLock("BShelf loaded image map")
+       {
+       }
+
+       bool Lock()
+       {
+               return fLock.Lock();
+       }
+
+       void Unlock()
+       {
+               fLock.Unlock();
+       }
+
+       static LoadedImages* Default()
+       {
+               if (sDefaultInstance == NULL)
+                       pthread_once(&sDefaultInitOnce, &_InitSingleton);
+
+               return sDefaultInstance;
+       }
+
+private:
+       static void _InitSingleton()
+       {
+               sDefaultInstance = new LoadedImages;
+       }
+
+private:
+       BLocker                                 fLock;
+
+       static pthread_once_t   sDefaultInitOnce;
+       static LoadedImages*    sDefaultInstance;
+};
+
+pthread_once_t LoadedImages::sDefaultInitOnce = PTHREAD_ONCE_INIT;
+LoadedImages* LoadedImages::sDefaultInstance = NULL;
+
+}      // unnamed namespace
+
+
 static property_info sShelfPropertyList[] = {
        {
                "Replicant",
                { B_COUNT_PROPERTIES, B_CREATE_PROPERTY },
-               { B_DIRECT_SPECIFIER }, 
-               NULL, 0, 
+               { B_DIRECT_SPECIFIER },
+               NULL, 0,
        },
 
        {
                "Replicant",
                { B_DELETE_PROPERTY, B_GET_PROPERTY },
-               { B_INDEX_SPECIFIER, B_REVERSE_INDEX_SPECIFIER, 
B_NAME_SPECIFIER, B_ID_SPECIFIER }, 
-               NULL, 0, 
+               { B_INDEX_SPECIFIER, B_REVERSE_INDEX_SPECIFIER, 
B_NAME_SPECIFIER, B_ID_SPECIFIER },
+               NULL, 0,
        },
 
        {
                "Replicant",
-               {}, 
+               {},
                { B_INDEX_SPECIFIER, B_REVERSE_INDEX_SPECIFIER, 
B_NAME_SPECIFIER, B_ID_SPECIFIER },
                "... of Replicant {index | name | id} of ...", 0,
        },
-       
+
        { 0, { 0 }, { 0 }, 0, 0 }
 };
 
@@ -75,7 +124,7 @@
                { B_DIRECT_SPECIFIER },
                NULL, 0, { B_INT32_TYPE }
        },
-       
+
        {
                "Name",
                { B_GET_PROPERTY },
@@ -103,7 +152,7 @@
                { B_DIRECT_SPECIFIER },
                NULL, 0,
        },
-       
+
        { 0, { 0 }, { 0 }, 0, 0 }
 };
 
@@ -123,7 +172,7 @@
        static int32 IndexOf(BList const *list, BMessage const *msg);
        static int32 IndexOf(BList const *list, BView const *view, bool 
allowZombie);
        static int32 IndexOf(BList const *list, unsigned long id);
-       
+
        status_t Archive(BMessage *msg);
 
        BMessage*                       message;
@@ -247,7 +296,7 @@
        if (view && (view->Archive(&archive) == B_OK)) {
                msg->AddInt32("uniqueid", id);
                BPoint pos (0,0);
-               if (view) { 
+               if (view) {
                        msg->AddMessage("message", &archive);
                        pos = view->Frame().LeftTop();
                } else if (zombie_view)
@@ -364,7 +413,7 @@
 ShelfContainerViewFilter::ShelfContainerViewFilter(BShelf *shelf, BView *view)
        : BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE),
        fShelf(shelf),
-       fView(view)     
+       fView(view)
 {
 }
 
@@ -420,7 +469,7 @@
                        rect = dragger->fTarget->Frame();
                rect.OffsetTo(point);
                point = rect.LeftTop() + fShelf->AdjustReplicantBy(rect, msg);
-               
+
                if (dragger->fRelation == BDragger::TARGET_IS_PARENT)
                        dragger->fTarget->MoveTo(point);
                else if (dragger->fRelation == BDragger::TARGET_IS_CHILD)
@@ -428,7 +477,7 @@
                else {
                        //TODO: TARGET_UNKNOWN/TARGET_SIBLING
                }
-       
+
        } else {
                if (fShelf->_AddReplicant(msg, &point, fShelf->fGenCount++) == 
B_OK)
                        Looper()->DetachCurrentMessage();
@@ -445,7 +494,7 @@
        : BMessageFilter(B_ANY_DELIVERY, B_ANY_SOURCE),
        fShelf(shelf),
        fView(view)
-{              
+{
 }
 
 
@@ -616,12 +665,12 @@
                                break;
                        }
                        return BHandler::MessageReceived(msg);
-                       
-               case B_CREATE_PROPERTY: 
+
+               case B_CREATE_PROPERTY:
                {
                        BMessage replicantMsg;
                        BPoint pos;
-                       if (msg->FindMessage("data", &replicantMsg) == B_OK 
+                       if (msg->FindMessage("data", &replicantMsg) == B_OK
                                && msg->FindPoint("location", &pos) == B_OK) {
                                        err = AddReplicant(&replicantMsg, pos);
                        }
@@ -635,7 +684,7 @@
                if (err == B_BAD_SCRIPT_SYNTAX)
                        replyMsg.AddString("message", "Didn't understand the 
specifier(s)");
                else
-                       replyMsg.AddString("message", strerror(err));           
        
+                       replyMsg.AddString("message", strerror(err));
        }
 
        replyMsg.AddInt32("error", err);
@@ -689,7 +738,7 @@
        BPropertyInfo shelfPropInfo(sShelfPropertyList);
        BHandler *target = NULL;
        BView *replicant = NULL;
-       
+
        switch (shelfPropInfo.FindMatch(msg, 0, specifier, form, property)) {
                case 0:
                        target = this;
@@ -1072,7 +1121,7 @@
                        data->AddMessage("replicant", &archive);
                archive.MakeEmpty();
        }
-       
+
        return B_OK;
 }
 
@@ -1128,7 +1177,7 @@
                                replmsg = new BMessage();
                                replicant.FindPoint("position", &point);
                                replicant.FindMessage("message", replmsg);
-                               AddReplicant(replmsg, point);                   
        
+                               AddReplicant(replmsg, point);
                        }
                }
        }
@@ -1151,15 +1200,15 @@
        int32 index = replicant_data::IndexOf(&fReplicants, item->message);
 
        ReplicantDeleted(index, item->message, view);
-       
-       fReplicants.RemoveItem(item);   
 
+       fReplicants.RemoveItem(item);
+
        if (item->relation == BDragger::TARGET_IS_PARENT
-               || item->relation == BDragger::TARGET_IS_SIBLING) {             
        
-               delete view;                    
+               || item->relation == BDragger::TARGET_IS_SIBLING) {
+               delete view;
        }
        if (item->relation == BDragger::TARGET_IS_CHILD
-               || item->relation == BDragger::TARGET_IS_SIBLING) {     
+               || item->relation == BDragger::TARGET_IS_SIBLING) {
                delete item->dragger;
        }
 
@@ -1167,15 +1216,17 @@
        const char* signature = NULL;
        if (item->message->FindString("add_on", &signature) == B_OK
                && signature != NULL) {
-               AutoLock<BLocker> lock(sLoadedImageMapLocker);
+               LoadedImages* loadedImages = LoadedImages::Default();
+               AutoLock<LoadedImages> lock(loadedImages);
                if (lock.IsLocked()) {
-                       LoadedImageMap::iterator it = 
sLoadedImages.find(BString(signature));
+                       LoadedImageMap::iterator it = loadedImages->images.find(
+                               BString(signature));
 
-                       if (it != sLoadedImages.end()) {
+                       if (it != loadedImages->images.end()) {
                                (*it).second.second--;
                                if ((*it).second.second <= 0) {
                                        unload_add_on((*it).second.first);
-                                       sLoadedImages.erase(it);
+                                       loadedImages->images.erase(it);
                                }
                        }
                }
@@ -1221,8 +1272,8 @@
                const char *addOn = NULL;
 
                if (data->FindString("class", &className) == B_OK
-                       && data->FindString("add_on", &addOn) == B_OK) {        
        
-                       if (find_replicant(fReplicants, className, addOn)) {    
        
+                       && data->FindString("add_on", &addOn) == B_OK) {
+                       if (find_replicant(fReplicants, className, addOn)) {
                                printf("Replicant was rejected. Unique 
replicant already exists. class=%s, signature=%s",
                                        className, addOn);
                                return send_reply(data, B_ERROR, uniqueID);
@@ -1264,12 +1315,14 @@
        // Update use count for image
        const char* signature = NULL;
        if (data->FindString("add_on", &signature) == B_OK && signature != 
NULL) {
-               AutoLock<BLocker> lock(sLoadedImageMapLocker);
+               LoadedImages* loadedImages = LoadedImages::Default();
+               AutoLock<LoadedImages> lock(loadedImages);
                if (lock.IsLocked()) {
-                       LoadedImageMap::iterator it = 
sLoadedImages.find(BString(signature));
+                       LoadedImageMap::iterator it = loadedImages->images.find(
+                               BString(signature));
 
-                       if (it == sLoadedImages.end())
-                               sLoadedImages.insert(LoadedImageMap::value_type(
+                       if (it == loadedImages->images.end())
+                               
loadedImages->images.insert(LoadedImageMap::value_type(
                                        BString(signature), std::pair<image_id, 
int>(image, 1)));
                        else
                                (*it).second.second++;
@@ -1298,7 +1351,7 @@
        // TODO: test me -- there seems to be lots of bugs parked here!
        BView *replicant = NULL;
        _GetReplicantData(data, view, replicant, dragger, relation);
-       
+
        if (dragger != NULL)
                dragger->_SetViewToDrag(replicant);
 
@@ -1306,32 +1359,32 @@
        if (!CanAcceptReplicantView(frame, replicant, data)) {
                // the view has not been accepted
                if (relation == BDragger::TARGET_IS_PARENT
-                       || relation == BDragger::TARGET_IS_SIBLING) {           
        
-                       delete replicant;                       
+                       || relation == BDragger::TARGET_IS_SIBLING) {
+                       delete replicant;
                }
                if (relation == BDragger::TARGET_IS_CHILD
-                       || relation == BDragger::TARGET_IS_SIBLING) {   
+                       || relation == BDragger::TARGET_IS_SIBLING) {
                        delete dragger;
                }
                return NULL;
        }
 
        BPoint adjust = AdjustReplicantBy(frame, data);
-       
+
        if (dragger != NULL)
                dragger->_SetShelf(this);
 
-       // TODO: could be not correct for some relations        
+       // TODO: could be not correct for some relations
        view->MoveTo(point + adjust);
 
        // if it's a sibling or a child, we need to add the dragger
        if (relation == BDragger::TARGET_IS_SIBLING
                || relation == BDragger::TARGET_IS_CHILD)
                fContainerView->AddChild(dragger);
-       
+
        if (relation != BDragger::TARGET_IS_CHILD)
                fContainerView->AddChild(replicant);
-       
+
        replicant->AddFilter(new ReplicantViewFilter(this, replicant));
 
        return replicant;
@@ -1349,18 +1402,18 @@
                image_id draggerImage = B_ERROR;
                replicant = view;
                dragger = dynamic_cast<BDragger*>(_InstantiateObject(&widget, 
&draggerImage));
-               // Replicant is a sibling, or unknown, if there isn't a dragger 
        
-               if (dragger != NULL)                    
+               // Replicant is a sibling, or unknown, if there isn't a dragger
+               if (dragger != NULL)
                        relation = BDragger::TARGET_IS_SIBLING;
 
        } else if ((dragger = dynamic_cast<BDragger*>(view)) != NULL) {
-               // Replicant is child of the dragger                    
-               relation = BDragger::TARGET_IS_CHILD;           
-               replicant = dragger->ChildAt(0);                
+               // Replicant is child of the dragger
+               relation = BDragger::TARGET_IS_CHILD;
+               replicant = dragger->ChildAt(0);
 
        } else {
                // Replicant is parent of the dragger
-               relation = BDragger::TARGET_IS_PARENT;          
+               relation = BDragger::TARGET_IS_PARENT;
                replicant = view;
                dragger = dynamic_cast<BDragger 
*>(replicant->FindView("_dragger_"));
                        // can be NULL, the replicant could not have a dragger 
at all
@@ -1411,7 +1464,7 @@
        switch (msg->what) {
                case B_INDEX_SPECIFIER: {
                        int32 index = -1;
-                       if (msg->FindInt32("index", &index)!=B_OK) 
+                       if (msg->FindInt32("index", &index)!=B_OK)
                                break;
                        ReplicantAt(index, &replicant, &ID, &err);
                        break;
@@ -1431,7 +1484,7 @@
                                BView *view = NULL;
                                ReplicantAt(i, &view, &ID, &err);
                                if (err == B_OK) {
-                                       if (view->Name() != NULL && 
+                                       if (view->Name() != NULL &&
                                                strlen(view->Name()) == 
strlen(name) && !strcmp(view->Name(), name)) {
                                                replicant = view;
                                                break;


Other related posts:

  • » [haiku-commits] r34368 - haiku/trunk/src/kits/interface - ingo_weinhold