mirror of
https://github.com/Xahau/xahaud.git
synced 2025-12-06 17:27:52 +00:00
Beast improvements and vflib compatibility module work
* Add CallQueue vflib compatibility class * Use run instead of run_one * Merge BindableServiceQueue into CallQueue * Take BEAST_VARIADIC_MAX into account * Fix license headers as suggested by Vinnie * Remove obsolete comment * Add ManualServiceQueue * Add ManualServiceQueue to beast_vflib include * Move static unit test variables of header only classes to module cpp * Remove no longer used mutex member * _VARIADIC_MAX maxes out at 10 * Correctly apply BEAST_VARIADIC_MAX * Merge BindableServiceQueue into CallQueue * New GuiServiceQueue and its JUCE dependency * Fix leftover merge errors * Fix CallQueue unit test * Don't use bassert for better CI support
This commit is contained in:
committed by
Vinnie Falco
parent
bf87614fa6
commit
08aa415c66
@@ -107,7 +107,7 @@ extern void beast_reportFatalError (char const* message, char const* fileName, i
|
|||||||
This is only compiled in a debug build.
|
This is only compiled in a debug build.
|
||||||
@see Logger::outputDebugString
|
@see Logger::outputDebugString
|
||||||
*/
|
*/
|
||||||
#define DBG(dbgtext) { beast::String tempDbgBuf; tempDbgBuf << dbgtext; beast::Logger::outputDebugString (tempDbgBuf); }
|
#define BDBG(dbgtext) { beast::String tempDbgBuf; tempDbgBuf << dbgtext; beast::Logger::outputDebugString (tempDbgBuf); }
|
||||||
|
|
||||||
/** This will always cause an assertion failure.
|
/** This will always cause an assertion failure.
|
||||||
It is only compiled in a debug build, (unless BEAST_LOG_ASSERTIONS is enabled for your build).
|
It is only compiled in a debug build, (unless BEAST_LOG_ASSERTIONS is enabled for your build).
|
||||||
@@ -127,7 +127,7 @@ extern void beast_reportFatalError (char const* message, char const* fileName, i
|
|||||||
|
|
||||||
// If debugging is disabled, these dummy debug and assertion macros are used..
|
// If debugging is disabled, these dummy debug and assertion macros are used..
|
||||||
|
|
||||||
#define DBG(dbgtext)
|
#define BDBG(dbgtext)
|
||||||
#define bassertfalse { beast_LogCurrentAssertion }
|
#define bassertfalse { beast_LogCurrentAssertion }
|
||||||
|
|
||||||
# if BEAST_LOG_ASSERTIONS
|
# if BEAST_LOG_ASSERTIONS
|
||||||
|
|||||||
@@ -354,6 +354,7 @@ protected:
|
|||||||
|
|
||||||
void wait();
|
void wait();
|
||||||
virtual void enqueue (Item* item);
|
virtual void enqueue (Item* item);
|
||||||
|
bool empty();
|
||||||
|
|
||||||
virtual std::size_t dequeue() = 0;
|
virtual std::size_t dequeue() = 0;
|
||||||
virtual Waiter* new_waiter() = 0;
|
virtual Waiter* new_waiter() = 0;
|
||||||
|
|||||||
@@ -179,6 +179,12 @@ void ServiceQueueBase::enqueue (Item* item)
|
|||||||
waiter->signal();
|
waiter->signal();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool ServiceQueueBase::empty()
|
||||||
|
{
|
||||||
|
SharedState::Access state (m_state);
|
||||||
|
return state->handlers.empty();
|
||||||
|
}
|
||||||
|
|
||||||
// A thread can only be blocked on one ServiceQueue so we store the pointer
|
// A thread can only be blocked on one ServiceQueue so we store the pointer
|
||||||
// to which ServiceQueue it is blocked on to determine if the thread belongs
|
// to which ServiceQueue it is blocked on to determine if the thread belongs
|
||||||
// to that queue.
|
// to that queue.
|
||||||
|
|||||||
@@ -456,8 +456,8 @@ void BEAST_CALLTYPE Thread::sleep (int millisecs)
|
|||||||
|
|
||||||
void BEAST_API beast_threadEntryPoint (void*);
|
void BEAST_API beast_threadEntryPoint (void*);
|
||||||
|
|
||||||
extern "C" void* threadEntryProc (void*);
|
extern "C" void* threadEntryProcBeast (void*);
|
||||||
extern "C" void* threadEntryProc (void* userData)
|
extern "C" void* threadEntryProcBeast (void* userData)
|
||||||
{
|
{
|
||||||
BEAST_AUTORELEASEPOOL
|
BEAST_AUTORELEASEPOOL
|
||||||
{
|
{
|
||||||
@@ -482,7 +482,7 @@ void Thread::launchThread()
|
|||||||
threadHandle = 0;
|
threadHandle = 0;
|
||||||
pthread_t handle = 0;
|
pthread_t handle = 0;
|
||||||
|
|
||||||
if (pthread_create (&handle, 0, threadEntryProc, this) == 0)
|
if (pthread_create (&handle, 0, threadEntryProcBeast, this) == 0)
|
||||||
{
|
{
|
||||||
pthread_detach (handle);
|
pthread_detach (handle);
|
||||||
threadHandle = (void*) handle;
|
threadHandle = (void*) handle;
|
||||||
|
|||||||
@@ -85,7 +85,7 @@ void LeakCheckedBase::LeakCounterBase::checkForLeaks ()
|
|||||||
always use ScopedPointers, OwnedArrays, SharedObjects,
|
always use ScopedPointers, OwnedArrays, SharedObjects,
|
||||||
etc, and avoid the 'delete' operator at all costs!
|
etc, and avoid the 'delete' operator at all costs!
|
||||||
*/
|
*/
|
||||||
DBG ("Leaked objects: " << count << " of " << getClassName ());
|
BDBG ("Leaked objects: " << count << " of " << getClassName ());
|
||||||
|
|
||||||
//bassertfalse;
|
//bassertfalse;
|
||||||
}
|
}
|
||||||
@@ -115,7 +115,7 @@ void LeakCheckedBase::reportDanglingPointer (char const*)
|
|||||||
SharedObjects, etc, and avoid the 'delete' operator
|
SharedObjects, etc, and avoid the 'delete' operator
|
||||||
at all costs!
|
at all costs!
|
||||||
*/
|
*/
|
||||||
DBG ("Dangling pointer deletion: " << objectName);
|
BDBG ("Dangling pointer deletion: " << objectName);
|
||||||
|
|
||||||
bassertfalse;
|
bassertfalse;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -9,9 +9,10 @@
|
|||||||
/* Begin PBXBuildFile section */
|
/* Begin PBXBuildFile section */
|
||||||
CD0A5B3F181707F700DA0342 /* mac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD0A5B3E181707F700DA0342 /* mac.cpp */; };
|
CD0A5B3F181707F700DA0342 /* mac.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD0A5B3E181707F700DA0342 /* mac.cpp */; };
|
||||||
CD0A5B421817097800DA0342 /* BeastUnitTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD0A5B401817097800DA0342 /* BeastUnitTests.cpp */; };
|
CD0A5B421817097800DA0342 /* BeastUnitTests.cpp in Sources */ = {isa = PBXBuildFile; fileRef = CD0A5B401817097800DA0342 /* BeastUnitTests.cpp */; };
|
||||||
CD0A5B4918170DC300DA0342 /* beast.mm in Sources */ = {isa = PBXBuildFile; fileRef = CD0A5B4818170DC300DA0342 /* beast.mm */; };
|
CD0A5B4918170DC300DA0342 /* beast_modules.mm in Sources */ = {isa = PBXBuildFile; fileRef = CD0A5B4818170DC300DA0342 /* beast_modules.mm */; };
|
||||||
CD0A5B4B18170EBC00DA0342 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD0A5B4A18170EBC00DA0342 /* CoreServices.framework */; };
|
CD0A5B4B18170EBC00DA0342 /* CoreServices.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD0A5B4A18170EBC00DA0342 /* CoreServices.framework */; };
|
||||||
CD0A5B4E18170F0D00DA0342 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD0A5B4D18170F0D00DA0342 /* AppKit.framework */; };
|
CD0A5B4E18170F0D00DA0342 /* AppKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = CD0A5B4D18170F0D00DA0342 /* AppKit.framework */; };
|
||||||
|
CD1CBE68181B2D99002CCC0C /* juce_modules.mm in Sources */ = {isa = PBXBuildFile; fileRef = CD1CBE64181B2689002CCC0C /* juce_modules.mm */; };
|
||||||
/* End PBXBuildFile section */
|
/* End PBXBuildFile section */
|
||||||
|
|
||||||
/* Begin PBXCopyFilesBuildPhase section */
|
/* Begin PBXCopyFilesBuildPhase section */
|
||||||
@@ -31,13 +32,16 @@
|
|||||||
CD0A5B3E181707F700DA0342 /* mac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mac.cpp; path = ../../src/mac.cpp; sourceTree = "<group>"; };
|
CD0A5B3E181707F700DA0342 /* mac.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = mac.cpp; path = ../../src/mac.cpp; sourceTree = "<group>"; };
|
||||||
CD0A5B401817097800DA0342 /* BeastUnitTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BeastUnitTests.cpp; path = ../../src/BeastUnitTests.cpp; sourceTree = "<group>"; };
|
CD0A5B401817097800DA0342 /* BeastUnitTests.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = BeastUnitTests.cpp; path = ../../src/BeastUnitTests.cpp; sourceTree = "<group>"; };
|
||||||
CD0A5B411817097800DA0342 /* BeastUnitTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BeastUnitTests.h; path = ../../src/BeastUnitTests.h; sourceTree = "<group>"; };
|
CD0A5B411817097800DA0342 /* BeastUnitTests.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = BeastUnitTests.h; path = ../../src/BeastUnitTests.h; sourceTree = "<group>"; };
|
||||||
CD0A5B4318170A5100DA0342 /* beast.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = beast.cpp; path = ../../src/beast.cpp; sourceTree = "<group>"; };
|
CD0A5B4318170A5100DA0342 /* beast_modules.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = beast_modules.cpp; path = ../../src/beast_modules.cpp; sourceTree = "<group>"; };
|
||||||
CD0A5B4418170A5100DA0342 /* beast.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = beast.h; path = ../../src/beast.h; sourceTree = "<group>"; };
|
CD0A5B4418170A5100DA0342 /* beast_modules.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = beast_modules.h; path = ../../src/beast_modules.h; sourceTree = "<group>"; };
|
||||||
CD0A5B4818170DC300DA0342 /* beast.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = beast.mm; path = ../../src/beast.mm; sourceTree = "<group>"; };
|
CD0A5B4818170DC300DA0342 /* beast_modules.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = beast_modules.mm; path = ../../src/beast_modules.mm; sourceTree = "<group>"; };
|
||||||
CD0A5B4A18170EBC00DA0342 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; };
|
CD0A5B4A18170EBC00DA0342 /* CoreServices.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreServices.framework; path = System/Library/Frameworks/CoreServices.framework; sourceTree = SDKROOT; };
|
||||||
CD0A5B4D18170F0D00DA0342 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
|
CD0A5B4D18170F0D00DA0342 /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = System/Library/Frameworks/AppKit.framework; sourceTree = SDKROOT; };
|
||||||
CD0A5B4F181714A000DA0342 /* beast */ = {isa = PBXFileReference; lastKnownFileType = folder; name = beast; path = ../../../../beast; sourceTree = "<group>"; };
|
CD0A5B4F181714A000DA0342 /* beast */ = {isa = PBXFileReference; lastKnownFileType = folder; name = beast; path = ../../../../beast; sourceTree = "<group>"; };
|
||||||
CD0A5B50181714B800DA0342 /* modules */ = {isa = PBXFileReference; lastKnownFileType = folder; name = modules; path = ../../../../modules; sourceTree = "<group>"; };
|
CD0A5B50181714B800DA0342 /* modules */ = {isa = PBXFileReference; lastKnownFileType = folder; name = modules; path = ../../../../modules; sourceTree = "<group>"; };
|
||||||
|
CD1CBE62181B2689002CCC0C /* juce_modules.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = juce_modules.cpp; path = ../../src/juce_modules.cpp; sourceTree = "<group>"; };
|
||||||
|
CD1CBE63181B2689002CCC0C /* juce_modules.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = juce_modules.h; path = ../../src/juce_modules.h; sourceTree = "<group>"; };
|
||||||
|
CD1CBE64181B2689002CCC0C /* juce_modules.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; name = juce_modules.mm; path = ../../src/juce_modules.mm; sourceTree = "<group>"; };
|
||||||
/* End PBXFileReference section */
|
/* End PBXFileReference section */
|
||||||
|
|
||||||
/* Begin PBXFrameworksBuildPhase section */
|
/* Begin PBXFrameworksBuildPhase section */
|
||||||
@@ -58,11 +62,14 @@
|
|||||||
children = (
|
children = (
|
||||||
CD0A5B50181714B800DA0342 /* modules */,
|
CD0A5B50181714B800DA0342 /* modules */,
|
||||||
CD0A5B4F181714A000DA0342 /* beast */,
|
CD0A5B4F181714A000DA0342 /* beast */,
|
||||||
CD0A5B4818170DC300DA0342 /* beast.mm */,
|
CD0A5B4318170A5100DA0342 /* beast_modules.cpp */,
|
||||||
CD0A5B4318170A5100DA0342 /* beast.cpp */,
|
CD0A5B4418170A5100DA0342 /* beast_modules.h */,
|
||||||
CD0A5B4418170A5100DA0342 /* beast.h */,
|
CD0A5B4818170DC300DA0342 /* beast_modules.mm */,
|
||||||
CD0A5B401817097800DA0342 /* BeastUnitTests.cpp */,
|
CD0A5B401817097800DA0342 /* BeastUnitTests.cpp */,
|
||||||
CD0A5B411817097800DA0342 /* BeastUnitTests.h */,
|
CD0A5B411817097800DA0342 /* BeastUnitTests.h */,
|
||||||
|
CD1CBE62181B2689002CCC0C /* juce_modules.cpp */,
|
||||||
|
CD1CBE63181B2689002CCC0C /* juce_modules.h */,
|
||||||
|
CD1CBE64181B2689002CCC0C /* juce_modules.mm */,
|
||||||
CD0A5B3E181707F700DA0342 /* mac.cpp */,
|
CD0A5B3E181707F700DA0342 /* mac.cpp */,
|
||||||
CD0A5B4C18170EC600DA0342 /* Frameworks */,
|
CD0A5B4C18170EC600DA0342 /* Frameworks */,
|
||||||
CD0A5B331817074500DA0342 /* Products */,
|
CD0A5B331817074500DA0342 /* Products */,
|
||||||
@@ -139,7 +146,8 @@
|
|||||||
files = (
|
files = (
|
||||||
CD0A5B3F181707F700DA0342 /* mac.cpp in Sources */,
|
CD0A5B3F181707F700DA0342 /* mac.cpp in Sources */,
|
||||||
CD0A5B421817097800DA0342 /* BeastUnitTests.cpp in Sources */,
|
CD0A5B421817097800DA0342 /* BeastUnitTests.cpp in Sources */,
|
||||||
CD0A5B4918170DC300DA0342 /* beast.mm in Sources */,
|
CD1CBE68181B2D99002CCC0C /* juce_modules.mm in Sources */,
|
||||||
|
CD0A5B4918170DC300DA0342 /* beast_modules.mm in Sources */,
|
||||||
);
|
);
|
||||||
runOnlyForDeploymentPostprocessing = 0;
|
runOnlyForDeploymentPostprocessing = 0;
|
||||||
};
|
};
|
||||||
@@ -180,9 +188,10 @@
|
|||||||
HEADER_SEARCH_PATHS = (
|
HEADER_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||||
|
"$(SRCROOT)/../../src",
|
||||||
|
"$(SRCROOT)/../../../../../../../JUCE",
|
||||||
"$(SRCROOT)/../../../../config",
|
"$(SRCROOT)/../../../../config",
|
||||||
"$(SRCROOT)/../../../..",
|
"$(SRCROOT)/../../../..",
|
||||||
"$(SRCROOT)/../../../../beast",
|
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||||
ONLY_ACTIVE_ARCH = YES;
|
ONLY_ACTIVE_ARCH = YES;
|
||||||
@@ -219,9 +228,10 @@
|
|||||||
HEADER_SEARCH_PATHS = (
|
HEADER_SEARCH_PATHS = (
|
||||||
"$(inherited)",
|
"$(inherited)",
|
||||||
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
/Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/include,
|
||||||
|
"$(SRCROOT)/../../src",
|
||||||
|
"$(SRCROOT)/../../../../../../../JUCE",
|
||||||
"$(SRCROOT)/../../../../config",
|
"$(SRCROOT)/../../../../config",
|
||||||
"$(SRCROOT)/../../../..",
|
"$(SRCROOT)/../../../..",
|
||||||
"$(SRCROOT)/../../../../beast",
|
|
||||||
);
|
);
|
||||||
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
MACOSX_DEPLOYMENT_TARGET = 10.8;
|
||||||
SDKROOT = macosx;
|
SDKROOT = macosx;
|
||||||
|
|||||||
94
demos/unittests/src/AppConfig.h
Normal file
94
demos/unittests/src/AppConfig.h
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
/*
|
||||||
|
|
||||||
|
IMPORTANT! This file is auto-generated each time you save your
|
||||||
|
project - if you alter its contents, your changes may be overwritten!
|
||||||
|
|
||||||
|
There's a section below where you can add your own custom code safely, and the
|
||||||
|
Introjucer will preserve the contents of that block, but the best way to change
|
||||||
|
any of these definitions is by using the Introjucer's project settings.
|
||||||
|
|
||||||
|
Any commented-out settings will assume their default values.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef __JUCE_APPCONFIG_M70QFTRRK__
|
||||||
|
#define __JUCE_APPCONFIG_M70QFTRRK__
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
// [BEGIN_USER_CODE_SECTION]
|
||||||
|
|
||||||
|
// (You can add your own code in this section, and the Introjucer will not overwrite it)
|
||||||
|
|
||||||
|
// [END_USER_CODE_SECTION]
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
#define JUCE_MODULE_AVAILABLE_juce_core 1
|
||||||
|
//#define JUCE_MODULE_AVAILABLE_juce_cryptography 1
|
||||||
|
//#define JUCE_MODULE_AVAILABLE_juce_data_structures 1
|
||||||
|
#define JUCE_MODULE_AVAILABLE_juce_events 1
|
||||||
|
//#define JUCE_MODULE_AVAILABLE_juce_graphics 1
|
||||||
|
//#define JUCE_MODULE_AVAILABLE_juce_gui_basics 1
|
||||||
|
//#define JUCE_MODULE_AVAILABLE_juce_gui_extra 1
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
// juce_core flags:
|
||||||
|
|
||||||
|
#ifndef JUCE_FORCE_DEBUG
|
||||||
|
//#define JUCE_FORCE_DEBUG
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef JUCE_LOG_ASSERTIONS
|
||||||
|
#define JUCE_LOG_ASSERTIONS 1
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef JUCE_CHECK_MEMORY_LEAKS
|
||||||
|
//#define JUCE_CHECK_MEMORY_LEAKS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES
|
||||||
|
//#define JUCE_DONT_AUTOLINK_TO_WIN32_LIBRARIES
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef JUCE_INCLUDE_ZLIB_CODE
|
||||||
|
//#define JUCE_INCLUDE_ZLIB_CODE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
// juce_graphics flags:
|
||||||
|
|
||||||
|
#ifndef JUCE_USE_COREIMAGE_LOADER
|
||||||
|
#define JUCE_USE_COREIMAGE_LOADER 0
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef JUCE_USE_DIRECTWRITE
|
||||||
|
//#define JUCE_USE_DIRECTWRITE
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
// juce_gui_basics flags:
|
||||||
|
|
||||||
|
#ifndef JUCE_ENABLE_REPAINT_DEBUGGING
|
||||||
|
//#define JUCE_ENABLE_REPAINT_DEBUGGING
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef JUCE_USE_XSHM
|
||||||
|
//#define JUCE_USE_XSHM
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef JUCE_USE_XRENDER
|
||||||
|
//#define JUCE_USE_XRENDER
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifndef JUCE_USE_XCURSOR
|
||||||
|
//#define JUCE_USE_XCURSOR
|
||||||
|
#endif
|
||||||
|
|
||||||
|
//==============================================================================
|
||||||
|
// juce_gui_extra flags:
|
||||||
|
|
||||||
|
#ifndef JUCE_WEB_BROWSER
|
||||||
|
//#define JUCE_WEB_BROWSER
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#endif // __JUCE_APPCONFIG_M70QFTRRK__
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
#ifndef UNITTESTS_BEASTUNITTESTS_H_INCLUDED
|
#ifndef UNITTESTS_BEASTUNITTESTS_H_INCLUDED
|
||||||
#define UNITTESTS_BEASTUNITTESTS_H_INCLUDED
|
#define UNITTESTS_BEASTUNITTESTS_H_INCLUDED
|
||||||
|
|
||||||
#include "beast.h"
|
#include "beast_modules.h"
|
||||||
|
|
||||||
int runUnitTests (beast::String const& match, beast::String const& format);
|
int runUnitTests (beast::String const& match, beast::String const& format);
|
||||||
|
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
*/
|
*/
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
#include "beast.h"
|
#include "beast_modules.h"
|
||||||
|
|
||||||
#include "modules/beast_core/beast_core.cpp"
|
#include "modules/beast_core/beast_core.cpp"
|
||||||
#include "modules/beast_vflib/beast_vflib.cpp"
|
#include "modules/beast_vflib/beast_vflib.cpp"
|
||||||
@@ -17,8 +17,8 @@
|
|||||||
*/
|
*/
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
#ifndef UNITTESTS_BEAST_H_INCLUDED
|
#ifndef UNITTESTS_BEASTMODULES_H_INCLUDED
|
||||||
#define UNITTESTS_BEAST_H_INCLUDED
|
#define UNITTESTS_BEASTMODULES_H_INCLUDED
|
||||||
|
|
||||||
#include "BeastConfig.h"
|
#include "BeastConfig.h"
|
||||||
|
|
||||||
20
demos/unittests/src/beast_modules.mm
Normal file
20
demos/unittests/src/beast_modules.mm
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||||
|
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#include "beast_modules.cpp"
|
||||||
21
demos/unittests/src/juce_modules.cpp
Normal file
21
demos/unittests/src/juce_modules.cpp
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||||
|
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
|
#include "modules/juce_core/juce_core.cpp"
|
||||||
|
#include "modules/juce_events/juce_events.cpp"
|
||||||
28
demos/unittests/src/juce_modules.h
Normal file
28
demos/unittests/src/juce_modules.h
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||||
|
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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 UNITTESTS_JUCEMODULES_H_INCLUDED
|
||||||
|
#define UNITTESTS_JUCEMODULES_H_INCLUDED
|
||||||
|
|
||||||
|
#include "AppConfig.h"
|
||||||
|
|
||||||
|
#include "modules/juce_core/juce_core.h"
|
||||||
|
#include "modules/juce_events/juce_events.h"
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -17,4 +17,4 @@
|
|||||||
*/
|
*/
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
#include "beast.cpp"
|
#include "juce_modules.cpp"
|
||||||
@@ -17,9 +17,13 @@
|
|||||||
*/
|
*/
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|
||||||
|
#include "juce_modules.h"
|
||||||
|
#include "beast_modules.h"
|
||||||
|
|
||||||
#include "BeastUnitTests.h"
|
#include "BeastUnitTests.h"
|
||||||
|
|
||||||
int main(int argc, const char * argv[])
|
int main(int argc, const char * argv[])
|
||||||
{
|
{
|
||||||
|
juce::ScopedJuceInitialiser_GUI juce;
|
||||||
return runUnitTests("", "text");
|
return runUnitTests("", "text");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,22 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||||
|
Copyright Patrick Dehne <patrick@mysonicweb.de> (www.sonicweb-radio.de)
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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.
|
||||||
|
*/
|
||||||
|
//==============================================================================
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <tchar.h>
|
#include <tchar.h>
|
||||||
|
|
||||||
|
|||||||
@@ -199,7 +199,7 @@ void PropertySet::restoreFromXml (const XmlElement& xml)
|
|||||||
const ScopedLock sl (lock);
|
const ScopedLock sl (lock);
|
||||||
clear();
|
clear();
|
||||||
|
|
||||||
forEachXmlChildElementWithTagName (xml, e, "VALUE")
|
beast_forEachXmlChildElementWithTagName (xml, e, "VALUE")
|
||||||
{
|
{
|
||||||
if (e->hasAttribute ("name")
|
if (e->hasAttribute ("name")
|
||||||
&& e->hasAttribute ("val"))
|
&& e->hasAttribute ("val"))
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ FileLogger::~FileLogger() {}
|
|||||||
void FileLogger::logMessage (const String& message)
|
void FileLogger::logMessage (const String& message)
|
||||||
{
|
{
|
||||||
const ScopedLock sl (logLock);
|
const ScopedLock sl (logLock);
|
||||||
DBG (message);
|
BDBG (message);
|
||||||
FileOutputStream out (logFile, 256);
|
FileOutputStream out (logFile, 256);
|
||||||
out << message << newLine;
|
out << message << newLine;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ void logAssertion (const char* const filename, const int lineNum) noexcept
|
|||||||
#if BEAST_LOG_ASSERTIONS
|
#if BEAST_LOG_ASSERTIONS
|
||||||
Logger::writeToLog (m);
|
Logger::writeToLog (m);
|
||||||
#else
|
#else
|
||||||
DBG (m);
|
BDBG (m);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ struct Expression::Helpers
|
|||||||
public:
|
public:
|
||||||
EvaluationError (const String& desc) : description (desc)
|
EvaluationError (const String& desc) : description (desc)
|
||||||
{
|
{
|
||||||
DBG ("Expression::EvaluationError: " + description);
|
BDBG ("Expression::EvaluationError: " + description);
|
||||||
}
|
}
|
||||||
|
|
||||||
String description;
|
String description;
|
||||||
@@ -1086,7 +1086,7 @@ SharedPtr<Expression::Term> Expression::Term::negated()
|
|||||||
Expression::ParseError::ParseError (const String& message)
|
Expression::ParseError::ParseError (const String& message)
|
||||||
: description (message)
|
: description (message)
|
||||||
{
|
{
|
||||||
DBG ("Expression::ParseError: " + message);
|
BDBG ("Expression::ParseError: " + message);
|
||||||
}
|
}
|
||||||
|
|
||||||
//==============================================================================
|
//==============================================================================
|
||||||
|
|||||||
@@ -47,10 +47,10 @@
|
|||||||
# ifdef _VARIADIC_MAX
|
# ifdef _VARIADIC_MAX
|
||||||
# define BEAST_VARIADIC_MAX _VARIADIC_MAX
|
# define BEAST_VARIADIC_MAX _VARIADIC_MAX
|
||||||
# else
|
# else
|
||||||
# define BEAST_VARIADIC_MAX 9
|
# define BEAST_VARIADIC_MAX 10
|
||||||
# endif
|
# endif
|
||||||
#else
|
#else
|
||||||
# define BEAST_VARIADIC_MAX 9
|
# define BEAST_VARIADIC_MAX 10
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
|
|
||||||
@see forEachXmlChildElementWithTagName
|
@see forEachXmlChildElementWithTagName
|
||||||
*/
|
*/
|
||||||
#define forEachXmlChildElement(parentXmlElement, childElementVariableName) \
|
#define beast_forEachXmlChildElement(parentXmlElement, childElementVariableName) \
|
||||||
\
|
\
|
||||||
for (beast::XmlElement* childElementVariableName = (parentXmlElement).getFirstChildElement(); \
|
for (beast::XmlElement* childElementVariableName = (parentXmlElement).getFirstChildElement(); \
|
||||||
childElementVariableName != nullptr; \
|
childElementVariableName != nullptr; \
|
||||||
@@ -72,7 +72,7 @@
|
|||||||
|
|
||||||
@see forEachXmlChildElement
|
@see forEachXmlChildElement
|
||||||
*/
|
*/
|
||||||
#define forEachXmlChildElementWithTagName(parentXmlElement, childElementVariableName, requiredTagName) \
|
#define beast_forEachXmlChildElementWithTagName(parentXmlElement, childElementVariableName, requiredTagName) \
|
||||||
\
|
\
|
||||||
for (beast::XmlElement* childElementVariableName = (parentXmlElement).getChildByName (requiredTagName); \
|
for (beast::XmlElement* childElementVariableName = (parentXmlElement).getChildByName (requiredTagName); \
|
||||||
childElementVariableName != nullptr; \
|
childElementVariableName != nullptr; \
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/*
|
/*
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
Copyright Patrick Dehne <patrick@mysonicweb.de> (www.sonicweb-radio.de)
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
@@ -20,3 +20,9 @@
|
|||||||
#include "beast_vflib.h"
|
#include "beast_vflib.h"
|
||||||
|
|
||||||
#include "threads/ThreadWithServiceQueue.cpp"
|
#include "threads/ThreadWithServiceQueue.cpp"
|
||||||
|
|
||||||
|
/** Unit tests for header only classes
|
||||||
|
*/
|
||||||
|
|
||||||
|
static beast::detail::CallQueueTests callQueueTests;
|
||||||
|
static beast::detail::ManualServiceQueueTests manualServiceQueueTests;
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
/*
|
/*
|
||||||
This file is part of BeastUtils: https://github.com/pdehne/BeastUtils
|
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||||
Copyright 2013, Patrick Dehne <patrick@sonicweb.de>
|
Copyright Patrick Dehne <patrick@mysonicweb.de> (www.sonicweb-radio.de)
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
@@ -21,7 +21,9 @@
|
|||||||
#define BEAST_VFLIB_H_INCLUDED
|
#define BEAST_VFLIB_H_INCLUDED
|
||||||
|
|
||||||
#include "functor/BindHelper.h"
|
#include "functor/BindHelper.h"
|
||||||
#include "threads/BindableServiceQueue.h"
|
#include "threads/CallQueue.h"
|
||||||
#include "threads/ThreadWithServiceQueue.h"
|
#include "threads/ThreadWithServiceQueue.h"
|
||||||
|
#include "threads/ManualServiceQueue.h"
|
||||||
|
#include "threads/GuiServiceQueue.h"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
/*
|
/*
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||||
|
Copyright Patrick Dehne <patrick@mysonicweb.de> (www.sonicweb-radio.de)
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
@@ -38,6 +39,7 @@ private:
|
|||||||
UnaryFunction m_f;
|
UnaryFunction m_f;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
#if BEAST_VARIADIC_MAX >= 1
|
||||||
template <typename Arg>
|
template <typename Arg>
|
||||||
explicit BindHelper (Arg& arg)
|
explicit BindHelper (Arg& arg)
|
||||||
: m_f (arg)
|
: m_f (arg)
|
||||||
@@ -51,26 +53,61 @@ public:
|
|||||||
template <typename F>
|
template <typename F>
|
||||||
void operator() (F const& f) const
|
void operator() (F const& f) const
|
||||||
{ m_f (f); }
|
{ m_f (f); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BEAST_VARIADIC_MAX >= 2
|
||||||
template <typename F, class P1>
|
template <typename F, class P1>
|
||||||
void operator() (F const& f, P1 const& p1) const
|
void operator() (F const& f, P1 const& p1) const
|
||||||
{ m_f (bind (f, p1)); }
|
{ m_f (bind (f, p1)); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BEAST_VARIADIC_MAX >= 3
|
||||||
template <typename F, class P1, class P2>
|
template <typename F, class P1, class P2>
|
||||||
void operator() (F const& f, P1 const& p1, P2 const& p2) const
|
void operator() (F const& f, P1 const& p1, P2 const& p2) const
|
||||||
{ m_f (bind (f, p1, p2)); }
|
{ m_f (bind (f, p1, p2)); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BEAST_VARIADIC_MAX >= 4
|
||||||
template <typename F, class P1, class P2, class P3>
|
template <typename F, class P1, class P2, class P3>
|
||||||
void operator() (F const& f, P1 const& p1, P2 const& p2, P3 const& p3) const
|
void operator() (F const& f, P1 const& p1, P2 const& p2, P3 const& p3) const
|
||||||
{ m_f (bind (f, p1, p2, p3)); }
|
{ m_f (bind (f, p1, p2, p3)); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BEAST_VARIADIC_MAX >= 5
|
||||||
template <typename F, class P1, class P2, class P3, class P4>
|
template <typename F, class P1, class P2, class P3, class P4>
|
||||||
void operator() (F const& f, P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4) const
|
void operator() (F const& f, P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4) const
|
||||||
{ m_f (bind (f, p1, p2, p3, p4)); }
|
{ m_f (bind (f, p1, p2, p3, p4)); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BEAST_VARIADIC_MAX >= 6
|
||||||
template <typename F, class P1, class P2, class P3, class P4, class P5>
|
template <typename F, class P1, class P2, class P3, class P4, class P5>
|
||||||
void operator() (F const& f, P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4, P5 const& p5) const
|
void operator() (F const& f, P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4, P5 const& p5) const
|
||||||
{ m_f (bind (f, p1, p2, p3, p4, p5)); }
|
{ m_f (bind (f, p1, p2, p3, p4, p5)); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BEAST_VARIADIC_MAX >= 7
|
||||||
|
template <typename F, class P1, class P2, class P3, class P4, class P5, class P6>
|
||||||
|
void operator() (F const& f, P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4, P5 const& p5, P6 const& p6) const
|
||||||
|
{ m_f (bind (f, p1, p2, p3, p4, p5, p6)); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BEAST_VARIADIC_MAX >= 8
|
||||||
|
template <typename F, class P1, class P2, class P3, class P4, class P5, class P6, class P7>
|
||||||
|
void operator() (F const& f, P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4, P5 const& p5, P6 const& p6, P7 const& p7) const
|
||||||
|
{ m_f (bind (f, p1, p2, p3, p4, p5, p6, p7)); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BEAST_VARIADIC_MAX >= 9
|
||||||
|
template <typename F, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8>
|
||||||
|
void operator() (F const& f, P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4, P5 const& p5, P6 const& p6, P7 const& p7, P8 const& p8) const
|
||||||
|
{ m_f (bind (f, p1, p2, p3, p4, p5, p6, p7, p8)); }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BEAST_VARIADIC_MAX >= 10
|
||||||
|
template <typename F, class P1, class P2, class P3, class P4, class P5, class P6, class P7, class P8, class P9>
|
||||||
|
void operator() (F const& f, P1 const& p1, P2 const& p2, P3 const& p3, P4 const& p4, P5 const& p5, P6 const& p6, P7 const& p7, P8 const& p8, P9 const& p9) const
|
||||||
|
{ m_f (bind (f, p1, p2, p3, p4, p5, p6, p7, p8, p9)); }
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,71 +0,0 @@
|
|||||||
//------------------------------------------------------------------------------
|
|
||||||
/*
|
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
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 BEAST_VFLIB_BINDABLESERVICEQUEUETYPE_H_INCLUDED
|
|
||||||
#define BEAST_VFLIB_BINDABLESERVICEQUEUETYPE_H_INCLUDED
|
|
||||||
|
|
||||||
#include "beast/Threads.h"
|
|
||||||
#include "../functor/BindHelper.h"
|
|
||||||
|
|
||||||
namespace beast {
|
|
||||||
|
|
||||||
template <class Allocator = std::allocator <char> >
|
|
||||||
class BindableServiceQueueType
|
|
||||||
: public ServiceQueueType <Allocator>
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
explicit BindableServiceQueueType (int expectedConcurrency = 1,
|
|
||||||
Allocator alloc = Allocator())
|
|
||||||
: ServiceQueueType<Allocator>(expectedConcurrency, alloc)
|
|
||||||
, queue(*this)
|
|
||||||
, call(*this)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
struct BindHelperPost
|
|
||||||
{
|
|
||||||
BindableServiceQueueType<Allocator>& m_queue;
|
|
||||||
explicit BindHelperPost (BindableServiceQueueType<Allocator>& queue)
|
|
||||||
: m_queue (queue)
|
|
||||||
{ }
|
|
||||||
template <typename F>
|
|
||||||
void operator() (F const& f) const
|
|
||||||
{ m_queue.post ( F (f) ); }
|
|
||||||
};
|
|
||||||
|
|
||||||
struct BindHelperDispatch
|
|
||||||
{
|
|
||||||
BindableServiceQueueType<Allocator>& m_queue;
|
|
||||||
explicit BindHelperDispatch (BindableServiceQueueType<Allocator>& queue)
|
|
||||||
: m_queue (queue)
|
|
||||||
{ }
|
|
||||||
template <typename F>
|
|
||||||
void operator() (F const& f) const
|
|
||||||
{ m_queue.dispatch ( F (f) ); }
|
|
||||||
};
|
|
||||||
|
|
||||||
BindHelper <BindHelperPost> const queue;
|
|
||||||
BindHelper <BindHelperDispatch> const call;
|
|
||||||
};
|
|
||||||
|
|
||||||
typedef BindableServiceQueueType <std::allocator <char> > BindableServiceQueue;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
382
modules/beast_vflib/threads/CallQueue.h
Normal file
382
modules/beast_vflib/threads/CallQueue.h
Normal file
@@ -0,0 +1,382 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||||
|
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||||
|
Copyright Patrick Dehne <patrick@mysonicweb.de> (www.sonicweb-radio.de)
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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 BEAST_VFLIB_CALLQUEUE_H_INCLUDED
|
||||||
|
#define BEAST_VFLIB_CALLQUEUE_H_INCLUDED
|
||||||
|
|
||||||
|
#include "beast/Threads.h"
|
||||||
|
#include "../functor/BindHelper.h"
|
||||||
|
|
||||||
|
namespace beast {
|
||||||
|
|
||||||
|
template <class Allocator = std::allocator <char> >
|
||||||
|
class CallQueueType
|
||||||
|
: public ServiceQueueType <Allocator>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit CallQueueType (const String& name,
|
||||||
|
int expectedConcurrency = 1,
|
||||||
|
Allocator alloc = Allocator())
|
||||||
|
: ServiceQueueType<Allocator>(expectedConcurrency, alloc)
|
||||||
|
, m_name (name)
|
||||||
|
, queue(*this)
|
||||||
|
, call(*this)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
~CallQueueType ()
|
||||||
|
{
|
||||||
|
// Someone forget to close the queue.
|
||||||
|
bassert (m_closed.isSignaled ());
|
||||||
|
|
||||||
|
// Can't destroy queue with unprocessed calls.
|
||||||
|
bassert (ServiceQueueBase::empty ());
|
||||||
|
}
|
||||||
|
|
||||||
|
void enqueue (ServiceQueueBase::Item* item)
|
||||||
|
{
|
||||||
|
// If this goes off someone added calls
|
||||||
|
// after the queue has been closed.
|
||||||
|
bassert (!m_closed.isSignaled ());
|
||||||
|
|
||||||
|
ServiceQueueType <Allocator>::enqueue (item);
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Close the queue.
|
||||||
|
|
||||||
|
Functors may not be added after this routine is called. This is used for
|
||||||
|
diagnostics, to track down spurious calls during application shutdown
|
||||||
|
or exit. Derived classes may call this if the appropriate time is known.
|
||||||
|
|
||||||
|
The queue is synchronized after it is closed.
|
||||||
|
Can still have pending calls, just can't put new ones in.
|
||||||
|
*/
|
||||||
|
virtual void close ()
|
||||||
|
{
|
||||||
|
m_closed.signal ();
|
||||||
|
|
||||||
|
ServiceQueueType <Allocator>::stop ();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct BindHelperPost
|
||||||
|
{
|
||||||
|
CallQueueType<Allocator>& m_queue;
|
||||||
|
explicit BindHelperPost (CallQueueType<Allocator>& queue)
|
||||||
|
: m_queue (queue)
|
||||||
|
{ }
|
||||||
|
template <typename F>
|
||||||
|
void operator() (F const& f) const
|
||||||
|
{ m_queue.post ( F (f) ); }
|
||||||
|
};
|
||||||
|
|
||||||
|
struct BindHelperDispatch
|
||||||
|
{
|
||||||
|
CallQueueType<Allocator>& m_queue;
|
||||||
|
explicit BindHelperDispatch (CallQueueType<Allocator>& queue)
|
||||||
|
: m_queue (queue)
|
||||||
|
{ }
|
||||||
|
template <typename F>
|
||||||
|
void operator() (F const& f) const
|
||||||
|
{ m_queue.dispatch ( F (f) ); }
|
||||||
|
};
|
||||||
|
|
||||||
|
BindHelper <BindHelperPost> const queue;
|
||||||
|
BindHelper <BindHelperDispatch> const call;
|
||||||
|
|
||||||
|
private:
|
||||||
|
String m_name;
|
||||||
|
AtomicFlag m_closed;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef CallQueueType <std::allocator <char> > CallQueue;
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class CallQueueTests
|
||||||
|
: public UnitTest
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct CallTracker
|
||||||
|
{
|
||||||
|
CallQueueTests *unitTest;
|
||||||
|
int c0, c1, c2, c3, c4, c5, c6, c7, c8;
|
||||||
|
int q0, q1, q2, q3, q4, q5, q6, q7, q8;
|
||||||
|
|
||||||
|
CallTracker(CallQueueTests *parent)
|
||||||
|
: unitTest(parent)
|
||||||
|
, c0(0), c1(0), c2(0), c3(0), c4(0), c5(0), c6(0), c7(0), c8(0)
|
||||||
|
, q0(0), q1(0), q2(0), q3(0), q4(0), q5(0), q6(0), q7(0), q8(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void doQ0() { q0++; }
|
||||||
|
|
||||||
|
void doQ1(const String& p1)
|
||||||
|
{
|
||||||
|
unitTest->expect(p1 == "p1");
|
||||||
|
q1++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void doQ2(const String& p1, const String& p2)
|
||||||
|
{
|
||||||
|
unitTest->expect(p1 == "p1");
|
||||||
|
unitTest->expect(p2 == "p2");
|
||||||
|
q2++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void doQ3(const String& p1, const String& p2, const String& p3)
|
||||||
|
{
|
||||||
|
unitTest->expect(p1 == "p1");
|
||||||
|
unitTest->expect(p2 == "p2");
|
||||||
|
unitTest->expect(p3 == "p3");
|
||||||
|
q3++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void doQ4(const String& p1, const String& p2, const String& p3, const String& p4)
|
||||||
|
{
|
||||||
|
unitTest->expect(p1 == "p1");
|
||||||
|
unitTest->expect(p2 == "p2");
|
||||||
|
unitTest->expect(p3 == "p3");
|
||||||
|
unitTest->expect(p4 == "p4");
|
||||||
|
q4++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void doQ5(const String& p1, const String& p2, const String& p3, const String& p4, const String& p5)
|
||||||
|
{
|
||||||
|
unitTest->expect(p1 == "p1");
|
||||||
|
unitTest->expect(p2 == "p2");
|
||||||
|
unitTest->expect(p3 == "p3");
|
||||||
|
unitTest->expect(p4 == "p4");
|
||||||
|
unitTest->expect(p5 == "p5");
|
||||||
|
q5++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void doQ6(const String& p1, const String& p2, const String& p3, const String& p4, const String& p5, const String& p6)
|
||||||
|
{
|
||||||
|
unitTest->expect(p1 == "p1");
|
||||||
|
unitTest->expect(p2 == "p2");
|
||||||
|
unitTest->expect(p3 == "p3");
|
||||||
|
unitTest->expect(p4 == "p4");
|
||||||
|
unitTest->expect(p5 == "p5");
|
||||||
|
unitTest->expect(p6 == "p6");
|
||||||
|
q6++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void doQ7(const String& p1, const String& p2, const String& p3, const String& p4, const String& p5, const String& p6, const String& p7)
|
||||||
|
{
|
||||||
|
unitTest->expect(p1 == "p1");
|
||||||
|
unitTest->expect(p2 == "p2");
|
||||||
|
unitTest->expect(p3 == "p3");
|
||||||
|
unitTest->expect(p4 == "p4");
|
||||||
|
unitTest->expect(p5 == "p5");
|
||||||
|
unitTest->expect(p6 == "p6");
|
||||||
|
unitTest->expect(p7 == "p7");
|
||||||
|
q7++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void doQ8(const String& p1, const String& p2, const String& p3, const String& p4, const String& p5, const String& p6, const String& p7, const String& p8)
|
||||||
|
{
|
||||||
|
unitTest->expect(p1 == "p1");
|
||||||
|
unitTest->expect(p2 == "p2");
|
||||||
|
unitTest->expect(p3 == "p3");
|
||||||
|
unitTest->expect(p4 == "p4");
|
||||||
|
unitTest->expect(p5 == "p5");
|
||||||
|
unitTest->expect(p6 == "p6");
|
||||||
|
unitTest->expect(p7 == "p7");
|
||||||
|
unitTest->expect(p8 == "p8");
|
||||||
|
q8++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void doC0() { c0++; }
|
||||||
|
|
||||||
|
void doC1(const String& p1)
|
||||||
|
{
|
||||||
|
unitTest->expect(p1 == "p1");
|
||||||
|
c1++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void doC2(const String& p1, const String& p2)
|
||||||
|
{
|
||||||
|
unitTest->expect(p1 == "p1");
|
||||||
|
unitTest->expect(p2 == "p2");
|
||||||
|
c2++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void doC3(const String& p1, const String& p2, const String& p3)
|
||||||
|
{
|
||||||
|
unitTest->expect(p1 == "p1");
|
||||||
|
unitTest->expect(p2 == "p2");
|
||||||
|
unitTest->expect(p3 == "p3");
|
||||||
|
c3++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void doC4(const String& p1, const String& p2, const String& p3, const String& p4)
|
||||||
|
{
|
||||||
|
unitTest->expect(p1 == "p1");
|
||||||
|
unitTest->expect(p2 == "p2");
|
||||||
|
unitTest->expect(p3 == "p3");
|
||||||
|
unitTest->expect(p4 == "p4");
|
||||||
|
c4++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void doC5(const String& p1, const String& p2, const String& p3, const String& p4, const String& p5)
|
||||||
|
{
|
||||||
|
unitTest->expect(p1 == "p1");
|
||||||
|
unitTest->expect(p2 == "p2");
|
||||||
|
unitTest->expect(p3 == "p3");
|
||||||
|
unitTest->expect(p4 == "p4");
|
||||||
|
unitTest->expect(p5 == "p5");
|
||||||
|
c5++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void doC6(const String& p1, const String& p2, const String& p3, const String& p4, const String& p5, const String& p6)
|
||||||
|
{
|
||||||
|
unitTest->expect(p1 == "p1");
|
||||||
|
unitTest->expect(p2 == "p2");
|
||||||
|
unitTest->expect(p3 == "p3");
|
||||||
|
unitTest->expect(p4 == "p4");
|
||||||
|
unitTest->expect(p5 == "p5");
|
||||||
|
unitTest->expect(p6 == "p6");
|
||||||
|
c6++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void doC7(const String& p1, const String& p2, const String& p3, const String& p4, const String& p5, const String& p6, const String& p7)
|
||||||
|
{
|
||||||
|
unitTest->expect(p1 == "p1");
|
||||||
|
unitTest->expect(p2 == "p2");
|
||||||
|
unitTest->expect(p3 == "p3");
|
||||||
|
unitTest->expect(p4 == "p4");
|
||||||
|
unitTest->expect(p5 == "p5");
|
||||||
|
unitTest->expect(p6 == "p6");
|
||||||
|
unitTest->expect(p7 == "p7");
|
||||||
|
c7++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void doC8(const String& p1, const String& p2, const String& p3, const String& p4, const String& p5, const String& p6, const String& p7, const String& p8)
|
||||||
|
{
|
||||||
|
unitTest->expect(p1 == "p1");
|
||||||
|
unitTest->expect(p2 == "p2");
|
||||||
|
unitTest->expect(p3 == "p3");
|
||||||
|
unitTest->expect(p4 == "p4");
|
||||||
|
unitTest->expect(p5 == "p5");
|
||||||
|
unitTest->expect(p6 == "p6");
|
||||||
|
unitTest->expect(p7 == "p7");
|
||||||
|
unitTest->expect(p8 == "p8");
|
||||||
|
c8++;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
CallTracker m_callTracker;
|
||||||
|
|
||||||
|
void testArities ()
|
||||||
|
{
|
||||||
|
beginTestCase("Arities");
|
||||||
|
|
||||||
|
int calls = 0;
|
||||||
|
|
||||||
|
#if BEAST_VARIADIC_MAX >= 2
|
||||||
|
m_queue.queue(&CallTracker::doQ0, &m_callTracker); calls++;
|
||||||
|
m_queue.queue(&CallTracker::doC0, &m_callTracker); calls++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BEAST_VARIADIC_MAX >= 3
|
||||||
|
m_queue.queue(&CallTracker::doQ1, &m_callTracker, "p1"); calls++;
|
||||||
|
m_queue.queue(&CallTracker::doC1, &m_callTracker, "p1"); calls++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BEAST_VARIADIC_MAX >= 4
|
||||||
|
m_queue.queue(&CallTracker::doQ2, &m_callTracker, "p1", "p2"); calls++;
|
||||||
|
m_queue.queue(&CallTracker::doC2, &m_callTracker, "p1", "p2"); calls++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BEAST_VARIADIC_MAX >= 5
|
||||||
|
m_queue.queue(&CallTracker::doQ3, &m_callTracker, "p1", "p2", "p3"); calls++;
|
||||||
|
m_queue.queue(&CallTracker::doC3, &m_callTracker, "p1", "p2", "p3"); calls++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BEAST_VARIADIC_MAX >= 6
|
||||||
|
m_queue.queue(&CallTracker::doQ4, &m_callTracker, "p1", "p2", "p3", "p4"); calls++;
|
||||||
|
m_queue.queue(&CallTracker::doC4, &m_callTracker, "p1", "p2", "p3", "p4"); calls++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BEAST_VARIADIC_MAX >= 7
|
||||||
|
m_queue.queue(&CallTracker::doQ5, &m_callTracker, "p1", "p2", "p3", "p4", "p5"); calls++;
|
||||||
|
m_queue.queue(&CallTracker::doC5, &m_callTracker, "p1", "p2", "p3", "p4", "p5"); calls++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BEAST_VARIADIC_MAX >= 8
|
||||||
|
m_queue.queue(&CallTracker::doQ6, &m_callTracker, "p1", "p2", "p3", "p4", "p5", "p6"); calls++;
|
||||||
|
m_queue.queue(&CallTracker::doC6, &m_callTracker, "p1", "p2", "p3", "p4", "p5", "p6"); calls++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BEAST_VARIADIC_MAX >= 9
|
||||||
|
m_queue.queue(&CallTracker::doQ7, &m_callTracker, "p1", "p2", "p3", "p4", "p5", "p6", "p7"); calls++;
|
||||||
|
m_queue.queue(&CallTracker::doC7, &m_callTracker, "p1", "p2", "p3", "p4", "p5", "p6", "p7"); calls++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if BEAST_VARIADIC_MAX >= 10
|
||||||
|
m_queue.queue(&CallTracker::doQ8, &m_callTracker, "p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8"); calls++;
|
||||||
|
m_queue.queue(&CallTracker::doC8, &m_callTracker, "p1", "p2", "p3", "p4", "p5", "p6", "p7", "p8"); calls++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
std::size_t performedCalls = m_queue.poll();
|
||||||
|
|
||||||
|
m_queue.close();
|
||||||
|
|
||||||
|
expect (performedCalls == calls);
|
||||||
|
|
||||||
|
expect (m_callTracker.c0 == 1);
|
||||||
|
expect (m_callTracker.c1 == 1);
|
||||||
|
expect (m_callTracker.c2 == 1);
|
||||||
|
expect (m_callTracker.c3 == 1);
|
||||||
|
expect (m_callTracker.c4 == 1);
|
||||||
|
expect (m_callTracker.c5 == 1);
|
||||||
|
|
||||||
|
expect (m_callTracker.q0 == 1);
|
||||||
|
expect (m_callTracker.q1 == 1);
|
||||||
|
expect (m_callTracker.q2 == 1);
|
||||||
|
expect (m_callTracker.q3 == 1);
|
||||||
|
expect (m_callTracker.q4 == 1);
|
||||||
|
expect (m_callTracker.q5 == 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void runTest()
|
||||||
|
{
|
||||||
|
testArities();
|
||||||
|
}
|
||||||
|
|
||||||
|
CallQueueTests ()
|
||||||
|
: UnitTest ("CallQueue", "beast")
|
||||||
|
, m_queue("CallQueue Test Queue")
|
||||||
|
, m_callTracker(this)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
CallQueue m_queue;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
72
modules/beast_vflib/threads/GuiServiceQueue.h
Normal file
72
modules/beast_vflib/threads/GuiServiceQueue.h
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||||
|
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||||
|
Copyright Patrick Dehne <patrick@mysonicweb.de> (www.sonicweb-radio.de)
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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 BEAST_VFLIB_GUISERVICEQUEUE_H_INCLUDED
|
||||||
|
#define BEAST_VFLIB_GUISERVICEQUEUE_H_INCLUDED
|
||||||
|
|
||||||
|
#include "AppConfig.h"
|
||||||
|
#include "modules/juce_core/juce_core.h"
|
||||||
|
#include "modules/juce_events/juce_events.h"
|
||||||
|
|
||||||
|
#include "CallQueue.h"
|
||||||
|
|
||||||
|
namespace beast {
|
||||||
|
|
||||||
|
class GuiServiceQueue
|
||||||
|
: public CallQueue
|
||||||
|
, private juce::AsyncUpdater
|
||||||
|
, private ThreadWithServiceQueue::EntryPoints
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit GuiServiceQueue (const String& name)
|
||||||
|
: CallQueue(name)
|
||||||
|
, m_thread(name)
|
||||||
|
{
|
||||||
|
bassert (juce::MessageManager::getInstance()->isThisTheMessageThread());
|
||||||
|
|
||||||
|
m_thread.start (this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void close ()
|
||||||
|
{
|
||||||
|
m_thread.stop (true);
|
||||||
|
|
||||||
|
CallQueue::close ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void enqueue (ServiceQueueBase::Item* item)
|
||||||
|
{
|
||||||
|
CallQueue::enqueue (item);
|
||||||
|
|
||||||
|
m_thread.call (&juce::AsyncUpdater::triggerAsyncUpdate, (AsyncUpdater*)this);
|
||||||
|
}
|
||||||
|
|
||||||
|
void handleAsyncUpdate()
|
||||||
|
{
|
||||||
|
poll();
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
ThreadWithServiceQueue m_thread;
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
165
modules/beast_vflib/threads/ManualServiceQueue.h
Normal file
165
modules/beast_vflib/threads/ManualServiceQueue.h
Normal file
@@ -0,0 +1,165 @@
|
|||||||
|
//------------------------------------------------------------------------------
|
||||||
|
/*
|
||||||
|
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||||
|
Copyright Patrick Dehne <patrick@mysonicweb.de> (www.sonicweb-radio.de)
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
|
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 BEAST_VFLIB_MANUALSERVICEQUEUE_H_INCLUDED
|
||||||
|
#define BEAST_VFLIB_MANUALSERVICEQUEUE_H_INCLUDED
|
||||||
|
|
||||||
|
#include "CallQueue.h"
|
||||||
|
|
||||||
|
namespace beast {
|
||||||
|
|
||||||
|
class ManualServiceQueue
|
||||||
|
: public CallQueue
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
explicit ManualServiceQueue (const String& name)
|
||||||
|
: CallQueue(name)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Calls all functors in the queue. Returns if there are no
|
||||||
|
more functors available to run
|
||||||
|
*/
|
||||||
|
bool synchronize ()
|
||||||
|
{
|
||||||
|
if(poll() > 0)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
class ManualServiceQueueTests
|
||||||
|
: public UnitTest
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct CallTracker
|
||||||
|
{
|
||||||
|
ManualServiceQueueTests *unitTest;
|
||||||
|
int c0, c1;
|
||||||
|
int q0, q1;
|
||||||
|
|
||||||
|
CallTracker(ManualServiceQueueTests *parent)
|
||||||
|
: unitTest(parent)
|
||||||
|
, c0(0), c1(0)
|
||||||
|
, q0(0), q1(0)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void doQ0() { q0++; }
|
||||||
|
|
||||||
|
void doQ1(const String& p1)
|
||||||
|
{
|
||||||
|
unitTest->expect(p1 == "p1");
|
||||||
|
q1++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void doC0() { c0++; }
|
||||||
|
|
||||||
|
void doC1(const String& p1)
|
||||||
|
{
|
||||||
|
unitTest->expect(p1 == "p1");
|
||||||
|
c1++;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
void performEmptyQueue()
|
||||||
|
{
|
||||||
|
beginTestCase("Empty queue");
|
||||||
|
|
||||||
|
ManualServiceQueue queue("ManualServiceQueueTests");
|
||||||
|
|
||||||
|
bool doneSomething = queue.synchronize();
|
||||||
|
expect(!doneSomething);
|
||||||
|
|
||||||
|
queue.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
void performCalls()
|
||||||
|
{
|
||||||
|
beginTestCase("Calls");
|
||||||
|
|
||||||
|
Random r;
|
||||||
|
r.setSeedRandomly();
|
||||||
|
|
||||||
|
ManualServiceQueue queue("ManualServiceQueueTests");
|
||||||
|
|
||||||
|
static int const batches = 1000;
|
||||||
|
|
||||||
|
for(std::size_t i=0; i<batches; i++)
|
||||||
|
{
|
||||||
|
CallTracker ct(this);
|
||||||
|
|
||||||
|
std::size_t batchSize = r.nextLargeNumber(10).toInteger();
|
||||||
|
|
||||||
|
if(batchSize > 0)
|
||||||
|
{
|
||||||
|
for(std::size_t y=0; y<batchSize; y++)
|
||||||
|
{
|
||||||
|
int callType = r.nextLargeNumber(10).toInteger();
|
||||||
|
|
||||||
|
if(callType % 2)
|
||||||
|
{
|
||||||
|
queue.queue(&CallTracker::doQ0, &ct);
|
||||||
|
queue.call(&CallTracker::doC0, &ct);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
queue.queue(&CallTracker::doQ1, &ct, "p1");
|
||||||
|
queue.call(&CallTracker::doC1, &ct, "p1");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool doneSomething = queue.synchronize();
|
||||||
|
|
||||||
|
expect(doneSomething);
|
||||||
|
expect ((ct.q0 + ct.q1) == batchSize);
|
||||||
|
expect ((ct.c0 + ct.c1) == batchSize);
|
||||||
|
|
||||||
|
doneSomething = queue.synchronize();
|
||||||
|
expect(!doneSomething);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
queue.close ();
|
||||||
|
}
|
||||||
|
|
||||||
|
void runTest()
|
||||||
|
{
|
||||||
|
performEmptyQueue ();
|
||||||
|
performCalls ();
|
||||||
|
}
|
||||||
|
|
||||||
|
ManualServiceQueueTests () : UnitTest ("ManualServiceQueue", "beast")
|
||||||
|
{
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
/*
|
/*
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||||
|
Copyright Patrick Dehne <patrick@mysonicweb.de> (www.sonicweb-radio.de)
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
@@ -22,11 +23,11 @@
|
|||||||
namespace beast {
|
namespace beast {
|
||||||
|
|
||||||
ThreadWithServiceQueue::ThreadWithServiceQueue (const String& name)
|
ThreadWithServiceQueue::ThreadWithServiceQueue (const String& name)
|
||||||
: Thread (name)
|
: CallQueue(name)
|
||||||
|
, m_thread(name, this)
|
||||||
, m_entryPoints(nullptr)
|
, m_entryPoints(nullptr)
|
||||||
, m_calledStart(false)
|
, m_calledStart(false)
|
||||||
, m_calledStop(false)
|
, m_calledStop(false)
|
||||||
, m_interrupted(false)
|
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -37,24 +38,17 @@ ThreadWithServiceQueue::~ThreadWithServiceQueue()
|
|||||||
|
|
||||||
void ThreadWithServiceQueue::start (EntryPoints* const entryPoints)
|
void ThreadWithServiceQueue::start (EntryPoints* const entryPoints)
|
||||||
{
|
{
|
||||||
{
|
|
||||||
CriticalSection::ScopedLockType lock (m_mutex);
|
|
||||||
|
|
||||||
// start() MUST be called.
|
// start() MUST be called.
|
||||||
bassert (!m_calledStart);
|
bassert (!m_calledStart);
|
||||||
m_calledStart = true;
|
m_calledStart = true;
|
||||||
}
|
|
||||||
|
|
||||||
m_entryPoints = entryPoints;
|
m_entryPoints = entryPoints;
|
||||||
|
|
||||||
startThread();
|
m_thread.startThread ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThreadWithServiceQueue::stop (bool const wait)
|
void ThreadWithServiceQueue::stop (bool const wait)
|
||||||
{
|
{
|
||||||
{
|
|
||||||
CriticalSection::ScopedLockType lock (m_mutex);
|
|
||||||
|
|
||||||
// start() MUST be called.
|
// start() MUST be called.
|
||||||
bassert (m_calledStart);
|
bassert (m_calledStart);
|
||||||
|
|
||||||
@@ -62,66 +56,32 @@ void ThreadWithServiceQueue::stop (bool const wait)
|
|||||||
{
|
{
|
||||||
m_calledStop = true;
|
m_calledStop = true;
|
||||||
|
|
||||||
{
|
m_thread.signalThreadShouldExit();
|
||||||
CriticalSection::ScopedUnlockType unlock (m_mutex);
|
|
||||||
|
|
||||||
call (&Thread::signalThreadShouldExit, this);
|
|
||||||
|
|
||||||
// something could slip in here
|
// something could slip in here
|
||||||
|
|
||||||
// m_queue.close();
|
close ();
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (wait)
|
if (wait)
|
||||||
waitForThreadToExit();
|
m_thread.waitForThreadToExit ();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThreadWithServiceQueue::interrupt ()
|
void ThreadWithServiceQueue::runThread ()
|
||||||
{
|
|
||||||
call (&ThreadWithServiceQueue::doInterrupt, this);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool ThreadWithServiceQueue::interruptionPoint ()
|
|
||||||
{
|
|
||||||
return m_interrupted;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThreadWithServiceQueue::run ()
|
|
||||||
{
|
{
|
||||||
m_entryPoints->threadInit ();
|
m_entryPoints->threadInit ();
|
||||||
|
|
||||||
while (! this->threadShouldExit())
|
while (! m_thread.threadShouldExit ())
|
||||||
{
|
run ();
|
||||||
run_one();
|
|
||||||
|
|
||||||
bool isInterrupted = m_entryPoints->threadIdle();
|
// Perform the remaining calls in the queue
|
||||||
|
|
||||||
isInterrupted |= interruptionPoint();
|
reset ();
|
||||||
|
poll ();
|
||||||
if(isInterrupted)
|
|
||||||
{
|
|
||||||
// We put this call into the service queue to make
|
|
||||||
// sure we get through to threadIdle without
|
|
||||||
// waiting
|
|
||||||
call (&ThreadWithServiceQueue::doWakeUp, this);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_entryPoints->threadExit();
|
m_entryPoints->threadExit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ThreadWithServiceQueue::doInterrupt ()
|
|
||||||
{
|
|
||||||
m_interrupted = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void ThreadWithServiceQueue::doWakeUp ()
|
|
||||||
{
|
|
||||||
m_interrupted = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
namespace detail
|
namespace detail
|
||||||
@@ -129,22 +89,27 @@ namespace detail
|
|||||||
|
|
||||||
//------------------------------------------------------------------------------
|
//------------------------------------------------------------------------------
|
||||||
|
|
||||||
class BindableServiceQueueTests
|
class ThreadWithServiceQueueTests
|
||||||
: public UnitTest
|
: public UnitTest
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
struct BindableServiceQueueRunner
|
struct ThreadWithServiceQueueRunner
|
||||||
: public ThreadWithServiceQueue::EntryPoints
|
: public ThreadWithServiceQueue::EntryPoints
|
||||||
{
|
{
|
||||||
ThreadWithServiceQueue m_worker;
|
ThreadWithServiceQueue m_worker;
|
||||||
int cCallCount, c1CallCount, idleInterruptedCount;
|
int cCallCount, c1CallCount;
|
||||||
|
int qCallCount, q1CallCount;
|
||||||
|
int initCalled, exitCalled;
|
||||||
|
|
||||||
BindableServiceQueueRunner()
|
ThreadWithServiceQueueRunner()
|
||||||
: m_worker("BindableServiceQueueRunner")
|
: m_worker("ThreadWithServiceQueueRunner")
|
||||||
, cCallCount(0)
|
, cCallCount(0)
|
||||||
, c1CallCount(0)
|
, c1CallCount(0)
|
||||||
, idleInterruptedCount(0)
|
, qCallCount(0)
|
||||||
|
, q1CallCount(0)
|
||||||
|
, initCalled(0)
|
||||||
|
, exitCalled(0)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,14 +123,9 @@ public:
|
|||||||
m_worker.stop(true);
|
m_worker.stop(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
void interrupt()
|
|
||||||
{
|
|
||||||
m_worker.interrupt();
|
|
||||||
}
|
|
||||||
|
|
||||||
void c()
|
void c()
|
||||||
{
|
{
|
||||||
m_worker.queue(&BindableServiceQueueRunner::cImpl, this);
|
m_worker.call(&ThreadWithServiceQueueRunner::cImpl, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cImpl()
|
void cImpl()
|
||||||
@@ -175,7 +135,7 @@ public:
|
|||||||
|
|
||||||
void c1(int p1)
|
void c1(int p1)
|
||||||
{
|
{
|
||||||
m_worker.queue(&BindableServiceQueueRunner::c1Impl, this, p1);
|
m_worker.call(&ThreadWithServiceQueueRunner::c1Impl, this, p1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void c1Impl(int p1)
|
void c1Impl(int p1)
|
||||||
@@ -183,30 +143,58 @@ public:
|
|||||||
c1CallCount++;
|
c1CallCount++;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool threadIdle ()
|
void q()
|
||||||
{
|
{
|
||||||
bool interrupted = m_worker.interruptionPoint ();
|
m_worker.queue(&ThreadWithServiceQueueRunner::qImpl, this);
|
||||||
|
}
|
||||||
|
|
||||||
if(interrupted)
|
void qImpl()
|
||||||
idleInterruptedCount++;
|
{
|
||||||
|
qCallCount++;
|
||||||
|
}
|
||||||
|
|
||||||
return interrupted;
|
void q1(int p1)
|
||||||
|
{
|
||||||
|
m_worker.queue(&ThreadWithServiceQueueRunner::q1Impl, this, p1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void q1Impl(int p1)
|
||||||
|
{
|
||||||
|
q1CallCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void threadInit ()
|
||||||
|
{
|
||||||
|
initCalled++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void threadExit ()
|
||||||
|
{
|
||||||
|
exitCalled++;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static int const calls = 10000;
|
static int const calls = 1000;
|
||||||
|
|
||||||
void performCalls()
|
void performCalls()
|
||||||
{
|
{
|
||||||
Random r;
|
Random r;
|
||||||
r.setSeedRandomly();
|
r.setSeedRandomly();
|
||||||
|
|
||||||
BindableServiceQueueRunner runner;
|
ThreadWithServiceQueueRunner runner;
|
||||||
|
|
||||||
beginTestCase("Calls and interruptions");
|
|
||||||
|
|
||||||
runner.start();
|
runner.start();
|
||||||
|
|
||||||
|
for(std::size_t i=0; i<calls; i++)
|
||||||
|
{
|
||||||
|
int wait = r.nextLargeNumber(10).toInteger();
|
||||||
|
|
||||||
|
if(wait % 2)
|
||||||
|
runner.q();
|
||||||
|
else
|
||||||
|
runner.q1Impl(wait);
|
||||||
|
}
|
||||||
|
|
||||||
for(std::size_t i=0; i<calls; i++)
|
for(std::size_t i=0; i<calls; i++)
|
||||||
{
|
{
|
||||||
int wait = r.nextLargeNumber(10).toInteger();
|
int wait = r.nextLargeNumber(10).toInteger();
|
||||||
@@ -217,30 +205,31 @@ public:
|
|||||||
runner.c1Impl(wait);
|
runner.c1Impl(wait);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(std::size_t i=0; i<calls; i++)
|
|
||||||
runner.interrupt();
|
|
||||||
|
|
||||||
runner.stop();
|
runner.stop();
|
||||||
|
|
||||||
// We can only reason that the idle method must have been interrupted
|
|
||||||
// at least once
|
|
||||||
expect ((runner.cCallCount + runner.c1CallCount) == calls);
|
expect ((runner.cCallCount + runner.c1CallCount) == calls);
|
||||||
expect (runner.idleInterruptedCount > 0);
|
expect ((runner.qCallCount + runner.q1CallCount) == calls);
|
||||||
|
expect (runner.initCalled == 1);
|
||||||
|
expect (runner.exitCalled == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void runTest()
|
void runTest()
|
||||||
{
|
{
|
||||||
|
beginTestCase("Calls");
|
||||||
|
|
||||||
|
for(int i=0; i<100; i++)
|
||||||
performCalls ();
|
performCalls ();
|
||||||
}
|
}
|
||||||
|
|
||||||
BindableServiceQueueTests () : UnitTest ("BindableServiceQueue", "beast")
|
ThreadWithServiceQueueTests () : UnitTest ("ThreadWithServiceQueue", "beast")
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
static BindableServiceQueueTests bindableServiceQueueTests;
|
static CallQueueTests callQueueTests;
|
||||||
|
|
||||||
|
static ThreadWithServiceQueueTests bindableServiceQueueTests;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -2,6 +2,7 @@
|
|||||||
/*
|
/*
|
||||||
This file is part of Beast: https://github.com/vinniefalco/Beast
|
This file is part of Beast: https://github.com/vinniefalco/Beast
|
||||||
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
Copyright 2013, Vinnie Falco <vinnie.falco@gmail.com>
|
||||||
|
Copyright Patrick Dehne <patrick@mysonicweb.de> (www.sonicweb-radio.de)
|
||||||
|
|
||||||
Permission to use, copy, modify, and/or distribute this software for any
|
Permission to use, copy, modify, and/or distribute this software for any
|
||||||
purpose with or without fee is hereby granted, provided that the above
|
purpose with or without fee is hereby granted, provided that the above
|
||||||
@@ -20,18 +21,12 @@
|
|||||||
#ifndef BEAST_VFLIB_THREADWITHSERVICEQUEUE_H_INCLUDED
|
#ifndef BEAST_VFLIB_THREADWITHSERVICEQUEUE_H_INCLUDED
|
||||||
#define BEAST_VFLIB_THREADWITHSERVICEQUEUE_H_INCLUDED
|
#define BEAST_VFLIB_THREADWITHSERVICEQUEUE_H_INCLUDED
|
||||||
|
|
||||||
#include "BindableServiceQueue.h"
|
#include "CallQueue.h"
|
||||||
|
|
||||||
namespace beast {
|
namespace beast {
|
||||||
|
|
||||||
/** TODO: Queued calls no longer interrupt the idle method at the moment
|
|
||||||
use an explicit call to interrupt() if you want to also interrupt the
|
|
||||||
idle method when queuing calls
|
|
||||||
*/
|
|
||||||
|
|
||||||
class ThreadWithServiceQueue
|
class ThreadWithServiceQueue
|
||||||
: public BindableServiceQueue
|
: public CallQueue
|
||||||
, public Thread
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/** Entry points for a ThreadWithCallQueue.
|
/** Entry points for a ThreadWithCallQueue.
|
||||||
@@ -44,13 +39,6 @@ namespace beast {
|
|||||||
virtual void threadInit () { }
|
virtual void threadInit () { }
|
||||||
|
|
||||||
virtual void threadExit () { }
|
virtual void threadExit () { }
|
||||||
|
|
||||||
virtual bool threadIdle ()
|
|
||||||
{
|
|
||||||
bool interrupted = false;
|
|
||||||
|
|
||||||
return interrupted;
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
explicit ThreadWithServiceQueue (const String& name);
|
explicit ThreadWithServiceQueue (const String& name);
|
||||||
@@ -61,31 +49,44 @@ namespace beast {
|
|||||||
|
|
||||||
void stop (bool const wait);
|
void stop (bool const wait);
|
||||||
|
|
||||||
// Should be called periodically by the idle function.
|
/** Calls all functors in the queue. Blocks if there are no
|
||||||
// There are two possible results:
|
functors available to run until more functors become
|
||||||
//
|
available or the queue is stopped
|
||||||
// #1 Returns false. The idle function may continue or return.
|
|
||||||
// #2 Returns true. The idle function should return as soon as possible.
|
|
||||||
//
|
|
||||||
// May only be called on the service queue thead
|
|
||||||
bool interruptionPoint ();
|
|
||||||
|
|
||||||
/* Interrupts the idle function.
|
|
||||||
*/
|
*/
|
||||||
void interrupt ();
|
bool synchronize ();
|
||||||
|
|
||||||
|
/** Helper class to work around ThreadWithServiceQueue and Thread both
|
||||||
|
having a run member
|
||||||
|
*/
|
||||||
|
class Worker
|
||||||
|
: public Thread
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
Worker(const String& name, ThreadWithServiceQueue *parent)
|
||||||
|
: Thread(name)
|
||||||
|
, m_parent(parent)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void run()
|
||||||
|
{
|
||||||
|
m_parent->runThread();
|
||||||
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void run ();
|
ThreadWithServiceQueue *m_parent;
|
||||||
void doInterrupt ();
|
};
|
||||||
void doWakeUp ();
|
|
||||||
|
void runThread ();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
EntryPoints* m_entryPoints;
|
EntryPoints* m_entryPoints;
|
||||||
bool m_calledStart;
|
bool m_calledStart;
|
||||||
bool m_calledStop;
|
bool m_calledStop;
|
||||||
bool m_interrupted;
|
Worker m_thread;
|
||||||
CriticalSection m_mutex;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
Reference in New Issue
Block a user