gfx/2d/UserData.h

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/2d/UserData.h	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,128 @@
     1.4 +/* -*- Mode: c++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
     1.5 + * This Source Code Form is subject to the terms of the Mozilla Public
     1.6 + * License, v. 2.0. If a copy of the MPL was not distributed with this
     1.7 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
     1.8 +
     1.9 +#ifndef MOZILLA_GFX_USERDATA_H_
    1.10 +#define MOZILLA_GFX_USERDATA_H_
    1.11 +
    1.12 +#include <stdlib.h>
    1.13 +#include "Types.h"
    1.14 +#include "mozilla/Assertions.h"
    1.15 +
    1.16 +namespace mozilla {
    1.17 +namespace gfx {
    1.18 +
    1.19 +struct UserDataKey {
    1.20 +  int unused;
    1.21 +};
    1.22 +
    1.23 +/* this class is basically a clone of the user data concept from cairo */
    1.24 +class UserData
    1.25 +{
    1.26 +  typedef void (*destroyFunc)(void *data);
    1.27 +public:
    1.28 +  UserData() : count(0), entries(nullptr) {}
    1.29 +
    1.30 +  /* Attaches untyped userData associated with key. destroy is called on destruction */
    1.31 +  void Add(UserDataKey *key, void *userData, destroyFunc destroy)
    1.32 +  {
    1.33 +    for (int i=0; i<count; i++) {
    1.34 +      if (key == entries[i].key) {
    1.35 +        if (entries[i].destroy) {
    1.36 +          entries[i].destroy(entries[i].userData);
    1.37 +        }
    1.38 +        entries[i].userData = userData;
    1.39 +        entries[i].destroy = destroy;
    1.40 +        return;
    1.41 +      }
    1.42 +    }
    1.43 +
    1.44 +    // We could keep entries in a std::vector instead of managing it by hand
    1.45 +    // but that would propagate an stl dependency out which we'd rather not
    1.46 +    // do (see bug 666609). Plus, the entries array is expect to stay small
    1.47 +    // so doing a realloc everytime we add a new entry shouldn't be too costly
    1.48 +    entries = static_cast<Entry*>(realloc(entries, sizeof(Entry)*(count+1)));
    1.49 +
    1.50 +    if (!entries) {
    1.51 +      MOZ_CRASH();
    1.52 +    }
    1.53 +
    1.54 +    entries[count].key      = key;
    1.55 +    entries[count].userData = userData;
    1.56 +    entries[count].destroy  = destroy;
    1.57 +
    1.58 +    count++;
    1.59 +  }
    1.60 +
    1.61 +  /* Remove and return user data associated with key, without destroying it */
    1.62 +  void* Remove(UserDataKey *key)
    1.63 +  {
    1.64 +    for (int i=0; i<count; i++) {
    1.65 +      if (key == entries[i].key) {
    1.66 +        void *userData = entries[i].userData;
    1.67 +        // decrement before looping so entries[i+1] doesn't read past the end:
    1.68 +        --count;
    1.69 +        for (;i<count; i++) {
    1.70 +          entries[i] = entries[i+1];
    1.71 +        }
    1.72 +        return userData;
    1.73 +      }
    1.74 +    }
    1.75 +    return nullptr;
    1.76 +  }
    1.77 +
    1.78 +  /* Retrives the userData for the associated key */
    1.79 +  void *Get(UserDataKey *key) const
    1.80 +  {
    1.81 +    for (int i=0; i<count; i++) {
    1.82 +      if (key == entries[i].key) {
    1.83 +        return entries[i].userData;
    1.84 +      }
    1.85 +    }
    1.86 +    return nullptr;
    1.87 +  }
    1.88 +
    1.89 +  bool Has(UserDataKey *key)
    1.90 +  {
    1.91 +    for (int i=0; i<count; i++) {
    1.92 +      if (key == entries[i].key) {
    1.93 +        return true;
    1.94 +      }
    1.95 +    }
    1.96 +    return false;
    1.97 +  }
    1.98 +
    1.99 +  void Destroy()
   1.100 +  {
   1.101 +    for (int i=0; i<count; i++) {
   1.102 +      if (entries[i].destroy) {
   1.103 +        entries[i].destroy(entries[i].userData);
   1.104 +      }
   1.105 +    }
   1.106 +    free(entries);
   1.107 +    entries = nullptr;
   1.108 +    count = 0;
   1.109 +  }
   1.110 +
   1.111 +  ~UserData()
   1.112 +  {
   1.113 +    Destroy();
   1.114 +  }
   1.115 +
   1.116 +private:
   1.117 +  struct Entry {
   1.118 +    const UserDataKey *key;
   1.119 +    void *userData;
   1.120 +    destroyFunc destroy;
   1.121 +  };
   1.122 +
   1.123 +  int count;
   1.124 +  Entry *entries;
   1.125 +
   1.126 +};
   1.127 +
   1.128 +}
   1.129 +}
   1.130 +
   1.131 +#endif /* MOZILLA_GFX_USERDATA_H_ */

mercurial