aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/adlmidi_opl3.cpp2
-rw-r--r--src/adlmidi_private.hpp81
2 files changed, 78 insertions, 5 deletions
diff --git a/src/adlmidi_opl3.cpp b/src/adlmidi_opl3.cpp
index 3e9dcc9..66254b6 100644
--- a/src/adlmidi_opl3.cpp
+++ b/src/adlmidi_opl3.cpp
@@ -523,7 +523,7 @@ void OPL3::Reset(int emulator, unsigned long PCM_RATE)
regBD.clear();
#ifndef ADLMIDI_HW_OPL
- cardsOP2.resize(NumCards, AdlMIDI_CPtr<OPLChipBase>());
+ cardsOP2.resize(NumCards, AdlMIDI_SPtr<OPLChipBase>());
#endif
NumChannels = NumCards * 23;
diff --git a/src/adlmidi_private.hpp b/src/adlmidi_private.hpp
index f63d04b..312f462 100644
--- a/src/adlmidi_private.hpp
+++ b/src/adlmidi_private.hpp
@@ -144,9 +144,11 @@ public:
void reset(PTR *p = NULL)
{
- if(m_p)
- free(m_p);
- m_p = p;
+ if(p != m_p) {
+ if(m_p)
+ free(m_p);
+ m_p = p;
+ }
}
PTR *get()
@@ -161,6 +163,77 @@ public:
{
return m_p;
}
+private:
+ AdlMIDI_CPtr(const AdlMIDI_CPtr &);
+ AdlMIDI_CPtr &operator=(const AdlMIDI_CPtr &);
+};
+
+/*
+ Shared pointer with non-atomic counter
+ FAQ: Why not std::shared_ptr? Because of Android NDK now doesn't supports it
+*/
+template<class VALUE>
+class AdlMIDI_SPtr
+{
+ VALUE *m_p;
+ size_t *m_counter;
+public:
+ AdlMIDI_SPtr() : m_p(NULL), m_counter(NULL) {}
+ ~AdlMIDI_SPtr()
+ {
+ reset(NULL);
+ }
+
+ AdlMIDI_SPtr(const AdlMIDI_SPtr &other)
+ : m_p(other.m_p), m_counter(other.m_counter)
+ {
+ if(m_counter)
+ ++*m_counter;
+ }
+
+ AdlMIDI_SPtr &operator=(const AdlMIDI_SPtr &other)
+ {
+ reset();
+ m_p = other.m_p;
+ m_counter = other.m_counter;
+ if(m_counter)
+ ++*m_counter;
+ return *this;
+ }
+
+ void reset(VALUE *p = NULL)
+ {
+ if(p != m_p) {
+ if(m_p && --*m_counter == 0)
+ delete m_p;
+ m_p = p;
+ if(!p) {
+ if(m_counter) {
+ delete m_counter;
+ m_counter = NULL;
+ }
+ }
+ else
+ {
+ if(!m_counter)
+ m_counter = new size_t;
+ *m_counter = 1;
+ }
+ }
+ }
+
+ VALUE *get()
+ {
+ return m_p;
+ }
+ VALUE &operator*()
+ {
+ return *m_p;
+ }
+ VALUE *operator->()
+ {
+ return m_p;
+ }
};
class MIDIplay;
@@ -174,7 +247,7 @@ public:
char ____padding[4];
ADL_MIDIPlayer *_parent;
#ifndef ADLMIDI_HW_OPL
- std::vector<AdlMIDI_CPtr<OPLChipBase > > cardsOP2;
+ std::vector<AdlMIDI_SPtr<OPLChipBase > > cardsOP2;
#endif
private:
std::vector<size_t> ins; // index to adl[], cached, needed by Touch()