@@ -134,6 +134,23 @@ | |||
#define CARLA_SAFE_ASSERT_CONTINUE(cond) if (cond) pass(); else { carla_assert(#cond, __FILE__, __LINE__); continue; } | |||
#define CARLA_SAFE_ASSERT_RETURN(cond, ret) if (cond) pass(); else { carla_assert(#cond, __FILE__, __LINE__); return ret; } | |||
// Define CARLA_DECLARE_NON_COPY_CLASS | |||
#ifdef CARLA_PROPER_CPP11_SUPPORT | |||
# define CARLA_DECLARE_NON_COPY_CLASS(ClassName) \ | |||
private: \ | |||
ClassName(ClassName&) = delete; \ | |||
ClassName(const ClassName&) = delete; \ | |||
ClassName& operator=(ClassName&) = delete; \ | |||
ClassName& operator=(const ClassName&) = delete; | |||
#else | |||
# define CARLA_DECLARE_NON_COPY_CLASS(ClassName) \ | |||
private: \ | |||
ClassName(ClassName&); \ | |||
ClassName(const ClassName&); \ | |||
ClassName& operator=(ClassName&); \ | |||
ClassName& operator=(const ClassName&); | |||
#endif | |||
// Define CARLA_DECLARE_NON_COPY_STRUCT | |||
#ifdef CARLA_PROPER_CPP11_SUPPORT | |||
# define CARLA_DECLARE_NON_COPY_STRUCT(StructName) \ | |||
@@ -145,6 +162,18 @@ | |||
# define CARLA_DECLARE_NON_COPY_STRUCT(StructName) | |||
#endif | |||
#ifdef CARLA_PROPER_CPP11_SUPPORT | |||
# define CARLA_PREVENT_HEAP_ALLOCATION \ | |||
private: \ | |||
static void* operator new(size_t) = delete; \ | |||
static void operator delete(void*) = delete; | |||
#else | |||
# define CARLA_PREVENT_HEAP_ALLOCATION \ | |||
private: \ | |||
static void* operator new(size_t); \ | |||
static void operator delete(void*); | |||
#endif | |||
// Define CARLA_EXPORT | |||
#ifdef BUILD_BRIDGE | |||
# define CARLA_EXPORT extern "C" | |||
@@ -35,8 +35,8 @@ public: | |||
bool isQuiting() const; | |||
private: | |||
class Private; | |||
Private* const kPrivate; | |||
class PrivateData; | |||
PrivateData* const pData; | |||
friend class Window; | |||
}; | |||
@@ -44,18 +44,14 @@ | |||
# define nullptr (0) | |||
#endif | |||
#define DGL_NAMESPACE DGL | |||
#ifndef DGL_NAMESPACE | |||
# define DGL_NAMESPACE DGL | |||
#endif | |||
#define START_NAMESPACE_DGL namespace DGL_NAMESPACE { | |||
#define END_NAMESPACE_DGL } | |||
#define USE_NAMESPACE_DGL using namespace DGL_NAMESPACE; | |||
#if DGL_OS_WINDOWS | |||
# include <windows.h> | |||
#else | |||
# include <unistd.h> | |||
#endif | |||
#if DGL_OS_MAC | |||
# include <OpenGL/glu.h> | |||
#else | |||
@@ -78,71 +74,68 @@ START_NAMESPACE_DGL | |||
// ----------------------------------------------------------------------- | |||
/* | |||
* Convenience symbols for ASCII control characters. | |||
*/ | |||
enum Char { | |||
DGL_CHAR_BACKSPACE = 0x08, | |||
DGL_CHAR_ESCAPE = 0x1B, | |||
DGL_CHAR_DELETE = 0x7F | |||
CHAR_BACKSPACE = 0x08, | |||
CHAR_ESCAPE = 0x1B, | |||
CHAR_DELETE = 0x7F | |||
}; | |||
/* | |||
* Special (non-Unicode) keyboard keys. | |||
*/ | |||
enum Key { | |||
DGL_KEY_F1 = 1, | |||
DGL_KEY_F2, | |||
DGL_KEY_F3, | |||
DGL_KEY_F4, | |||
DGL_KEY_F5, | |||
DGL_KEY_F6, | |||
DGL_KEY_F7, | |||
DGL_KEY_F8, | |||
DGL_KEY_F9, | |||
DGL_KEY_F10, | |||
DGL_KEY_F11, | |||
DGL_KEY_F12, | |||
DGL_KEY_LEFT, | |||
DGL_KEY_UP, | |||
DGL_KEY_RIGHT, | |||
DGL_KEY_DOWN, | |||
DGL_KEY_PAGE_UP, | |||
DGL_KEY_PAGE_DOWN, | |||
DGL_KEY_HOME, | |||
DGL_KEY_END, | |||
DGL_KEY_INSERT, | |||
DGL_KEY_SHIFT, | |||
DGL_KEY_CTRL, | |||
DGL_KEY_ALT, | |||
DGL_KEY_SUPER | |||
KEY_F1 = 1, | |||
KEY_F2, | |||
KEY_F3, | |||
KEY_F4, | |||
KEY_F5, | |||
KEY_F6, | |||
KEY_F7, | |||
KEY_F8, | |||
KEY_F9, | |||
KEY_F10, | |||
KEY_F11, | |||
KEY_F12, | |||
KEY_LEFT, | |||
KEY_UP, | |||
KEY_RIGHT, | |||
KEY_DOWN, | |||
KEY_PAGE_UP, | |||
KEY_PAGE_DOWN, | |||
KEY_HOME, | |||
KEY_END, | |||
KEY_INSERT, | |||
KEY_SHIFT, | |||
KEY_CTRL, | |||
KEY_ALT, | |||
KEY_SUPER | |||
}; | |||
/* | |||
* Keyboard modifier flags. | |||
*/ | |||
enum Modifier { | |||
DGL_MODIFIER_SHIFT = 1 << 0, /**< Shift key */ | |||
DGL_MODIFIER_CTRL = 1 << 1, /**< Control key */ | |||
DGL_MODIFIER_ALT = 1 << 2, /**< Alt/Option key */ | |||
DGL_MODIFIER_SUPER = 1 << 3 /**< Mod4/Command/Windows key */ | |||
MODIFIER_SHIFT = 1 << 0, /**< Shift key */ | |||
MODIFIER_CTRL = 1 << 1, /**< Control key */ | |||
MODIFIER_ALT = 1 << 2, /**< Alt/Option key */ | |||
MODIFIER_SUPER = 1 << 3 /**< Mod4/Command/Windows key */ | |||
}; | |||
// ----------------------------------------------------------------------- | |||
END_NAMESPACE_DGL | |||
static inline | |||
void dgl_sleep(unsigned int secs) | |||
{ | |||
#ifdef DGL_OS_WINDOWS | |||
Sleep(secs * 1000); | |||
#else | |||
sleep(secs); | |||
#endif | |||
} | |||
/* | |||
* Cross-platform sleep function. | |||
*/ | |||
void sleep(unsigned int secs); | |||
static inline | |||
void dgl_msleep(unsigned int msecs) | |||
{ | |||
#ifdef DGL_OS_WINDOWS | |||
Sleep(msecs); | |||
#else | |||
usleep(msecs * 1000); | |||
#endif | |||
} | |||
/* | |||
* Cross-platform msleep function. | |||
*/ | |||
void msleep(unsigned int msecs); | |||
// ----------------------------------------------------------------------- | |||
END_NAMESPACE_DGL | |||
#endif // DGL_BASE_HPP_INCLUDED |
@@ -13,6 +13,7 @@ BUILD_CXX_FLAGS += -I. | |||
OBJS = \ | |||
src/App.cpp.o \ | |||
src/Base.cpp.o \ | |||
src/Image.cpp.o \ | |||
src/ImageAboutWindow.cpp.o \ | |||
src/ImageButton.cpp.o \ | |||
@@ -24,6 +25,7 @@ OBJS = \ | |||
OBJS_posix32 = \ | |||
src/App.cpp.posix32.o \ | |||
src/Base.cpp.posix32.o \ | |||
src/Image.cpp.posix32.o \ | |||
src/ImageAboutWindow.cpp.posix32.o \ | |||
src/ImageButton.cpp.posix32.o \ | |||
@@ -35,6 +37,7 @@ OBJS_posix32 = \ | |||
OBJS_posix64 = \ | |||
src/App.cpp.posix64.o \ | |||
src/Base.cpp.posix64.o \ | |||
src/Image.cpp.posix64.o \ | |||
src/ImageAboutWindow.cpp.posix64.o \ | |||
src/ImageButton.cpp.posix64.o \ | |||
@@ -46,6 +49,7 @@ OBJS_posix64 = \ | |||
OBJS_win32 = \ | |||
src/App.cpp.win32.o \ | |||
src/Base.cpp.win32.o \ | |||
src/Image.cpp.win32.o \ | |||
src/ImageAboutWindow.cpp.win32.o \ | |||
src/ImageButton.cpp.win32.o \ | |||
@@ -57,6 +61,7 @@ OBJS_win32 = \ | |||
OBJS_win64 = \ | |||
src/App.cpp.win64.o \ | |||
src/Base.cpp.win64.o \ | |||
src/Image.cpp.win64.o \ | |||
src/ImageAboutWindow.cpp.win64.o \ | |||
src/ImageButton.cpp.win64.o \ | |||
@@ -34,14 +34,14 @@ public: | |||
{ | |||
} | |||
App* getApp() | |||
App& getApp() const | |||
{ | |||
return &fApp; | |||
return fApp; | |||
} | |||
Window* getWindow() | |||
Window& getWindow() const | |||
{ | |||
return &fWindow; | |||
return fWindow; | |||
} | |||
void exec() | |||
@@ -53,6 +53,11 @@ public: | |||
// ------------------------------------------------------------------- | |||
// helpers | |||
void setResizable(bool yesNo) | |||
{ | |||
fWindow.setResizable(yesNo); | |||
} | |||
void setSize(unsigned int width, unsigned int height) | |||
{ | |||
fWindow.setSize(width, height); | |||
@@ -19,12 +19,6 @@ | |||
#include "Geometry.hpp" | |||
#ifdef PROPER_CPP11_SUPPORT | |||
# include <cstdint> | |||
#else | |||
# include <stdint.h> | |||
#endif | |||
START_NAMESPACE_DGL | |||
// ----------------------------------------------------------------------- | |||
@@ -35,7 +29,7 @@ class Window; | |||
class Widget | |||
{ | |||
public: | |||
Widget(Window* parent); | |||
Widget(Window& parent); | |||
virtual ~Widget(); | |||
bool isVisible() const; | |||
@@ -82,7 +76,7 @@ public: | |||
protected: | |||
virtual void onDisplay(); | |||
virtual bool onKeyboard(bool press, uint32_t key); | |||
virtual bool onKeyboard(bool press, unsigned key); | |||
virtual bool onMouse(int button, bool press, int x, int y); | |||
virtual bool onMotion(int x, int y); | |||
virtual bool onScroll(float dx, float dy); | |||
@@ -91,7 +85,7 @@ protected: | |||
virtual void onClose(); | |||
private: | |||
Window* fParent; | |||
Window& fParent; | |||
bool fVisible; | |||
Rectangle<int> fArea; | |||
@@ -29,11 +29,12 @@ class Widget; | |||
class Window | |||
{ | |||
public: | |||
Window(App* app, Window* parent = nullptr); | |||
Window(App* app, intptr_t parentId); | |||
Window(App& app); | |||
Window(App& app, Window& parent); | |||
Window(App& app, intptr_t parentId); | |||
virtual ~Window(); | |||
void exec(bool lock = false); | |||
void exec(bool lockWait = false); | |||
void focus(); | |||
void idle(); | |||
void repaint(); | |||
@@ -44,8 +45,8 @@ public: | |||
void setSize(unsigned int width, unsigned int height); | |||
void setWindowTitle(const char* title); | |||
App* getApp() const; | |||
int getModifiers() const; | |||
App& getApp() const; | |||
int getModifiers() const; | |||
intptr_t getWindowId() const; | |||
void addWidget(Widget* widget); | |||
@@ -56,8 +57,8 @@ public: | |||
void close(); | |||
private: | |||
class Private; | |||
Private* const kPrivate; | |||
class PrivateData; | |||
PrivateData* const pData; | |||
}; | |||
// ----------------------------------------------------------------------- | |||
@@ -23,18 +23,18 @@ START_NAMESPACE_DGL | |||
// ----------------------------------------------------------------------- | |||
App::App() | |||
: kPrivate(new Private) | |||
: pData(new Private()) | |||
{ | |||
} | |||
App::~App() | |||
{ | |||
delete kPrivate; | |||
delete pData; | |||
} | |||
void App::idle() | |||
{ | |||
for (std::list<Window*>::iterator it = kPrivate->fWindows.begin(); it != kPrivate->fWindows.end(); ++it) | |||
for (std::list<Window*>::iterator it = pData->fWindows.begin(); it != pData->fWindows.end(); ++it) | |||
{ | |||
Window* const window(*it); | |||
window->idle(); | |||
@@ -43,18 +43,18 @@ void App::idle() | |||
void App::exec() | |||
{ | |||
while (kPrivate->fDoLoop) | |||
while (pData->fDoLoop) | |||
{ | |||
idle(); | |||
dgl_msleep(10); | |||
msleep(10); | |||
} | |||
} | |||
void App::quit() | |||
{ | |||
kPrivate->fDoLoop = false; | |||
pData->fDoLoop = false; | |||
for (std::list<Window*>::iterator it = kPrivate->fWindows.begin(); it != kPrivate->fWindows.end(); ++it) | |||
for (std::list<Window*>::iterator it = pData->fWindows.begin(); it != pData->fWindows.end(); ++it) | |||
{ | |||
Window* const window(*it); | |||
window->close(); | |||
@@ -63,7 +63,7 @@ void App::quit() | |||
bool App::isQuiting() const | |||
{ | |||
return !kPrivate->fDoLoop; | |||
return !pData->fDoLoop; | |||
} | |||
// ----------------------------------------------------------------------- | |||
@@ -14,8 +14,8 @@ | |||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
*/ | |||
#ifndef APP_PRIVATE_HPP_INCLUDED | |||
#define APP_PRIVATE_HPP_INCLUDED | |||
#ifndef DGL_APP_PRIVATE_HPP_INCLUDED | |||
#define DGL_APP_PRIVATE_HPP_INCLUDED | |||
#include "../App.hpp" | |||
@@ -27,7 +27,7 @@ START_NAMESPACE_DGL | |||
class Window; | |||
class App::Private | |||
class App::PrivateData | |||
{ | |||
public: | |||
Private() | |||
@@ -41,13 +41,13 @@ public: | |||
fWindows.clear(); | |||
} | |||
void addWindow(Window* window) | |||
void addWindow(Window* const window) | |||
{ | |||
if (window != nullptr) | |||
fWindows.push_back(window); | |||
} | |||
void removeWindow(Window* window) | |||
void removeWindow(Window* const window) | |||
{ | |||
if (window != nullptr) | |||
fWindows.remove(window); | |||
@@ -55,17 +55,13 @@ public: | |||
void oneShown() | |||
{ | |||
++fVisibleWindows; | |||
if (fVisibleWindows == 1) | |||
if (++fVisibleWindows == 1) | |||
fDoLoop = true; | |||
} | |||
void oneHidden() | |||
{ | |||
--fVisibleWindows; | |||
if (fVisibleWindows == 0) | |||
if (--fVisibleWindows == 0) | |||
fDoLoop = false; | |||
} | |||
@@ -82,4 +78,4 @@ private: | |||
END_NAMESPACE_DGL | |||
#endif // APP_PRIVATE_HPP_INCLUDED | |||
#endif // DGL_APP_PRIVATE_HPP_INCLUDED |
@@ -20,23 +20,27 @@ | |||
#include <cassert> | |||
#ifdef PROPER_CPP11_SUPPORT | |||
# include <cstdint> | |||
#else | |||
# include <stdint.h> | |||
#endif | |||
START_NAMESPACE_DGL | |||
// ----------------------------------------------------------------------- | |||
// Widget | |||
Widget::Widget(Window* parent) | |||
Widget::Widget(Window& parent) | |||
: fParent(parent), | |||
fVisible(true) | |||
{ | |||
assert(parent != nullptr); | |||
parent->addWidget(this); | |||
parent.addWidget(this); | |||
} | |||
Widget::~Widget() | |||
{ | |||
fParent->removeWidget(this); | |||
fParent.removeWidget(this); | |||
} | |||
bool Widget::isVisible() const | |||
@@ -50,7 +54,7 @@ void Widget::setVisible(bool yesNo) | |||
return; | |||
fVisible = yesNo; | |||
fParent->repaint(); | |||
fParent.repaint(); | |||
} | |||
int Widget::getX() const | |||
@@ -133,7 +137,7 @@ void Widget::setWidth(int width) | |||
return; | |||
fArea.setWidth(width); | |||
fParent->repaint(); | |||
fParent.repaint(); | |||
} | |||
void Widget::setHeight(int height) | |||
@@ -142,7 +146,7 @@ void Widget::setHeight(int height) | |||
return; | |||
fArea.setHeight(height); | |||
fParent->repaint(); | |||
fParent.repaint(); | |||
} | |||
void Widget::setSize(int width, int height) | |||
@@ -156,7 +160,7 @@ void Widget::setSize(const Size<int>& size) | |||
return; | |||
fArea.setSize(size); | |||
fParent->repaint(); | |||
fParent.repaint(); | |||
} | |||
const Rectangle<int>& Widget::getArea() const | |||
@@ -166,29 +170,29 @@ const Rectangle<int>& Widget::getArea() const | |||
int Widget::getModifiers() | |||
{ | |||
return fParent->getModifiers(); | |||
return fParent.getModifiers(); | |||
} | |||
App* Widget::getApp() const | |||
App& Widget::getApp() const | |||
{ | |||
return fParent->getApp(); | |||
return fParent.getApp(); | |||
} | |||
Window* Widget::getParent() const | |||
Window& Widget::getParent() const | |||
{ | |||
return fParent; | |||
} | |||
void Widget::repaint() | |||
{ | |||
fParent->repaint(); | |||
fParent.repaint(); | |||
} | |||
void Widget::onDisplay() | |||
{ | |||
} | |||
bool Widget::onKeyboard(bool, uint32_t) | |||
bool Widget::onKeyboard(bool, unsigned) | |||
{ | |||
return false; | |||
} | |||
@@ -50,10 +50,10 @@ Window* dgl_lastUiParent = nullptr; | |||
// ----------------------------------------------------------------------- | |||
// Window Private | |||
class Window::Private | |||
class Window::PrivateData | |||
{ | |||
public: | |||
Private(Window* self, App* app, App::Private* appPriv, Private* parent, intptr_t parentId = 0) | |||
Private(Window& self, App& app, App::PrivateData& appPriv, PrivateData& parent, intptr_t parentId = 0) | |||
: kApp(app), | |||
kAppPriv(appPriv), | |||
kSelf(self), | |||
@@ -71,6 +71,10 @@ public: | |||
#else | |||
_dummy(0) | |||
#endif | |||
{ | |||
} | |||
void setup() | |||
{ | |||
if (kView == nullptr) | |||
return; | |||
@@ -566,91 +570,97 @@ private: | |||
// ----------------------------------------------------------------------- | |||
// Window | |||
Window::Window(App* app, Window* parent) | |||
: kPrivate(new Private(this, app, app->kPrivate, (parent != nullptr) ? parent->kPrivate : nullptr)) | |||
Window::Window(App& app) | |||
: pData(new Private(this, app, app->pData, nullptr)) | |||
{ | |||
dgl_lastUiParent = this; | |||
} | |||
Window::Window(App& app, Window& parent) | |||
: pData(new Private(this, app, app->pData, parent->pData)) | |||
{ | |||
dgl_lastUiParent = this; | |||
} | |||
Window::Window(App* app, intptr_t parentId) | |||
: kPrivate(new Private(this, app, app->kPrivate, nullptr, parentId)) | |||
Window::Window(App*&app, intptr_t parentId) | |||
: pData(new Private(this, app, app->pData, nullptr, parentId)) | |||
{ | |||
dgl_lastUiParent = this; | |||
} | |||
Window::~Window() | |||
{ | |||
delete kPrivate; | |||
delete pData; | |||
} | |||
void Window::exec(bool lock) | |||
{ | |||
kPrivate->exec(lock); | |||
pData->exec(lock); | |||
} | |||
void Window::focus() | |||
{ | |||
kPrivate->focus(); | |||
pData->focus(); | |||
} | |||
void Window::idle() | |||
{ | |||
kPrivate->idle(); | |||
pData->idle(); | |||
} | |||
void Window::repaint() | |||
{ | |||
kPrivate->repaint(); | |||
pData->repaint(); | |||
} | |||
bool Window::isVisible() | |||
{ | |||
return kPrivate->isVisible(); | |||
return pData->isVisible(); | |||
} | |||
void Window::setResizable(bool yesNo) | |||
{ | |||
kPrivate->setResizable(yesNo); | |||
pData->setResizable(yesNo); | |||
} | |||
void Window::setVisible(bool yesNo) | |||
{ | |||
kPrivate->setVisible(yesNo); | |||
pData->setVisible(yesNo); | |||
} | |||
void Window::setSize(unsigned int width, unsigned int height) | |||
{ | |||
kPrivate->setSize(width, height); | |||
pData->setSize(width, height); | |||
} | |||
void Window::setWindowTitle(const char* title) | |||
{ | |||
kPrivate->setWindowTitle(title); | |||
pData->setWindowTitle(title); | |||
} | |||
App* Window::getApp() const | |||
{ | |||
return kPrivate->getApp(); | |||
return pData->getApp(); | |||
} | |||
int Window::getModifiers() const | |||
{ | |||
return kPrivate->getModifiers(); | |||
return pData->getModifiers(); | |||
} | |||
intptr_t Window::getWindowId() const | |||
{ | |||
return kPrivate->getWindowId(); | |||
return pData->getWindowId(); | |||
} | |||
void Window::addWidget(Widget* widget) | |||
{ | |||
kPrivate->addWidget(widget); | |||
pData->addWidget(widget); | |||
} | |||
void Window::removeWidget(Widget* widget) | |||
{ | |||
kPrivate->removeWidget(widget); | |||
pData->removeWidget(widget); | |||
} | |||
void Window::show() | |||
@@ -665,7 +675,7 @@ void Window::hide() | |||
void Window::close() | |||
{ | |||
kPrivate->close(); | |||
pData->close(); | |||
} | |||
// ----------------------------------------------------------------------- | |||
@@ -167,7 +167,7 @@ public: | |||
fPlugin.setProgram(realProgram); | |||
// Update parameters | |||
for (uint32_t i=0, count=fPlugin.parameterCount(); i < count; ++i) | |||
for (uint32_t i=0, count=fPlugin.getParameterCount(); i < count; ++i) | |||
{ | |||
if (fPlugin.isParameterIsOutput(i)) | |||
continue; | |||
@@ -293,9 +293,9 @@ public: | |||
} | |||
} | |||
fPlugin.run(fPortAudioIns, fPortAudioOuts, bufferSize, midiEventCount, midiEvents); | |||
fPlugin.run(fPortAudioIns, fPortAudioOuts, bufferSize, midiEvents, midiEventCount); | |||
#else | |||
fPlugin.run(fPortAudioIns, fPortAudioOuts, bufferSize, 0, nullptr); | |||
fPlugin.run(fPortAudioIns, fPortAudioOuts, bufferSize, nullptr, 0); | |||
#endif | |||
updateParameterOutputs(); | |||
@@ -631,10 +631,7 @@ public: | |||
for (unsigned long i=0; i < sLadspaDescriptor.PortCount; ++i) | |||
{ | |||
if (sLadspaDescriptor.PortNames[i] != nullptr) | |||
{ | |||
std::free((void*)sLadspaDescriptor.PortNames[i]); | |||
sLadspaDescriptor.PortNames[i] = nullptr; | |||
} | |||
} | |||
delete[] sLadspaDescriptor.PortNames; | |||
@@ -134,7 +134,6 @@ public: | |||
# endif | |||
} | |||
#else | |||
glWindow.setSize(fUI.width(), fUI.height()); | |||
glWindow.setWindowTitle(uiTitle); | |||
#endif | |||
} | |||
@@ -138,7 +138,9 @@ public: | |||
fData->sendNoteCallbackFunc = sendNoteCall; | |||
fData->uiResizeCallbackFunc = uiResizeCall; | |||
#ifndef DISTRHO_UI_OPENGL | |||
#ifdef DISTRHO_UI_OPENGL | |||
glWindow.setSize(fUi->d_getWidth(), fUi->d_getHeight()); | |||
#else | |||
assert(winId == 0); | |||
return; | |||
@@ -12,7 +12,7 @@ | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* For a full copy of the GNU General Public License see the GPL.txt file | |||
* For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||
*/ | |||
#include "CarlaString.hpp" | |||
@@ -26,8 +26,9 @@ int main() | |||
assert(str.length() == std::strlen("")); | |||
assert(str.isEmpty()); | |||
assert(str.contains("")); | |||
assert(str.contains("\0")); | |||
assert(! str.isNotEmpty()); | |||
assert(! str.contains("-")); | |||
assert(! str.contains(" ")); | |||
assert(! str.isDigit(0)); | |||
// single number | |||
@@ -1,61 +0,0 @@ | |||
/* | |||
* Carla Tests | |||
* Copyright (C) 2013 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU General Public License as | |||
* published by the Free Software Foundation; either version 2 of | |||
* the License, or any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* For a full copy of the GNU General Public License see the GPL.txt file | |||
*/ | |||
#include "dgl/Image.hpp" | |||
#include "dgl/StandaloneWindow.hpp" | |||
#include "DGL1_Artwork.hpp" | |||
USE_NAMESPACE_DGL; | |||
class MyWidget : public Widget | |||
{ | |||
public: | |||
MyWidget(StandaloneWindow* win) | |||
: Widget(win->getWindow()), | |||
fWindow(win->getWindow()) | |||
{ | |||
{ | |||
using namespace DGL1_Artwork; | |||
fImage.loadFromMemory(start_here_kxstudioData, | |||
Size<int>(start_here_kxstudioWidth, start_here_kxstudioHeight), | |||
GL_BGRA, GL_UNSIGNED_BYTE); | |||
} | |||
fWindow->setSize(fImage.getWidth(), fImage.getHeight()); | |||
fWindow->setWindowTitle("DGL Test"); | |||
} | |||
protected: | |||
void onDisplay() override | |||
{ | |||
fImage.draw(); | |||
} | |||
private: | |||
Window* const fWindow; | |||
Image fImage; | |||
}; | |||
int main() | |||
{ | |||
StandaloneWindow win; | |||
MyWidget widget(&win); | |||
win.exec(); | |||
return 0; | |||
} |
@@ -1,15 +0,0 @@ | |||
/* (Auto-generated binary data file). */ | |||
#ifndef BINARY_DGL1_ARTWORK_HPP | |||
#define BINARY_DGL1_ARTWORK_HPP | |||
namespace DGL1_Artwork | |||
{ | |||
extern const char* start_here_kxstudioData; | |||
const unsigned int start_here_kxstudioDataSize = 262144; | |||
const unsigned int start_here_kxstudioWidth = 256; | |||
const unsigned int start_here_kxstudioHeight = 256; | |||
} | |||
#endif // BINARY_DGL1_ARTWORK_HPP | |||
@@ -1,221 +0,0 @@ | |||
/* | |||
* Carla Tests | |||
* Copyright (C) 2013 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU General Public License as | |||
* published by the Free Software Foundation; either version 2 of | |||
* the License, or any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* For a full copy of the GNU General Public License see the GPL.txt file | |||
*/ | |||
#include "dgl/Image.hpp" | |||
#include "dgl/StandaloneWindow.hpp" | |||
#include "CarlaUtils.hpp" | |||
#include "NekoArtwork.hpp" | |||
// this is just a test file! | |||
#include <QtCore/QThread> | |||
USE_NAMESPACE_DGL; | |||
class NekoWidget : public Widget, | |||
QThread | |||
{ | |||
public: | |||
NekoWidget(StandaloneWindow* win) | |||
: Widget(win->getWindow()), | |||
fPos(0), | |||
fTimer(0), | |||
fTimerSpeed(20), | |||
fCurAction(kActionNone), | |||
fCurImage(&fImages.sit) | |||
{ | |||
// load images | |||
{ | |||
using namespace NekoArtwork; | |||
fImages.background.loadFromMemory(backgroundData, backgroundWidth, backgroundHeight, GL_BGR); | |||
#define JOIN(a, b) a ## b | |||
#define LOAD_IMAGE(NAME) fImages.NAME.loadFromMemory(JOIN(NAME, Data), JOIN(NAME, Width), JOIN(NAME, Height)); | |||
LOAD_IMAGE(sit) | |||
LOAD_IMAGE(tail) | |||
LOAD_IMAGE(claw1) | |||
LOAD_IMAGE(claw2) | |||
LOAD_IMAGE(scratch1) | |||
LOAD_IMAGE(scratch2) | |||
LOAD_IMAGE(run1) | |||
LOAD_IMAGE(run2) | |||
LOAD_IMAGE(run3) | |||
LOAD_IMAGE(run4) | |||
#undef JOIN | |||
#undef LOAD_IMAGE | |||
} | |||
QThread::start(); | |||
} | |||
~NekoWidget() | |||
{ | |||
hide(); | |||
QThread::quit(); | |||
QThread::wait(); | |||
} | |||
protected: | |||
void onDisplay() override | |||
{ | |||
int x = fPos+118; | |||
int y = -2; | |||
if (fCurImage == &fImages.claw1 || fCurImage == &fImages.claw2) | |||
{ | |||
x += 2; | |||
y += 12; | |||
} | |||
fImages.background.draw(); | |||
fCurImage->draw(x, y); | |||
} | |||
void idle() | |||
{ | |||
if (++fTimer % fTimerSpeed != 0) // target is 25ms | |||
return; | |||
if (fTimer == fTimerSpeed*9) | |||
{ | |||
if (fCurAction == kActionNone) | |||
fCurAction = static_cast<Action>(rand() % kActionCount); | |||
else | |||
fCurAction = kActionNone; | |||
fTimer = 0; | |||
} | |||
switch (fCurAction) | |||
{ | |||
case kActionNone: | |||
if (fCurImage == &fImages.sit) | |||
fCurImage = &fImages.tail; | |||
else | |||
fCurImage = &fImages.sit; | |||
break; | |||
case kActionClaw: | |||
if (fCurImage == &fImages.claw1) | |||
fCurImage = &fImages.claw2; | |||
else | |||
fCurImage = &fImages.claw1; | |||
break; | |||
case kActionScratch: | |||
if (fCurImage == &fImages.scratch1) | |||
fCurImage = &fImages.scratch2; | |||
else | |||
fCurImage = &fImages.scratch1; | |||
break; | |||
case kActionRunRight: | |||
if (fTimer == 0 && fPos > 20*9) | |||
{ | |||
// run the other way | |||
--fTimer; | |||
fCurAction = kActionRunLeft; | |||
idle(); | |||
break; | |||
} | |||
fPos += 20; | |||
if (fCurImage == &fImages.run1) | |||
fCurImage = &fImages.run2; | |||
else | |||
fCurImage = &fImages.run1; | |||
break; | |||
case kActionRunLeft: | |||
if (fTimer == 0 && fPos < 20*9) | |||
{ | |||
// run the other way | |||
--fTimer; | |||
fCurAction = kActionRunRight; | |||
idle(); | |||
break; | |||
} | |||
fPos -= 20; | |||
if (fCurImage == &fImages.run3) | |||
fCurImage = &fImages.run4; | |||
else | |||
fCurImage = &fImages.run3; | |||
break; | |||
case kActionCount: | |||
break; | |||
} | |||
repaint(); | |||
} | |||
void run() override | |||
{ | |||
while (isVisible()) | |||
{ | |||
idle(); | |||
carla_msleep(10); | |||
} | |||
} | |||
private: | |||
enum Action { | |||
kActionNone, // bounce tail | |||
kActionClaw, | |||
kActionScratch, | |||
kActionRunRight, | |||
kActionRunLeft, | |||
kActionCount | |||
}; | |||
struct Images { | |||
Image background; | |||
Image sit; | |||
Image tail; | |||
Image claw1; | |||
Image claw2; | |||
Image scratch1; | |||
Image scratch2; | |||
Image run1; | |||
Image run2; | |||
Image run3; | |||
Image run4; | |||
} fImages; | |||
int fPos; | |||
int fTimer; | |||
int fTimerSpeed; | |||
Action fCurAction; | |||
Image* fCurImage; | |||
}; | |||
int main() | |||
{ | |||
StandaloneWindow win; | |||
win.setSize(NekoArtwork::backgroundWidth, NekoArtwork::backgroundHeight); | |||
win.setWindowTitle("Neko Test"); | |||
NekoWidget widget(&win); | |||
win.exec(); | |||
return 0; | |||
} |
@@ -8,82 +8,71 @@ include ../Makefile.mk | |||
# -------------------------------------------------------------- | |||
BUILD_CXX_FLAGS += -I../backend -I../includes -I../modules -I../modules/distrho -I../modules/theme -I../modules/widgets -I../utils | |||
BUILD_CXX_FLAGS += -DWANT_NATIVE -DWANT_LADSPA -DWANT_DSSI -DWANT_LV2 -DWANT_VST -DWANT_FLUIDSYNTH -DWANT_LINUXSAMPLER | |||
BUILD_CXX_FLAGS += -DWANT_RTAUDIO -DWANT_OPENGL -DWANT_AUDIOFILE -DWANT_MIDIFILE -DWANT_ZYNADDSUBFX -DWANT_ZYNADDSUBFX_UI | |||
BUILD_CXX_FLAGS += -isystem /usr/include/qt4 | |||
BUILD_CXX_FLAGS += -I../backend -I../includes -I../modules -I../modules/distrho -I../utils | |||
BUILD_CXX_FLAGS += -DWANT_NATIVE -DWANT_LADSPA -DWANT_DSSI -DWANT_LV2 -DWANT_VST -DWANT_AU -DWANT_CSOUND -DWANT_FLUIDSYNTH -DWANT_LINUXSAMPLER | |||
BUILD_CXX_FLAGS += -DWANT_OPENGL -DWANT_AUDIOFILE -DWANT_MIDIFILE -DWANT_ZYNADDSUBFX -DWANT_ZYNADDSUBFX_UI | |||
BUILD_CXX_FLAGS += -isystem /usr/include/qt5 | |||
BUILD_CXX_FLAGS += -isystem /opt/kxstudio/include | |||
# BUILD_CXX_FLAGS += -isystem ../backend/engine/rtaudio-4.0.11 | |||
# BUILD_CXX_FLAGS += -I/opt/mingw32/include | |||
ANSI_CXX_FLAGS = -DBUILD_ANSI_TEST -DVESTIGE_HEADER | |||
ANSI_CXX_FLAGS += -ansi -pedantic -pedantic-errors -Wunused-parameter -Wuninitialized -Wno-vla | |||
ANSI_CXX_FLAGS += -std=c++11 -Wzero-as-null-pointer-constant | |||
# ANSI_CXX_FLAGS += -std=c++11 -Wzero-as-null-pointer-constant | |||
ANSI_CXX_FLAGS += -Wcast-qual -Wconversion -Wsign-conversion -Wlogical-op -Waggregate-return | |||
ifeq ($(MACOS),true) | |||
DGL_LIBS = -framework OpenGL -framework Cocoa | |||
else | |||
ifeq ($(WIN32),true) | |||
DGL_LIBS = -lQtCore -lopengl32 -lgdi32 -lole32 -luuid -lws2_32 | |||
DGL_LIBS = -lopengl32 -lgdi32 | |||
else | |||
DGL_LIBS = -lQtCore -lGL -lX11 | |||
DGL_LIBS = -lX11 | |||
endif | |||
endif | |||
ifeq ($(MACOS),true) | |||
TARGETS = CarlaString DGL1 DGL2 Print | |||
else | |||
TARGETS = ANSI CarlaString DGL1 DGL2 Print RtList Utils Widgets | |||
endif | |||
TARGETS = CarlaString Print RtList Utils | |||
all: $(TARGETS) RUN | |||
all: $(TARGETS) | |||
# -------------------------------------------------------------- | |||
ANSI: ANSI.cpp #../backend/standalone/CarlaStandalone.cpp.o CarlaBackendDummy.cpp.o ../modules/theme.a | |||
$(CXX) $^ $(BUILD_CXX_FLAGS) $(ANSI_CXX_FLAGS) $(LINK_FLAGS) -L/opt/kxstudio/lib -lQtCore -lQtGui -llo -o $@ | |||
$(CXX) $< $(BUILD_CXX_FLAGS) $(ANSI_CXX_FLAGS) $(LINK_FLAGS) -L/opt/kxstudio/lib -lQtCore -lQtGui -llo -o $@ | |||
CarlaString: CarlaString.cpp ../modules/utils/CarlaString.hpp | |||
$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) -o $@ | |||
CarlaString: CarlaString.cpp ../utils/CarlaString.hpp | |||
$(CXX) $< $(BUILD_CXX_FLAGS) $(LINK_FLAGS) -o $@ | |||
# valgrind ./CarlaString | |||
DGL1: DGL1.cpp DGL1_Artwork.cpp ../modules/dgl.a | |||
DGL: DGL.cpp | |||
$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) -o $@ | |||
DGL2: DGL2.cpp NekoArtwork.cpp ../modules/dgl.a | |||
$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) $(DGL_LIBS) -o $@ && $(STRIP) $@ | |||
RtList: RtList.cpp ../modules/utils/RtList.hpp ../modules/rtmempool.a | |||
$(CXX) RtList.cpp ../modules/rtmempool.a $(BUILD_CXX_FLAGS) $(LINK_FLAGS) -pthread -lpthread -o $@ | |||
Print: Print.cpp | |||
$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) -o $@ | |||
# valgrind ./Print | |||
Utils: Utils.cpp | |||
$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) -pthread -lpthread -o $@ | |||
RtList: RtList.cpp ../utils/RtList.hpp ../modules/rtmempool.a | |||
$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) -lpthread -o $@ | |||
# valgrind ./RtList | |||
Widgets: Widgets.cpp resources.cpp.o ../modules/theme.a ../modules/widgets.a | |||
$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) -lQtCore -lQtGui -o $@ | |||
RUN: $(TARGETS) | |||
./ANSI && ./CarlaString && ./RtList && ./Print && ./Utils | |||
./DGL1 && ./DGL2 | |||
Utils: Utils.cpp | |||
$(CXX) $^ $(BUILD_CXX_FLAGS) $(LINK_FLAGS) -o $@ | |||
# valgrind ./Utils | |||
# -------------------------------------------------------------- | |||
%.cpp.o: %.cpp | |||
$(CXX) $< $(BUILD_CXX_FLAGS) $(ANSI_CXX_FLAGS) -c -o $@ | |||
resources.cpp: ../../resources/resources.qrc | |||
$(RCC) $< -o resources.cpp | |||
../modules/%.a: | |||
$(MAKE) -C ../modules $* | |||
# -------------------------------------------------------------- | |||
clean: | |||
rm -f *.o resources.cpp $(TARGETS) | |||
rm -f *.o $(TARGETS) | |||
debug: | |||
$(MAKE) DEBUG=true | |||
# -------------------------------------------------------------- |
@@ -1,65 +0,0 @@ | |||
/* (Auto-generated binary data file). */ | |||
#ifndef BINARY_NEKOARTWORK_HPP | |||
#define BINARY_NEKOARTWORK_HPP | |||
namespace NekoArtwork | |||
{ | |||
extern const char* backgroundData; | |||
const unsigned int backgroundDataSize = 206064; | |||
const unsigned int backgroundWidth = 636; | |||
const unsigned int backgroundHeight = 108; | |||
extern const char* claw1Data; | |||
const unsigned int claw1DataSize = 4096; | |||
const unsigned int claw1Width = 32; | |||
const unsigned int claw1Height = 32; | |||
extern const char* claw2Data; | |||
const unsigned int claw2DataSize = 4096; | |||
const unsigned int claw2Width = 32; | |||
const unsigned int claw2Height = 32; | |||
extern const char* run1Data; | |||
const unsigned int run1DataSize = 4096; | |||
const unsigned int run1Width = 32; | |||
const unsigned int run1Height = 32; | |||
extern const char* run2Data; | |||
const unsigned int run2DataSize = 4096; | |||
const unsigned int run2Width = 32; | |||
const unsigned int run2Height = 32; | |||
extern const char* run3Data; | |||
const unsigned int run3DataSize = 4096; | |||
const unsigned int run3Width = 32; | |||
const unsigned int run3Height = 32; | |||
extern const char* run4Data; | |||
const unsigned int run4DataSize = 4096; | |||
const unsigned int run4Width = 32; | |||
const unsigned int run4Height = 32; | |||
extern const char* scratch1Data; | |||
const unsigned int scratch1DataSize = 4096; | |||
const unsigned int scratch1Width = 32; | |||
const unsigned int scratch1Height = 32; | |||
extern const char* scratch2Data; | |||
const unsigned int scratch2DataSize = 4096; | |||
const unsigned int scratch2Width = 32; | |||
const unsigned int scratch2Height = 32; | |||
extern const char* sitData; | |||
const unsigned int sitDataSize = 4096; | |||
const unsigned int sitWidth = 32; | |||
const unsigned int sitHeight = 32; | |||
extern const char* tailData; | |||
const unsigned int tailDataSize = 4096; | |||
const unsigned int tailWidth = 32; | |||
const unsigned int tailHeight = 32; | |||
} | |||
#endif // BINARY_NEKOARTWORK_HPP | |||
@@ -12,7 +12,7 @@ | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* For a full copy of the GNU General Public License see the GPL.txt file | |||
* For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||
*/ | |||
#include "CarlaUtils.hpp" | |||
@@ -12,7 +12,7 @@ | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* For a full copy of the GNU General Public License see the GPL.txt file | |||
* For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||
*/ | |||
#include "RtList.hpp" | |||
@@ -139,7 +139,7 @@ int main() | |||
assert(postRtEvents.data.count() == 4); | |||
assert(postRtEvents.dataPendingRT.count() == 0); | |||
for (auto it = postRtEvents.data.begin(); it.valid(); it.next()) | |||
for (RtList<MyData>::Itenerator it = postRtEvents.data.begin(); it.valid(); it.next()) | |||
{ | |||
MyData& my(*it); | |||
@@ -177,9 +177,7 @@ int main() | |||
if (evIns.count() > 0) | |||
{ | |||
const size_t count(evIns.count()); | |||
for (uint32_t j=0; j < count; ++j) | |||
for (uint32_t j=0, count=evIns.count(); j < count; ++j) | |||
{ | |||
const uint32_t& type(evIns.getAt(j)); | |||
@@ -12,11 +12,18 @@ | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* For a full copy of the GNU General Public License see the GPL.txt file | |||
* For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||
*/ | |||
#include "CarlaUtils.hpp" | |||
struct MyStruct { | |||
char pad[100]; | |||
int i; | |||
double d; | |||
intptr_t ptr; | |||
}; | |||
int main() | |||
{ | |||
// misc functions | |||
@@ -32,9 +39,7 @@ int main() | |||
// carla_setenv | |||
carla_setenv("THIS", "THAT"); | |||
// carla_setprocname | |||
carla_setprocname("test-proc"); | |||
assert(std::strcmp(getenv("THIS"), "THAT") == 0); | |||
// carla_strdup | |||
const char* const str1 = carla_strdup("string1"); | |||
@@ -123,12 +128,6 @@ int main() | |||
} | |||
{ | |||
struct MyStruct { | |||
char pad[100]; | |||
int i; | |||
double d; | |||
intptr_t ptr; | |||
}; | |||
MyStruct a, b, c, d; | |||
carla_zeroStruct<MyStruct>(a); | |||
carla_zeroStruct<MyStruct>(b); | |||
@@ -1,47 +0,0 @@ | |||
/* | |||
* Carla Tests | |||
* Copyright (C) 2013 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU General Public License as | |||
* published by the Free Software Foundation; either version 2 of | |||
* the License, or any later version. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* For a full copy of the GNU General Public License see the GPL.txt file | |||
*/ | |||
#include "CarlaStyle.hpp" | |||
#include "digitalpeakmeter.hpp" | |||
#include "ledbutton.hpp" | |||
#include "paramspinbox.hpp" | |||
#include "pixmapdial.hpp" | |||
#include "pixmapkeyboard.hpp" | |||
#include <QtGui/QApplication> | |||
int main(int argc, char* argv[]) | |||
{ | |||
QApplication app(argc, argv); | |||
app.setStyle(new CarlaStyle()); | |||
DigitalPeakMeter w1(nullptr); | |||
LEDButton w2(nullptr); | |||
ParamProgressBar w3(nullptr); | |||
PixmapDial w4(nullptr); | |||
PixmapKeyboard w5(nullptr); | |||
w4.setPixmap(2); | |||
w1.show(); | |||
w2.show(); | |||
w3.show(); | |||
w4.show(); | |||
w5.show(); | |||
return app.exec(); | |||
} |
@@ -1,18 +1,18 @@ | |||
/* | |||
* Carla misc utils using Juce resources | |||
* Carla misc utils based on Juce | |||
* Copyright (C) 2013 Raw Material Software Ltd. | |||
* Copyright (C) 2013 Filipe Coelho <falktx@falktx.com> | |||
* | |||
* This program is free software; you can redistribute it and/or | |||
* modify it under the terms of the GNU General Public License as | |||
* published by the Free Software Foundation; either version 2 of | |||
* the License, or any later version. | |||
* Permission to use, copy, modify, and/or distribute this software for any purpose with | |||
* or without fee is hereby granted, provided that the above copyright notice and this | |||
* permission notice appear in all copies. | |||
* | |||
* This program is distributed in the hope that it will be useful, | |||
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |||
* GNU General Public License for more details. | |||
* | |||
* For a full copy of the GNU General Public License see the doc/GPL.txt file. | |||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD | |||
* TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN | |||
* NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL | |||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER | |||
* IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN | |||
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | |||
*/ | |||
#ifndef CARLA_JUCE_UTILS_HPP_INCLUDED | |||
@@ -20,32 +20,114 @@ | |||
#include "CarlaUtils.hpp" | |||
#include "juce_core.h" | |||
#define CARLA_PREVENT_HEAP_ALLOCATION \ | |||
JUCE_PREVENT_HEAP_ALLOCATION | |||
#ifdef CARLA_PROPER_CPP11_SUPPORT | |||
# define CARLA_DECLARE_NON_COPYABLE(ClassName) \ | |||
private: \ | |||
ClassName(ClassName&) = delete; \ | |||
ClassName(const ClassName&) = delete; \ | |||
ClassName& operator=(ClassName&) = delete; \ | |||
ClassName& operator=(const ClassName&) = delete; | |||
#else | |||
# define CARLA_DECLARE_NON_COPYABLE(ClassName) \ | |||
private: \ | |||
ClassName(ClassName&); \ | |||
ClassName(const ClassName&); \ | |||
ClassName& operator=(ClassName&); \ | |||
ClassName& operator=(const ClassName&); | |||
#endif | |||
#define CARLA_LEAK_DETECTOR(ClassName) \ | |||
JUCE_LEAK_DETECTOR(ClassName) | |||
/** A good old-fashioned C macro concatenation helper. | |||
This combines two items (which may themselves be macros) into a single string, | |||
avoiding the pitfalls of the ## macro operator. | |||
*/ | |||
#define CARLA_JOIN_MACRO_HELPER(a, b) a ## b | |||
#define CARLA_JOIN_MACRO(item1, item2) CARLA_JOIN_MACRO_HELPER(item1, item2) | |||
/** This macro lets you embed a leak-detecting object inside a class.\n | |||
To use it, simply declare a CARLA_LEAK_DETECTOR(YourClassName) inside a private section | |||
of the class declaration. E.g. | |||
\code | |||
class MyClass | |||
{ | |||
public: | |||
MyClass(); | |||
void blahBlah(); | |||
private: | |||
CARLA_LEAK_DETECTOR(MyClass) | |||
}; | |||
\endcode | |||
*/ | |||
#define CARLA_LEAK_DETECTOR(ClassName) \ | |||
friend class LeakedObjectDetector<ClassName>; \ | |||
static const char* getLeakedObjectClassName() noexcept { return #ClassName; } \ | |||
LeakedObjectDetector<ClassName> CARLA_JOIN_MACRO(leakDetector, __LINE__); | |||
#define CARLA_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(ClassName) \ | |||
CARLA_DECLARE_NON_COPYABLE(ClassName) \ | |||
JUCE_LEAK_DETECTOR(ClassName) | |||
CARLA_DECLARE_NON_COPY_CLASS(ClassName) \ | |||
CARLA_LEAK_DETECTOR(ClassName) | |||
//============================================================================== | |||
/** | |||
Embedding an instance of this class inside another class can be used as a low-overhead | |||
way of detecting leaked instances. | |||
This class keeps an internal static count of the number of instances that are | |||
active, so that when the app is shutdown and the static destructors are called, | |||
it can check whether there are any left-over instances that may have been leaked. | |||
To use it, use the CARLA_LEAK_DETECTOR macro as a simple way to put one in your | |||
class declaration. | |||
*/ | |||
template <class OwnerClass> | |||
class LeakedObjectDetector | |||
{ | |||
public: | |||
//============================================================================== | |||
LeakedObjectDetector() noexcept { ++(getCounter().numObjects); } | |||
LeakedObjectDetector(const LeakedObjectDetector&) noexcept { ++(getCounter().numObjects); } | |||
~LeakedObjectDetector() | |||
{ | |||
if (--(getCounter().numObjects) < 0) | |||
{ | |||
/** If you hit this, then you've managed to delete more instances of this class than you've | |||
created.. That indicates that you're deleting some dangling pointers. | |||
Note that although this assertion will have been triggered during a destructor, it might | |||
not be this particular deletion that's at fault - the incorrect one may have happened | |||
at an earlier point in the program, and simply not been detected until now. | |||
Most errors like this are caused by using old-fashioned, non-RAII techniques for | |||
your object management. Tut, tut. Always, always use ScopedPointers, OwnedArrays, | |||
ReferenceCountedObjects, etc, and avoid the 'delete' operator at all costs! | |||
*/ | |||
carla_stderr2("*** Dangling pointer deletion! Class: '%s', Count: %i", getLeakedObjectClassName(), getCounter().numObjects); | |||
} | |||
} | |||
private: | |||
//============================================================================== | |||
class LeakCounter | |||
{ | |||
public: | |||
LeakCounter() noexcept | |||
{ | |||
numObjects = 0; | |||
} | |||
~LeakCounter() | |||
{ | |||
if (numObjects > 0) | |||
{ | |||
/** If you hit this, then you've leaked one or more objects of the type specified by | |||
the 'OwnerClass' template parameter - the name should have been printed by the line above. | |||
If you're leaking, it's probably because you're using old-fashioned, non-RAII techniques for | |||
your object management. Tut, tut. Always, always use ScopedPointers, OwnedArrays, | |||
ReferenceCountedObjects, etc, and avoid the 'delete' operator at all costs! | |||
*/ | |||
carla_stderr2("*** Leaked objects detected: %i instance(s) of class '%s'", numObjects, getLeakedObjectClassName()); | |||
} | |||
} | |||
volatile int numObjects; | |||
}; | |||
static const char* getLeakedObjectClassName() | |||
{ | |||
return OwnerClass::getLeakedObjectClassName(); | |||
} | |||
static LeakCounter& getCounter() noexcept | |||
{ | |||
static LeakCounter counter; | |||
return counter; | |||
} | |||
}; | |||
#endif // CARLA_JUCE_UTILS_HPP_INCLUDED |
@@ -334,6 +334,11 @@ public: | |||
return carla_strdup(fBuffer); | |||
} | |||
const char* getBuffer() const | |||
{ | |||
return fBuffer; | |||
} | |||
// ------------------------------------------------------------------- | |||
// public operators | |||
@@ -28,12 +28,18 @@ extern "C" { | |||
} | |||
// Declare non copyable and prevent heap allocation | |||
#define LIST_DECLARATIONS(ClassName) \ | |||
#ifdef CARLA_PROPER_CPP11_SUPPORT | |||
# define LIST_DECLARATIONS(ClassName) \ | |||
ClassName(ClassName&) = delete; \ | |||
ClassName(const ClassName&) = delete; \ | |||
ClassName& operator=(const ClassName&) = delete; \ | |||
static void* operator new(size_t) = delete; | |||
//static void operator delete(void*) = delete; // FIXME? | |||
#else | |||
# define LIST_DECLARATIONS(ClassName) \ | |||
ClassName(ClassName&); \ | |||
ClassName(const ClassName&); \ | |||
ClassName& operator=(const ClassName&); | |||
#endif | |||
typedef struct list_head k_list_head; | |||
@@ -411,17 +417,17 @@ public: | |||
} | |||
} | |||
void* allocate_atomic() | |||
void* allocate_atomic() const | |||
{ | |||
return rtsafe_memory_pool_allocate_atomic(fHandle); | |||
} | |||
void* allocate_sleepy() | |||
void* allocate_sleepy() const | |||
{ | |||
return rtsafe_memory_pool_allocate_sleepy(fHandle); | |||
} | |||
void deallocate(void* const dataPtr) | |||
void deallocate(void* const dataPtr) const | |||
{ | |||
rtsafe_memory_pool_deallocate(fHandle, dataPtr); | |||
} | |||
@@ -454,17 +460,13 @@ public: | |||
}; | |||
// ------------------------------------------------------------------- | |||
// Now the actual list code | |||
// Now the actual rt-list code | |||
RtList(Pool& memPool) | |||
: fMemPool(memPool) | |||
{ | |||
} | |||
~RtList() override | |||
{ | |||
} | |||
void append_sleepy(const T& value) | |||
{ | |||
if (typename List<T>::Data* const data = _allocate_sleepy()) | |||
@@ -547,10 +549,6 @@ public: | |||
{ | |||
} | |||
~NonRtList() override | |||
{ | |||
} | |||
private: | |||
typename List<T>::Data* _allocate() override | |||
{ | |||