OpenShot Audio Library | OpenShotAudio  0.3.1
juce_SharedResourcePointer.h
1 /*
2  ==============================================================================
3 
4  This file is part of the JUCE library.
5  Copyright (c) 2017 - ROLI Ltd.
6 
7  JUCE is an open source library subject to commercial or open-source
8  licensing.
9 
10  The code included in this file is provided under the terms of the ISC license
11  http://www.isc.org/downloads/software-support-policy/isc-license. Permission
12  To use, copy, modify, and/or distribute this software for any purpose with or
13  without fee is hereby granted provided that the above copyright notice and
14  this permission notice appear in all copies.
15 
16  JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
17  EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
18  DISCLAIMED.
19 
20  ==============================================================================
21 */
22 
23 namespace juce
24 {
25 
26 //==============================================================================
80 template <typename SharedObjectType>
82 {
83 public:
91  {
92  initialise();
93  }
94 
96  {
97  initialise();
98  }
99 
105  {
106  auto& holder = getSharedObjectHolder();
107  const SpinLock::ScopedLockType sl (holder.lock);
108 
109  if (--(holder.refCount) == 0)
110  holder.sharedInstance = nullptr;
111  }
112 
114  operator SharedObjectType*() const noexcept { return sharedObject; }
115 
117  SharedObjectType& get() const noexcept { return *sharedObject; }
118 
122  SharedObjectType& getObject() const noexcept { return *sharedObject; }
123 
125  SharedObjectType* operator->() const noexcept { return sharedObject; }
126 
128  int getReferenceCount() const noexcept { return getSharedObjectHolder().refCount; }
129 
130 private:
131  struct SharedObjectHolder
132  {
133  SpinLock lock;
134  std::unique_ptr<SharedObjectType> sharedInstance;
135  int refCount;
136  };
137 
138  static SharedObjectHolder& getSharedObjectHolder() noexcept
139  {
140  static void* holder [(sizeof (SharedObjectHolder) + sizeof(void*) - 1) / sizeof(void*)] = { nullptr };
141  return *reinterpret_cast<SharedObjectHolder*> (holder);
142  }
143 
144  SharedObjectType* sharedObject;
145 
146  void initialise()
147  {
148  auto& holder = getSharedObjectHolder();
149  const SpinLock::ScopedLockType sl (holder.lock);
150 
151  if (++(holder.refCount) == 1)
152  holder.sharedInstance.reset (new SharedObjectType());
153 
154  sharedObject = holder.sharedInstance.get();
155  }
156 
157  // There's no need to assign to a SharedResourcePointer because every
158  // instance of the class is exactly the same!
159  SharedResourcePointer& operator= (const SharedResourcePointer&) = delete;
160 
161  JUCE_LEAK_DETECTOR (SharedResourcePointer)
162 };
163 
164 } // namespace juce
SharedObjectType * operator->() const noexcept
SharedObjectType & getObject() const noexcept
SharedObjectType & get() const noexcept
GenericScopedLock< SpinLock > ScopedLockType
Definition: juce_SpinLock.h:73