migrating to the latest JUCE version

This commit is contained in:
2022-11-04 23:11:33 +01:00
committed by Nikolai Rodionov
parent 4257a0f8ba
commit faf8f18333
2796 changed files with 888518 additions and 784244 deletions

View File

@ -1,44 +1,44 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#ifdef JUCE_OSC_H_INCLUDED
/* When you add this cpp file to your project, you mustn't include it in a file where you've
already included any other headers - just put it inside a file on its own, possibly with your config
flags preceding it, but don't include anything else. That also includes avoiding any automatic prefix
header files that the compiler may be using.
*/
#error "Incorrect use of JUCE cpp file"
#endif
#include "juce_osc.h"
#include "osc/juce_OSCTypes.cpp"
#include "osc/juce_OSCTimeTag.cpp"
#include "osc/juce_OSCArgument.cpp"
#include "osc/juce_OSCAddress.cpp"
#include "osc/juce_OSCMessage.cpp"
#include "osc/juce_OSCBundle.cpp"
#include "osc/juce_OSCReceiver.cpp"
#include "osc/juce_OSCSender.cpp"
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
#ifdef JUCE_OSC_H_INCLUDED
/* When you add this cpp file to your project, you mustn't include it in a file where you've
already included any other headers - just put it inside a file on its own, possibly with your config
flags preceding it, but don't include anything else. That also includes avoiding any automatic prefix
header files that the compiler may be using.
*/
#error "Incorrect use of JUCE cpp file"
#endif
#include "juce_osc.h"
#include "osc/juce_OSCTypes.cpp"
#include "osc/juce_OSCTimeTag.cpp"
#include "osc/juce_OSCArgument.cpp"
#include "osc/juce_OSCAddress.cpp"
#include "osc/juce_OSCMessage.cpp"
#include "osc/juce_OSCBundle.cpp"
#include "osc/juce_OSCReceiver.cpp"
#include "osc/juce_OSCSender.cpp"

View File

@ -1,66 +1,66 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
/*******************************************************************************
The block below describes the properties of this module, and is read by
the Projucer to automatically generate project code that uses it.
For details about the syntax and how to create or use a module, see the
JUCE Module Format.md file.
BEGIN_JUCE_MODULE_DECLARATION
ID: juce_osc
vendor: juce
version: 6.1.2
name: JUCE OSC classes
description: Open Sound Control implementation.
website: http://www.juce.com/juce
license: GPL/Commercial
minimumCppStandard: 14
dependencies: juce_events
END_JUCE_MODULE_DECLARATION
*******************************************************************************/
#pragma once
#define JUCE_OSC_H_INCLUDED
#include <juce_core/juce_core.h>
#include <juce_events/juce_events.h>
//==============================================================================
#include "osc/juce_OSCTypes.h"
#include "osc/juce_OSCTimeTag.h"
#include "osc/juce_OSCArgument.h"
#include "osc/juce_OSCAddress.h"
#include "osc/juce_OSCMessage.h"
#include "osc/juce_OSCBundle.h"
#include "osc/juce_OSCReceiver.h"
#include "osc/juce_OSCSender.h"
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
/*******************************************************************************
The block below describes the properties of this module, and is read by
the Projucer to automatically generate project code that uses it.
For details about the syntax and how to create or use a module, see the
JUCE Module Format.md file.
BEGIN_JUCE_MODULE_DECLARATION
ID: juce_osc
vendor: juce
version: 7.0.2
name: JUCE OSC classes
description: Open Sound Control implementation.
website: http://www.juce.com/juce
license: GPL/Commercial
minimumCppStandard: 14
dependencies: juce_events
END_JUCE_MODULE_DECLARATION
*******************************************************************************/
#pragma once
#define JUCE_OSC_H_INCLUDED
#include <juce_core/juce_core.h>
#include <juce_events/juce_events.h>
//==============================================================================
#include "osc/juce_OSCTypes.h"
#include "osc/juce_OSCTimeTag.h"
#include "osc/juce_OSCArgument.h"
#include "osc/juce_OSCAddress.h"
#include "osc/juce_OSCMessage.h"
#include "osc/juce_OSCBundle.h"
#include "osc/juce_OSCReceiver.h"
#include "osc/juce_OSCSender.h"

File diff suppressed because it is too large Load Diff

View File

@ -1,153 +1,153 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/**
An OSC address.
This address always starts with a forward slash and has a format similar
to an URL, with several address parts separated by slashes.
Only a subset of ASCII characters are allowed in OSC addresses; see
OpenSoundControl 1.0 specification for details.
OSC addresses can be used to register ListenerWithOSCAddress objects to an
OSCReceiver if you wish them to only listen to certain messages with
matching OSC address patterns.
@see OSCReceiver, OSCAddressPattern, OSCMessage
@tags{OSC}
*/
class JUCE_API OSCAddress
{
public:
//==============================================================================
/** Constructs a new OSCAddress from a String.
@throw OSCFormatError if the string is not a valid OSC address.
*/
OSCAddress (const String& address);
/** Constructs a new OSCAddress from a C string.
@throw OSCFormatError of the string is not a valid OSC address.
*/
OSCAddress (const char* address);
/** Compares two OSCAddress objects.
@returns true if they contain the same address, false otherwise.
*/
bool operator== (const OSCAddress& other) const noexcept;
/** Compares two OSCAddress objects.
@returns false if they contain the same address, true otherwise.
*/
bool operator!= (const OSCAddress& other) const noexcept;
/** Converts the OSCAddress to a String.
Note: Trailing slashes are always removed automatically.
@returns a String object that represents the OSC address.
*/
String toString() const noexcept;
private:
//==============================================================================
StringArray oscSymbols;
String asString;
friend class OSCAddressPattern;
};
//==============================================================================
/**
An OSC address pattern.
Extends an OSC address by additionally allowing the following wildcards:
?, *, [], {}
OSC messages always have an OSC address pattern to specify the destination(s)
of the message.
@see OSCMessage, OSCAddress, OSCMessageListener
@tags{OSC}
*/
class JUCE_API OSCAddressPattern
{
public:
//==============================================================================
/** Constructs a new OSCAddressPattern from a String.
@throw OSCFormatError if the string is not a valid OSC address pattern.
*/
OSCAddressPattern (const String& address);
/** Constructs a new OSCAddressPattern from a C string.
@throw OSCFormatError of the string is not a valid OSC address pattern.
*/
OSCAddressPattern (const char* address);
/** Compares two OSCAddressPattern objects.
@returns true if they contain the same address pattern, false otherwise.
*/
bool operator== (const OSCAddressPattern& other) const noexcept;
/** Compares two OSCAddressPattern objects.
@returns false if they contain the same address pattern, true otherwise.
*/
bool operator!= (const OSCAddressPattern& other) const noexcept;
/** Checks if the OSCAddressPattern matches an OSC address with the wildcard
rules defined by the OpenSoundControl 1.0 specification.
@returns true if the OSCAddressPattern matches the given OSC address,
false otherwise.
*/
bool matches (const OSCAddress& address) const noexcept;
/** Checks whether the OSCAddressPattern contains any of the allowed OSC
address pattern wildcards: ?, *, [], {}
@returns true if the OSCAddressPattern contains OSC wildcards, false otherwise.
*/
bool containsWildcards() const noexcept { return wasInitialisedWithWildcards; }
/** Converts the OSCAddressPattern to a String.
Note: Trailing slashes are always removed automatically.
@returns a String object that represents the OSC address pattern.
*/
String toString() const noexcept;
private:
//==============================================================================
StringArray oscSymbols;
String asString;
bool wasInitialisedWithWildcards;
};
} // namespace juce
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/**
An OSC address.
This address always starts with a forward slash and has a format similar
to an URL, with several address parts separated by slashes.
Only a subset of ASCII characters are allowed in OSC addresses; see
OpenSoundControl 1.0 specification for details.
OSC addresses can be used to register ListenerWithOSCAddress objects to an
OSCReceiver if you wish them to only listen to certain messages with
matching OSC address patterns.
@see OSCReceiver, OSCAddressPattern, OSCMessage
@tags{OSC}
*/
class JUCE_API OSCAddress
{
public:
//==============================================================================
/** Constructs a new OSCAddress from a String.
@throw OSCFormatError if the string is not a valid OSC address.
*/
OSCAddress (const String& address);
/** Constructs a new OSCAddress from a C string.
@throw OSCFormatError of the string is not a valid OSC address.
*/
OSCAddress (const char* address);
/** Compares two OSCAddress objects.
@returns true if they contain the same address, false otherwise.
*/
bool operator== (const OSCAddress& other) const noexcept;
/** Compares two OSCAddress objects.
@returns false if they contain the same address, true otherwise.
*/
bool operator!= (const OSCAddress& other) const noexcept;
/** Converts the OSCAddress to a String.
Note: Trailing slashes are always removed automatically.
@returns a String object that represents the OSC address.
*/
String toString() const noexcept;
private:
//==============================================================================
StringArray oscSymbols;
String asString;
friend class OSCAddressPattern;
};
//==============================================================================
/**
An OSC address pattern.
Extends an OSC address by additionally allowing the following wildcards:
?, *, [], {}
OSC messages always have an OSC address pattern to specify the destination(s)
of the message.
@see OSCMessage, OSCAddress, OSCMessageListener
@tags{OSC}
*/
class JUCE_API OSCAddressPattern
{
public:
//==============================================================================
/** Constructs a new OSCAddressPattern from a String.
@throw OSCFormatError if the string is not a valid OSC address pattern.
*/
OSCAddressPattern (const String& address);
/** Constructs a new OSCAddressPattern from a C string.
@throw OSCFormatError of the string is not a valid OSC address pattern.
*/
OSCAddressPattern (const char* address);
/** Compares two OSCAddressPattern objects.
@returns true if they contain the same address pattern, false otherwise.
*/
bool operator== (const OSCAddressPattern& other) const noexcept;
/** Compares two OSCAddressPattern objects.
@returns false if they contain the same address pattern, true otherwise.
*/
bool operator!= (const OSCAddressPattern& other) const noexcept;
/** Checks if the OSCAddressPattern matches an OSC address with the wildcard
rules defined by the OpenSoundControl 1.0 specification.
@returns true if the OSCAddressPattern matches the given OSC address,
false otherwise.
*/
bool matches (const OSCAddress& address) const noexcept;
/** Checks whether the OSCAddressPattern contains any of the allowed OSC
address pattern wildcards: ?, *, [], {}
@returns true if the OSCAddressPattern contains OSC wildcards, false otherwise.
*/
bool containsWildcards() const noexcept { return wasInitialisedWithWildcards; }
/** Converts the OSCAddressPattern to a String.
Note: Trailing slashes are always removed automatically.
@returns a String object that represents the OSC address pattern.
*/
String toString() const noexcept;
private:
//==============================================================================
StringArray oscSymbols;
String asString;
bool wasInitialisedWithWildcards;
};
} // namespace juce

View File

@ -1,249 +1,249 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
OSCArgument::OSCArgument (int32 v) : type (OSCTypes::int32), intValue (v) {}
OSCArgument::OSCArgument (float v) : type (OSCTypes::float32), floatValue (v) {}
OSCArgument::OSCArgument (const String& s) : type (OSCTypes::string), stringValue (s) {}
OSCArgument::OSCArgument (MemoryBlock b) : type (OSCTypes::blob), blob (std::move (b)) {}
OSCArgument::OSCArgument (OSCColour c) : type (OSCTypes::colour), intValue ((int32) c.toInt32()) {}
//==============================================================================
String OSCArgument::getString() const noexcept
{
if (isString())
return stringValue;
jassertfalse; // you must check the type of an argument before attempting to get its value!
return {};
}
int32 OSCArgument::getInt32() const noexcept
{
if (isInt32())
return intValue;
jassertfalse; // you must check the type of an argument before attempting to get its value!
return 0;
}
float OSCArgument::getFloat32() const noexcept
{
if (isFloat32())
return floatValue;
jassertfalse; // you must check the type of an argument before attempting to get its value!
return 0.0f;
}
const MemoryBlock& OSCArgument::getBlob() const noexcept
{
// you must check the type of an argument before attempting to get its value!
jassert (isBlob());
return blob;
}
OSCColour OSCArgument::getColour() const noexcept
{
if (isColour())
return OSCColour::fromInt32 ((uint32) intValue);
jassertfalse; // you must check the type of an argument before attempting to get its value!
return { 0, 0, 0, 0 };
}
//==============================================================================
//==============================================================================
#if JUCE_UNIT_TESTS
class OSCArgumentTests : public UnitTest
{
public:
OSCArgumentTests()
: UnitTest ("OSCArgument class", UnitTestCategories::osc)
{}
MemoryBlock getMemoryBlockWithRandomData (size_t numBytes)
{
MemoryBlock block (numBytes);
Random rng = getRandom();
for (size_t i = 0; i < numBytes; ++i)
block[i] = (char) rng.nextInt (256);
return block;
}
void runTest()
{
runTestInitialisation();
}
void runTestInitialisation()
{
beginTest ("Int32");
{
int value = 123456789;
OSCArgument arg (value);
expect (arg.getType() == OSCTypes::int32);
expect (arg.isInt32());
expect (! arg.isFloat32());
expect (! arg.isString());
expect (! arg.isBlob());
expect (! arg.isColour());
expect (arg.getInt32() == value);
}
beginTest ("Float32");
{
float value = 12345.6789f;
OSCArgument arg (value);
expect (arg.getType() == OSCTypes::float32);
expect (! arg.isInt32());
expect (arg.isFloat32());
expect (! arg.isString());
expect (! arg.isBlob());
expect (! arg.isColour());
expect (arg.getFloat32() == value);
}
beginTest ("String");
{
String value = "Hello, World!";
OSCArgument arg (value);
expect (arg.getType() == OSCTypes::string);
expect (! arg.isInt32());
expect (! arg.isFloat32());
expect (arg.isString());
expect (! arg.isBlob());
expect (! arg.isColour());
expect (arg.getString() == value);
}
beginTest ("String (from C string)");
{
OSCArgument arg ("Hello, World!");
expect (arg.getType() == OSCTypes::string);
expect (! arg.isInt32());
expect (! arg.isFloat32());
expect (arg.isString());
expect (! arg.isBlob());
expect (! arg.isColour());
expect (arg.getString() == "Hello, World!");
}
beginTest ("Blob");
{
auto blob = getMemoryBlockWithRandomData (413);
OSCArgument arg (blob);
expect (arg.getType() == OSCTypes::blob);
expect (! arg.isInt32());
expect (! arg.isFloat32());
expect (! arg.isString());
expect (arg.isBlob());
expect (! arg.isColour());
expect (arg.getBlob() == blob);
}
beginTest ("Colour");
{
Random rng = getRandom();
for (int i = 100; --i >= 0;)
{
OSCColour col = { (uint8) rng.nextInt (256),
(uint8) rng.nextInt (256),
(uint8) rng.nextInt (256),
(uint8) rng.nextInt (256) };
OSCArgument arg (col);
expect (arg.getType() == OSCTypes::colour);
expect (! arg.isInt32());
expect (! arg.isFloat32());
expect (! arg.isString());
expect (! arg.isBlob());
expect (arg.isColour());
expect (arg.getColour().toInt32() == col.toInt32());
}
}
beginTest ("Copy, move and assignment");
{
{
int value = -42;
OSCArgument arg (value);
OSCArgument copy = arg;
expect (copy.getType() == OSCTypes::int32);
expect (copy.getInt32() == value);
OSCArgument assignment ("this will be overwritten!");
assignment = copy;
expect (assignment.getType() == OSCTypes::int32);
expect (assignment.getInt32() == value);
}
{
const size_t numBytes = 412;
MemoryBlock blob = getMemoryBlockWithRandomData (numBytes);
OSCArgument arg (blob);
OSCArgument copy = arg;
expect (copy.getType() == OSCTypes::blob);
expect (copy.getBlob() == blob);
OSCArgument assignment ("this will be overwritten!");
assignment = copy;
expect (assignment.getType() == OSCTypes::blob);
expect (assignment.getBlob() == blob);
}
}
}
};
static OSCArgumentTests OSCArgumentUnitTests;
#endif
} // namespace juce
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
OSCArgument::OSCArgument (int32 v) : type (OSCTypes::int32), intValue (v) {}
OSCArgument::OSCArgument (float v) : type (OSCTypes::float32), floatValue (v) {}
OSCArgument::OSCArgument (const String& s) : type (OSCTypes::string), stringValue (s) {}
OSCArgument::OSCArgument (MemoryBlock b) : type (OSCTypes::blob), blob (std::move (b)) {}
OSCArgument::OSCArgument (OSCColour c) : type (OSCTypes::colour), intValue ((int32) c.toInt32()) {}
//==============================================================================
String OSCArgument::getString() const noexcept
{
if (isString())
return stringValue;
jassertfalse; // you must check the type of an argument before attempting to get its value!
return {};
}
int32 OSCArgument::getInt32() const noexcept
{
if (isInt32())
return intValue;
jassertfalse; // you must check the type of an argument before attempting to get its value!
return 0;
}
float OSCArgument::getFloat32() const noexcept
{
if (isFloat32())
return floatValue;
jassertfalse; // you must check the type of an argument before attempting to get its value!
return 0.0f;
}
const MemoryBlock& OSCArgument::getBlob() const noexcept
{
// you must check the type of an argument before attempting to get its value!
jassert (isBlob());
return blob;
}
OSCColour OSCArgument::getColour() const noexcept
{
if (isColour())
return OSCColour::fromInt32 ((uint32) intValue);
jassertfalse; // you must check the type of an argument before attempting to get its value!
return { 0, 0, 0, 0 };
}
//==============================================================================
//==============================================================================
#if JUCE_UNIT_TESTS
class OSCArgumentTests : public UnitTest
{
public:
OSCArgumentTests()
: UnitTest ("OSCArgument class", UnitTestCategories::osc)
{}
MemoryBlock getMemoryBlockWithRandomData (size_t numBytes)
{
MemoryBlock block (numBytes);
Random rng = getRandom();
for (size_t i = 0; i < numBytes; ++i)
block[i] = (char) rng.nextInt (256);
return block;
}
void runTest()
{
runTestInitialisation();
}
void runTestInitialisation()
{
beginTest ("Int32");
{
int value = 123456789;
OSCArgument arg (value);
expect (arg.getType() == OSCTypes::int32);
expect (arg.isInt32());
expect (! arg.isFloat32());
expect (! arg.isString());
expect (! arg.isBlob());
expect (! arg.isColour());
expect (arg.getInt32() == value);
}
beginTest ("Float32");
{
float value = 12345.6789f;
OSCArgument arg (value);
expect (arg.getType() == OSCTypes::float32);
expect (! arg.isInt32());
expect (arg.isFloat32());
expect (! arg.isString());
expect (! arg.isBlob());
expect (! arg.isColour());
expect (arg.getFloat32() == value);
}
beginTest ("String");
{
String value = "Hello, World!";
OSCArgument arg (value);
expect (arg.getType() == OSCTypes::string);
expect (! arg.isInt32());
expect (! arg.isFloat32());
expect (arg.isString());
expect (! arg.isBlob());
expect (! arg.isColour());
expect (arg.getString() == value);
}
beginTest ("String (from C string)");
{
OSCArgument arg ("Hello, World!");
expect (arg.getType() == OSCTypes::string);
expect (! arg.isInt32());
expect (! arg.isFloat32());
expect (arg.isString());
expect (! arg.isBlob());
expect (! arg.isColour());
expect (arg.getString() == "Hello, World!");
}
beginTest ("Blob");
{
auto blob = getMemoryBlockWithRandomData (413);
OSCArgument arg (blob);
expect (arg.getType() == OSCTypes::blob);
expect (! arg.isInt32());
expect (! arg.isFloat32());
expect (! arg.isString());
expect (arg.isBlob());
expect (! arg.isColour());
expect (arg.getBlob() == blob);
}
beginTest ("Colour");
{
Random rng = getRandom();
for (int i = 100; --i >= 0;)
{
OSCColour col = { (uint8) rng.nextInt (256),
(uint8) rng.nextInt (256),
(uint8) rng.nextInt (256),
(uint8) rng.nextInt (256) };
OSCArgument arg (col);
expect (arg.getType() == OSCTypes::colour);
expect (! arg.isInt32());
expect (! arg.isFloat32());
expect (! arg.isString());
expect (! arg.isBlob());
expect (arg.isColour());
expect (arg.getColour().toInt32() == col.toInt32());
}
}
beginTest ("Copy, move and assignment");
{
{
int value = -42;
OSCArgument arg (value);
OSCArgument copy = arg;
expect (copy.getType() == OSCTypes::int32);
expect (copy.getInt32() == value);
OSCArgument assignment ("this will be overwritten!");
assignment = copy;
expect (assignment.getType() == OSCTypes::int32);
expect (assignment.getInt32() == value);
}
{
const size_t numBytes = 412;
MemoryBlock blob = getMemoryBlockWithRandomData (numBytes);
OSCArgument arg (blob);
OSCArgument copy = arg;
expect (copy.getType() == OSCTypes::blob);
expect (copy.getBlob() == blob);
OSCArgument assignment ("this will be overwritten!");
assignment = copy;
expect (assignment.getType() == OSCTypes::blob);
expect (assignment.getBlob() == blob);
}
}
}
};
static OSCArgumentTests OSCArgumentUnitTests;
#endif
} // namespace juce

View File

@ -1,124 +1,124 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/**
An OSC argument.
An OSC argument is a value of one of the following types: int32, float32, string,
or blob (raw binary data).
OSCMessage objects are essentially arrays of OSCArgument objects.
@tags{OSC}
*/
class JUCE_API OSCArgument
{
public:
/** Constructs an OSCArgument with type int32 and a given value. */
OSCArgument (int32 value);
/** Constructs an OSCArgument with type float32 and a given value. */
OSCArgument (float value);
/** Constructs an OSCArgument with type string and a given value */
OSCArgument (const String& value);
/** Constructs an OSCArgument with type blob and copies dataSize bytes
from the memory pointed to by data into the blob.
The data owned by the blob will be released when the OSCArgument object
gets destructed.
*/
OSCArgument (MemoryBlock blob);
/** Constructs an OSCArgument with type colour and a given colour value */
OSCArgument (OSCColour colour);
/** Returns the type of the OSCArgument as an OSCType.
OSCType is a char type, and its value will be the OSC type tag of the type.
*/
OSCType getType() const noexcept { return type; }
/** Returns whether the type of the OSCArgument is int32. */
bool isInt32() const noexcept { return type == OSCTypes::int32; }
/** Returns whether the type of the OSCArgument is float. */
bool isFloat32() const noexcept { return type == OSCTypes::float32; }
/** Returns whether the type of the OSCArgument is string. */
bool isString() const noexcept { return type == OSCTypes::string; }
/** Returns whether the type of the OSCArgument is blob. */
bool isBlob() const noexcept { return type == OSCTypes::blob; }
/** Returns whether the type of the OSCArgument is colour. */
bool isColour() const noexcept { return type == OSCTypes::colour; }
/** Returns the value of the OSCArgument as an int32.
If the type of the OSCArgument is not int32, the behaviour is undefined.
*/
int32 getInt32() const noexcept;
/** Returns the value of the OSCArgument as a float32.
If the type of the OSCArgument is not float32, the behaviour is undefined.
*/
float getFloat32() const noexcept;
/** Returns the value of the OSCArgument as a string.
If the type of the OSCArgument is not string, the behaviour is undefined.
*/
String getString() const noexcept;
/** Returns the binary data contained in the blob and owned by the OSCArgument,
as a reference to a JUCE MemoryBlock object.
If the type of the OSCArgument is not blob, the behaviour is undefined.
*/
const MemoryBlock& getBlob() const noexcept;
/** Returns the value of the OSCArgument as an OSCColour.
If the type of the OSCArgument is not a colour, the behaviour is undefined.
*/
OSCColour getColour() const noexcept;
private:
//==============================================================================
OSCType type;
union
{
int32 intValue;
float floatValue;
};
String stringValue;
MemoryBlock blob;
};
} // namespace juce
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/**
An OSC argument.
An OSC argument is a value of one of the following types: int32, float32, string,
or blob (raw binary data).
OSCMessage objects are essentially arrays of OSCArgument objects.
@tags{OSC}
*/
class JUCE_API OSCArgument
{
public:
/** Constructs an OSCArgument with type int32 and a given value. */
OSCArgument (int32 value);
/** Constructs an OSCArgument with type float32 and a given value. */
OSCArgument (float value);
/** Constructs an OSCArgument with type string and a given value */
OSCArgument (const String& value);
/** Constructs an OSCArgument with type blob and copies dataSize bytes
from the memory pointed to by data into the blob.
The data owned by the blob will be released when the OSCArgument object
gets destructed.
*/
OSCArgument (MemoryBlock blob);
/** Constructs an OSCArgument with type colour and a given colour value */
OSCArgument (OSCColour colour);
/** Returns the type of the OSCArgument as an OSCType.
OSCType is a char type, and its value will be the OSC type tag of the type.
*/
OSCType getType() const noexcept { return type; }
/** Returns whether the type of the OSCArgument is int32. */
bool isInt32() const noexcept { return type == OSCTypes::int32; }
/** Returns whether the type of the OSCArgument is float. */
bool isFloat32() const noexcept { return type == OSCTypes::float32; }
/** Returns whether the type of the OSCArgument is string. */
bool isString() const noexcept { return type == OSCTypes::string; }
/** Returns whether the type of the OSCArgument is blob. */
bool isBlob() const noexcept { return type == OSCTypes::blob; }
/** Returns whether the type of the OSCArgument is colour. */
bool isColour() const noexcept { return type == OSCTypes::colour; }
/** Returns the value of the OSCArgument as an int32.
If the type of the OSCArgument is not int32, the behaviour is undefined.
*/
int32 getInt32() const noexcept;
/** Returns the value of the OSCArgument as a float32.
If the type of the OSCArgument is not float32, the behaviour is undefined.
*/
float getFloat32() const noexcept;
/** Returns the value of the OSCArgument as a string.
If the type of the OSCArgument is not string, the behaviour is undefined.
*/
String getString() const noexcept;
/** Returns the binary data contained in the blob and owned by the OSCArgument,
as a reference to a JUCE MemoryBlock object.
If the type of the OSCArgument is not blob, the behaviour is undefined.
*/
const MemoryBlock& getBlob() const noexcept;
/** Returns the value of the OSCArgument as an OSCColour.
If the type of the OSCArgument is not a colour, the behaviour is undefined.
*/
OSCColour getColour() const noexcept;
private:
//==============================================================================
OSCType type;
union
{
int32 intValue;
float floatValue;
};
String stringValue;
MemoryBlock blob;
};
} // namespace juce

View File

@ -1,249 +1,249 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
OSCBundle::OSCBundle()
{
}
OSCBundle::OSCBundle (OSCTimeTag t) : timeTag (t)
{
}
// Note: The class invariant of OSCBundle::Element is that
// at least one of the pointers bundle and message is nullptr
// and the other one always points to a valid object.
OSCBundle::Element::Element (OSCMessage m)
: message (new OSCMessage (m)), bundle (nullptr)
{
}
OSCBundle::Element::Element (OSCBundle b)
: message (nullptr), bundle (new OSCBundle (b))
{
}
//==============================================================================
OSCBundle::Element::Element (const Element& other)
{
if (this != &other)
{
message = nullptr;
bundle = nullptr;
if (other.isMessage())
message.reset (new OSCMessage (other.getMessage()));
else
bundle.reset (new OSCBundle (other.getBundle()));
}
}
//==============================================================================
OSCBundle::Element::~Element()
{
bundle = nullptr;
message = nullptr;
}
//==============================================================================
bool OSCBundle::Element::isMessage() const noexcept
{
return message != nullptr;
}
bool OSCBundle::Element::isBundle() const noexcept
{
return bundle != nullptr;
}
//==============================================================================
const OSCMessage& OSCBundle::Element::getMessage() const
{
if (message == nullptr)
{
// This element is not a bundle! You must check this first before accessing.
jassertfalse;
throw OSCInternalError ("Access error in OSC bundle element.");
}
return *message;
}
//==============================================================================
const OSCBundle& OSCBundle::Element::getBundle() const
{
if (bundle == nullptr)
{
// This element is not a bundle! You must check this first before accessing.
jassertfalse;
throw OSCInternalError ("Access error in OSC bundle element.");
}
return *bundle;
}
//==============================================================================
//==============================================================================
#if JUCE_UNIT_TESTS
class OSCBundleTests : public UnitTest
{
public:
OSCBundleTests()
: UnitTest ("OSCBundle class", UnitTestCategories::osc)
{}
void runTest()
{
beginTest ("Construction");
{
OSCBundle bundle;
expect (bundle.getTimeTag().isImmediately());
}
beginTest ("Construction with time tag");
{
Time in100Seconds = (Time (Time::currentTimeMillis()) + RelativeTime (100.0));
OSCBundle bundle (in100Seconds);
expect (! bundle.getTimeTag().isImmediately());
expect (bundle.getTimeTag().toTime() == in100Seconds);
}
beginTest ("Usage when containing messages");
{
OSCBundle testBundle = generateTestBundle();
expectBundleEqualsTestBundle (testBundle);
}
beginTest ("Usage when containing other bundles (recursively)");
{
OSCBundle complexTestBundle;
complexTestBundle.addElement (generateTestBundle());
complexTestBundle.addElement (OSCMessage ("/test/"));
complexTestBundle.addElement (generateTestBundle());
expect (complexTestBundle.size() == 3);
OSCBundle::Element* elements = complexTestBundle.begin();
expect (! elements[0].isMessage());
expect (elements[0].isBundle());
expect (elements[1].isMessage());
expect (! elements[1].isBundle());
expect (! elements[2].isMessage());
expect (elements[2].isBundle());
expectBundleEqualsTestBundle (elements[0].getBundle());
expect (elements[1].getMessage().size() == 0);
expect (elements[1].getMessage().getAddressPattern().toString() == "/test");
expectBundleEqualsTestBundle (elements[2].getBundle());
}
}
private:
int testInt = 127;
float testFloat = 1.5;
OSCBundle generateTestBundle()
{
OSCBundle bundle;
OSCMessage msg1 ("/test/fader");
msg1.addInt32 (testInt);
OSCMessage msg2 ("/test/foo");
msg2.addString ("bar");
msg2.addFloat32 (testFloat);
bundle.addElement (msg1);
bundle.addElement (msg2);
return bundle;
}
void expectBundleEqualsTestBundle (const OSCBundle& bundle)
{
expect (bundle.size() == 2);
expect (bundle[0].isMessage());
expect (! bundle[0].isBundle());
expect (bundle[1].isMessage());
expect (! bundle[1].isBundle());
int numElementsCounted = 0;
for (auto& element : bundle)
{
expect (element.isMessage());
expect (! element.isBundle());
++numElementsCounted;
}
expectEquals (numElementsCounted, 2);
auto* e = bundle.begin();
expect (e[0].getMessage().size() == 1);
expect (e[0].getMessage().begin()->getInt32() == testInt);
expect (e[1].getMessage().size() == 2);
expect (e[1].getMessage()[1].getFloat32() == testFloat);
}
};
static OSCBundleTests OSCBundleUnitTests;
//==============================================================================
class OSCBundleElementTests : public UnitTest
{
public:
OSCBundleElementTests()
: UnitTest ("OSCBundle::Element class", UnitTestCategories::osc)
{}
void runTest()
{
beginTest ("Construction from OSCMessage");
{
float testFloat = -0.125;
OSCMessage msg ("/test");
msg.addFloat32 (testFloat);
OSCBundle::Element element (msg);
expect (element.isMessage());
expect (element.getMessage().size() == 1);
expect (element.getMessage()[0].getType() == OSCTypes::float32);
expect (element.getMessage()[0].getFloat32() == testFloat);
}
}
};
static OSCBundleElementTests OSCBundleElementUnitTests;
#endif
} // namespace juce
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
OSCBundle::OSCBundle()
{
}
OSCBundle::OSCBundle (OSCTimeTag t) : timeTag (t)
{
}
// Note: The class invariant of OSCBundle::Element is that
// at least one of the pointers bundle and message is nullptr
// and the other one always points to a valid object.
OSCBundle::Element::Element (OSCMessage m)
: message (new OSCMessage (m)), bundle (nullptr)
{
}
OSCBundle::Element::Element (OSCBundle b)
: message (nullptr), bundle (new OSCBundle (b))
{
}
//==============================================================================
OSCBundle::Element::Element (const Element& other)
{
if (this != &other)
{
message = nullptr;
bundle = nullptr;
if (other.isMessage())
message.reset (new OSCMessage (other.getMessage()));
else
bundle.reset (new OSCBundle (other.getBundle()));
}
}
//==============================================================================
OSCBundle::Element::~Element()
{
bundle = nullptr;
message = nullptr;
}
//==============================================================================
bool OSCBundle::Element::isMessage() const noexcept
{
return message != nullptr;
}
bool OSCBundle::Element::isBundle() const noexcept
{
return bundle != nullptr;
}
//==============================================================================
const OSCMessage& OSCBundle::Element::getMessage() const
{
if (message == nullptr)
{
// This element is not a bundle! You must check this first before accessing.
jassertfalse;
throw OSCInternalError ("Access error in OSC bundle element.");
}
return *message;
}
//==============================================================================
const OSCBundle& OSCBundle::Element::getBundle() const
{
if (bundle == nullptr)
{
// This element is not a bundle! You must check this first before accessing.
jassertfalse;
throw OSCInternalError ("Access error in OSC bundle element.");
}
return *bundle;
}
//==============================================================================
//==============================================================================
#if JUCE_UNIT_TESTS
class OSCBundleTests : public UnitTest
{
public:
OSCBundleTests()
: UnitTest ("OSCBundle class", UnitTestCategories::osc)
{}
void runTest()
{
beginTest ("Construction");
{
OSCBundle bundle;
expect (bundle.getTimeTag().isImmediately());
}
beginTest ("Construction with time tag");
{
Time in100Seconds = (Time (Time::currentTimeMillis()) + RelativeTime (100.0));
OSCBundle bundle (in100Seconds);
expect (! bundle.getTimeTag().isImmediately());
expect (bundle.getTimeTag().toTime() == in100Seconds);
}
beginTest ("Usage when containing messages");
{
OSCBundle testBundle = generateTestBundle();
expectBundleEqualsTestBundle (testBundle);
}
beginTest ("Usage when containing other bundles (recursively)");
{
OSCBundle complexTestBundle;
complexTestBundle.addElement (generateTestBundle());
complexTestBundle.addElement (OSCMessage ("/test/"));
complexTestBundle.addElement (generateTestBundle());
expect (complexTestBundle.size() == 3);
OSCBundle::Element* elements = complexTestBundle.begin();
expect (! elements[0].isMessage());
expect (elements[0].isBundle());
expect (elements[1].isMessage());
expect (! elements[1].isBundle());
expect (! elements[2].isMessage());
expect (elements[2].isBundle());
expectBundleEqualsTestBundle (elements[0].getBundle());
expect (elements[1].getMessage().size() == 0);
expect (elements[1].getMessage().getAddressPattern().toString() == "/test");
expectBundleEqualsTestBundle (elements[2].getBundle());
}
}
private:
int testInt = 127;
float testFloat = 1.5;
OSCBundle generateTestBundle()
{
OSCBundle bundle;
OSCMessage msg1 ("/test/fader");
msg1.addInt32 (testInt);
OSCMessage msg2 ("/test/foo");
msg2.addString ("bar");
msg2.addFloat32 (testFloat);
bundle.addElement (msg1);
bundle.addElement (msg2);
return bundle;
}
void expectBundleEqualsTestBundle (const OSCBundle& bundle)
{
expect (bundle.size() == 2);
expect (bundle[0].isMessage());
expect (! bundle[0].isBundle());
expect (bundle[1].isMessage());
expect (! bundle[1].isBundle());
int numElementsCounted = 0;
for (auto& element : bundle)
{
expect (element.isMessage());
expect (! element.isBundle());
++numElementsCounted;
}
expectEquals (numElementsCounted, 2);
auto* e = bundle.begin();
expect (e[0].getMessage().size() == 1);
expect (e[0].getMessage().begin()->getInt32() == testInt);
expect (e[1].getMessage().size() == 2);
expect (e[1].getMessage()[1].getFloat32() == testFloat);
}
};
static OSCBundleTests OSCBundleUnitTests;
//==============================================================================
class OSCBundleElementTests : public UnitTest
{
public:
OSCBundleElementTests()
: UnitTest ("OSCBundle::Element class", UnitTestCategories::osc)
{}
void runTest()
{
beginTest ("Construction from OSCMessage");
{
float testFloat = -0.125;
OSCMessage msg ("/test");
msg.addFloat32 (testFloat);
OSCBundle::Element element (msg);
expect (element.isMessage());
expect (element.getMessage().size() == 1);
expect (element.getMessage()[0].getType() == OSCTypes::float32);
expect (element.getMessage()[0].getFloat32() == testFloat);
}
}
};
static OSCBundleElementTests OSCBundleElementUnitTests;
#endif
} // namespace juce

View File

@ -1,146 +1,146 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/**
An OSC bundle.
An OSCBundle contains an OSCTimeTag and zero or more OSCBundle Elements.
The elements of a bundle can be OSC messages or other OSC bundles (this
means that OSC bundles can be nested).
This is an advanced OSC structure useful to bundle OSC messages together
whose effects must occur simultaneously at some given time. For most
use cases it is probably enough to send and receive plain OSC messages.
@tags{OSC}
*/
class JUCE_API OSCBundle
{
public:
//==============================================================================
/** Constructs an OSCBundle with no content and a default time tag ("immediately"). */
OSCBundle();
/** Constructs an OSCBundle with no content and a given time tag. */
OSCBundle (OSCTimeTag timeTag);
//==============================================================================
/** Sets the OSCBundle's OSC time tag. */
void setTimeTag (OSCTimeTag newTimeTag) noexcept { timeTag = newTimeTag; }
/** Returns the OSCBundle's OSC time tag. */
OSCTimeTag getTimeTag() const noexcept { return timeTag; }
//==============================================================================
/**
An OSC bundle element.
An OSCBundle Element contains either one OSCMessage or one OSCBundle.
*/
class JUCE_API Element
{
public:
//==============================================================================
/** Constructs an OSCBundle Element from an OSCMessage. */
Element (OSCMessage message);
/** Constructs an OSCBundle Element from an OSCBundle. */
Element (OSCBundle bundle);
/** Copy constructor. */
Element (const Element& other);
/** Destructor. */
~Element();
/** Returns true if the OSCBundle element is an OSCMessage. */
bool isMessage() const noexcept;
/** Returns true if the OSCBundle element is an OSCBundle. */
bool isBundle() const noexcept;
/** Returns a reference to the contained OSCMessage.
If the OSCBundle element is not an OSCMessage, behaviour is undefined.
*/
const OSCMessage& getMessage() const;
/** Returns a reference to the contained OSCBundle.
If the OSCBundle element is not an OSCBundle, behaviour is undefined.
*/
const OSCBundle& getBundle() const;
private:
//==============================================================================
std::unique_ptr<OSCMessage> message;
std::unique_ptr<OSCBundle> bundle;
};
//==============================================================================
/** Returns the number of elements contained in the bundle. */
int size() const noexcept { return elements.size(); }
/** Returns true if the bundle contains no elements; false otherwise. */
bool isEmpty() const noexcept { return elements.isEmpty(); }
/** Returns a reference to the OSCBundle element at index i in this bundle.
This method does not check the range and results in undefined behaviour
in case i < 0 or i >= size().
*/
OSCBundle::Element& operator[] (const int i) noexcept
{
return elements.getReference (i);
}
const OSCBundle::Element& operator[] (const int i) const noexcept
{
return elements.getReference (i);
}
/** Adds an OSCBundleElement to the OSCBundle's content. s*/
void addElement (const OSCBundle::Element& element) { elements.add (element); }
/** Returns a pointer to the first element of the OSCBundle. */
OSCBundle::Element* begin() noexcept { return elements.begin(); }
/** Returns a pointer to the first element of the OSCBundle. */
const OSCBundle::Element* begin() const noexcept { return elements.begin(); }
/** Returns a pointer past the last element of the OSCBundle. */
OSCBundle::Element* end() noexcept { return elements.end(); }
/** Returns a pointer past the last element of the OSCBundle. */
const OSCBundle::Element* end() const noexcept { return elements.end(); }
private:
//==============================================================================
Array<OSCBundle::Element> elements;
OSCTimeTag timeTag;
};
} // namespace juce
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/**
An OSC bundle.
An OSCBundle contains an OSCTimeTag and zero or more OSCBundle Elements.
The elements of a bundle can be OSC messages or other OSC bundles (this
means that OSC bundles can be nested).
This is an advanced OSC structure useful to bundle OSC messages together
whose effects must occur simultaneously at some given time. For most
use cases it is probably enough to send and receive plain OSC messages.
@tags{OSC}
*/
class JUCE_API OSCBundle
{
public:
//==============================================================================
/** Constructs an OSCBundle with no content and a default time tag ("immediately"). */
OSCBundle();
/** Constructs an OSCBundle with no content and a given time tag. */
OSCBundle (OSCTimeTag timeTag);
//==============================================================================
/** Sets the OSCBundle's OSC time tag. */
void setTimeTag (OSCTimeTag newTimeTag) noexcept { timeTag = newTimeTag; }
/** Returns the OSCBundle's OSC time tag. */
OSCTimeTag getTimeTag() const noexcept { return timeTag; }
//==============================================================================
/**
An OSC bundle element.
An OSCBundle Element contains either one OSCMessage or one OSCBundle.
*/
class JUCE_API Element
{
public:
//==============================================================================
/** Constructs an OSCBundle Element from an OSCMessage. */
Element (OSCMessage message);
/** Constructs an OSCBundle Element from an OSCBundle. */
Element (OSCBundle bundle);
/** Copy constructor. */
Element (const Element& other);
/** Destructor. */
~Element();
/** Returns true if the OSCBundle element is an OSCMessage. */
bool isMessage() const noexcept;
/** Returns true if the OSCBundle element is an OSCBundle. */
bool isBundle() const noexcept;
/** Returns a reference to the contained OSCMessage.
If the OSCBundle element is not an OSCMessage, behaviour is undefined.
*/
const OSCMessage& getMessage() const;
/** Returns a reference to the contained OSCBundle.
If the OSCBundle element is not an OSCBundle, behaviour is undefined.
*/
const OSCBundle& getBundle() const;
private:
//==============================================================================
std::unique_ptr<OSCMessage> message;
std::unique_ptr<OSCBundle> bundle;
};
//==============================================================================
/** Returns the number of elements contained in the bundle. */
int size() const noexcept { return elements.size(); }
/** Returns true if the bundle contains no elements; false otherwise. */
bool isEmpty() const noexcept { return elements.isEmpty(); }
/** Returns a reference to the OSCBundle element at index i in this bundle.
This method does not check the range and results in undefined behaviour
in case i < 0 or i >= size().
*/
OSCBundle::Element& operator[] (const int i) noexcept
{
return elements.getReference (i);
}
const OSCBundle::Element& operator[] (const int i) const noexcept
{
return elements.getReference (i);
}
/** Adds an OSCBundleElement to the OSCBundle's content. s*/
void addElement (const OSCBundle::Element& element) { elements.add (element); }
/** Returns a pointer to the first element of the OSCBundle. */
OSCBundle::Element* begin() noexcept { return elements.begin(); }
/** Returns a pointer to the first element of the OSCBundle. */
const OSCBundle::Element* begin() const noexcept { return elements.begin(); }
/** Returns a pointer past the last element of the OSCBundle. */
OSCBundle::Element* end() noexcept { return elements.end(); }
/** Returns a pointer past the last element of the OSCBundle. */
const OSCBundle::Element* end() const noexcept { return elements.end(); }
private:
//==============================================================================
Array<OSCBundle::Element> elements;
OSCTimeTag timeTag;
};
} // namespace juce

View File

@ -1,227 +1,227 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
OSCMessage::OSCMessage (const OSCAddressPattern& ap) noexcept : addressPattern (ap)
{
}
//==============================================================================
void OSCMessage::setAddressPattern (const OSCAddressPattern& ap) noexcept
{
addressPattern = ap;
}
OSCAddressPattern OSCMessage::getAddressPattern() const noexcept
{
return addressPattern;
}
//==============================================================================
int OSCMessage::size() const noexcept
{
return arguments.size();
}
bool OSCMessage::isEmpty() const noexcept
{
return arguments.isEmpty();
}
OSCArgument& OSCMessage::operator[] (const int i) noexcept
{
return arguments.getReference (i);
}
const OSCArgument& OSCMessage::operator[] (const int i) const noexcept
{
return arguments.getReference (i);
}
OSCArgument* OSCMessage::begin() noexcept
{
return arguments.begin();
}
const OSCArgument* OSCMessage::begin() const noexcept
{
return arguments.begin();
}
OSCArgument* OSCMessage::end() noexcept
{
return arguments.end();
}
const OSCArgument* OSCMessage::end() const noexcept
{
return arguments.end();
}
void OSCMessage::clear()
{
arguments.clear();
}
//==============================================================================
void OSCMessage::addInt32 (int32 value) { arguments.add (OSCArgument (value)); }
void OSCMessage::addFloat32 (float value) { arguments.add (OSCArgument (value)); }
void OSCMessage::addString (const String& value) { arguments.add (OSCArgument (value)); }
void OSCMessage::addBlob (MemoryBlock blob) { arguments.add (OSCArgument (std::move (blob))); }
void OSCMessage::addColour (OSCColour colour) { arguments.add (OSCArgument (colour)); }
void OSCMessage::addArgument (OSCArgument arg) { arguments.add (arg); }
//==============================================================================
//==============================================================================
#if JUCE_UNIT_TESTS
class OSCMessageTests : public UnitTest
{
public:
OSCMessageTests()
: UnitTest ("OSCMessage class", UnitTestCategories::osc)
{}
void runTest()
{
beginTest ("Basic usage");
{
OSCMessage msg ("/test/param0");
expectEquals (msg.size(), 0);
expect (msg.getAddressPattern().toString() == "/test/param0");
const int numTestArgs = 5;
const int testInt = 42;
const float testFloat = 3.14159f;
const String testString = "Hello, World!";
const OSCColour testColour = { 10, 20, 150, 200 };
const uint8 testBlobData[5] = { 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
const MemoryBlock testBlob (testBlobData, sizeof (testBlobData));
msg.addInt32 (testInt);
msg.addFloat32 (testFloat);
msg.addString (testString);
msg.addBlob (testBlob);
msg.addColour (testColour);
expectEquals (msg.size(), numTestArgs);
expectEquals (msg[0].getType(), OSCTypes::int32);
expectEquals (msg[1].getType(), OSCTypes::float32);
expectEquals (msg[2].getType(), OSCTypes::string);
expectEquals (msg[3].getType(), OSCTypes::blob);
expectEquals (msg[4].getType(), OSCTypes::colour);
expect (msg[0].isInt32());
expect (msg[1].isFloat32());
expect (msg[2].isString());
expect (msg[3].isBlob());
expect (msg[4].isColour());
expectEquals (msg[0].getInt32(), testInt);
expectEquals (msg[1].getFloat32(), testFloat);
expectEquals (msg[2].getString(), testString);
expect (msg[3].getBlob() == testBlob);
expect (msg[4].getColour().toInt32() == testColour.toInt32());
expect (msg.begin() + numTestArgs == msg.end());
auto arg = msg.begin();
expect (arg->isInt32());
expectEquals (arg->getInt32(), testInt);
++arg;
expect (arg->isFloat32());
expectEquals (arg->getFloat32(), testFloat);
++arg;
expect (arg->isString());
expectEquals (arg->getString(), testString);
++arg;
expect (arg->isBlob());
expect (arg->getBlob() == testBlob);
++arg;
expect (arg->isColour());
expect (arg->getColour().toInt32() == testColour.toInt32());
++arg;
expect (arg == msg.end());
}
beginTest ("Initialisation with argument list (C++11 only)");
{
int testInt = 42;
float testFloat = 5.5;
String testString = "Hello, World!";
{
OSCMessage msg ("/test", testInt);
expect (msg.getAddressPattern().toString() == String ("/test"));
expectEquals (msg.size(), 1);
expect (msg[0].isInt32());
expectEquals (msg[0].getInt32(), testInt);
}
{
OSCMessage msg ("/test", testFloat);
expect (msg.getAddressPattern().toString() == String ("/test"));
expectEquals (msg.size(), 1);
expect (msg[0].isFloat32());
expectEquals (msg[0].getFloat32(), testFloat);
}
{
OSCMessage msg ("/test", testString);
expect (msg.getAddressPattern().toString() == String ("/test"));
expectEquals (msg.size(), 1);
expect (msg[0].isString());
expectEquals (msg[0].getString(), testString);
}
{
OSCMessage msg ("/test", testInt, testFloat, testString, testFloat, testInt);
expect (msg.getAddressPattern().toString() == String ("/test"));
expectEquals (msg.size(), 5);
expect (msg[0].isInt32());
expect (msg[1].isFloat32());
expect (msg[2].isString());
expect (msg[3].isFloat32());
expect (msg[4].isInt32());
expectEquals (msg[0].getInt32(), testInt);
expectEquals (msg[1].getFloat32(), testFloat);
expectEquals (msg[2].getString(), testString);
expectEquals (msg[3].getFloat32(), testFloat);
expectEquals (msg[4].getInt32(), testInt);
}
}
}
};
static OSCMessageTests OSCMessageUnitTests;
#endif
} // namespace juce
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
OSCMessage::OSCMessage (const OSCAddressPattern& ap) noexcept : addressPattern (ap)
{
}
//==============================================================================
void OSCMessage::setAddressPattern (const OSCAddressPattern& ap) noexcept
{
addressPattern = ap;
}
OSCAddressPattern OSCMessage::getAddressPattern() const noexcept
{
return addressPattern;
}
//==============================================================================
int OSCMessage::size() const noexcept
{
return arguments.size();
}
bool OSCMessage::isEmpty() const noexcept
{
return arguments.isEmpty();
}
OSCArgument& OSCMessage::operator[] (const int i) noexcept
{
return arguments.getReference (i);
}
const OSCArgument& OSCMessage::operator[] (const int i) const noexcept
{
return arguments.getReference (i);
}
OSCArgument* OSCMessage::begin() noexcept
{
return arguments.begin();
}
const OSCArgument* OSCMessage::begin() const noexcept
{
return arguments.begin();
}
OSCArgument* OSCMessage::end() noexcept
{
return arguments.end();
}
const OSCArgument* OSCMessage::end() const noexcept
{
return arguments.end();
}
void OSCMessage::clear()
{
arguments.clear();
}
//==============================================================================
void OSCMessage::addInt32 (int32 value) { arguments.add (OSCArgument (value)); }
void OSCMessage::addFloat32 (float value) { arguments.add (OSCArgument (value)); }
void OSCMessage::addString (const String& value) { arguments.add (OSCArgument (value)); }
void OSCMessage::addBlob (MemoryBlock blob) { arguments.add (OSCArgument (std::move (blob))); }
void OSCMessage::addColour (OSCColour colour) { arguments.add (OSCArgument (colour)); }
void OSCMessage::addArgument (OSCArgument arg) { arguments.add (arg); }
//==============================================================================
//==============================================================================
#if JUCE_UNIT_TESTS
class OSCMessageTests : public UnitTest
{
public:
OSCMessageTests()
: UnitTest ("OSCMessage class", UnitTestCategories::osc)
{}
void runTest()
{
beginTest ("Basic usage");
{
OSCMessage msg ("/test/param0");
expectEquals (msg.size(), 0);
expect (msg.getAddressPattern().toString() == "/test/param0");
const int numTestArgs = 5;
const int testInt = 42;
const float testFloat = 3.14159f;
const String testString = "Hello, World!";
const OSCColour testColour = { 10, 20, 150, 200 };
const uint8 testBlobData[5] = { 0xBB, 0xCC, 0xDD, 0xEE, 0xFF };
const MemoryBlock testBlob (testBlobData, sizeof (testBlobData));
msg.addInt32 (testInt);
msg.addFloat32 (testFloat);
msg.addString (testString);
msg.addBlob (testBlob);
msg.addColour (testColour);
expectEquals (msg.size(), numTestArgs);
expectEquals (msg[0].getType(), OSCTypes::int32);
expectEquals (msg[1].getType(), OSCTypes::float32);
expectEquals (msg[2].getType(), OSCTypes::string);
expectEquals (msg[3].getType(), OSCTypes::blob);
expectEquals (msg[4].getType(), OSCTypes::colour);
expect (msg[0].isInt32());
expect (msg[1].isFloat32());
expect (msg[2].isString());
expect (msg[3].isBlob());
expect (msg[4].isColour());
expectEquals (msg[0].getInt32(), testInt);
expectEquals (msg[1].getFloat32(), testFloat);
expectEquals (msg[2].getString(), testString);
expect (msg[3].getBlob() == testBlob);
expect (msg[4].getColour().toInt32() == testColour.toInt32());
expect (msg.begin() + numTestArgs == msg.end());
auto arg = msg.begin();
expect (arg->isInt32());
expectEquals (arg->getInt32(), testInt);
++arg;
expect (arg->isFloat32());
expectEquals (arg->getFloat32(), testFloat);
++arg;
expect (arg->isString());
expectEquals (arg->getString(), testString);
++arg;
expect (arg->isBlob());
expect (arg->getBlob() == testBlob);
++arg;
expect (arg->isColour());
expect (arg->getColour().toInt32() == testColour.toInt32());
++arg;
expect (arg == msg.end());
}
beginTest ("Initialisation with argument list (C++11 only)");
{
int testInt = 42;
float testFloat = 5.5;
String testString = "Hello, World!";
{
OSCMessage msg ("/test", testInt);
expect (msg.getAddressPattern().toString() == String ("/test"));
expectEquals (msg.size(), 1);
expect (msg[0].isInt32());
expectEquals (msg[0].getInt32(), testInt);
}
{
OSCMessage msg ("/test", testFloat);
expect (msg.getAddressPattern().toString() == String ("/test"));
expectEquals (msg.size(), 1);
expect (msg[0].isFloat32());
expectEquals (msg[0].getFloat32(), testFloat);
}
{
OSCMessage msg ("/test", testString);
expect (msg.getAddressPattern().toString() == String ("/test"));
expectEquals (msg.size(), 1);
expect (msg[0].isString());
expectEquals (msg[0].getString(), testString);
}
{
OSCMessage msg ("/test", testInt, testFloat, testString, testFloat, testInt);
expect (msg.getAddressPattern().toString() == String ("/test"));
expectEquals (msg.size(), 5);
expect (msg[0].isInt32());
expect (msg[1].isFloat32());
expect (msg[2].isString());
expect (msg[3].isFloat32());
expect (msg[4].isInt32());
expectEquals (msg[0].getInt32(), testInt);
expectEquals (msg[1].getFloat32(), testFloat);
expectEquals (msg[2].getString(), testString);
expectEquals (msg[3].getFloat32(), testFloat);
expectEquals (msg[4].getInt32(), testInt);
}
}
}
};
static OSCMessageTests OSCMessageUnitTests;
#endif
} // namespace juce

View File

@ -1,183 +1,183 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/**
An OSC Message.
An OSCMessage consists of an OSCAddressPattern and zero or more OSCArguments.
OSC messages are the elementary objects that are used to exchange any data
via OSC. An OSCSender can send OSCMessage objects to an OSCReceiver.
@tags{OSC}
*/
class JUCE_API OSCMessage
{
public:
//==============================================================================
/** Constructs an OSCMessage object with the given address pattern and no
arguments.
@param ap the address pattern of the message. This must be a valid OSC
address (starting with a forward slash) and may contain
OSC wildcard expressions. You can pass in a string literal
or a juce String (they will be converted to an OSCAddressPattern
automatically).
*/
OSCMessage (const OSCAddressPattern& ap) noexcept;
/** Constructs an OSCMessage object with the given address pattern and list
of arguments.
@param ap the address pattern of the message. This must be a valid OSC
address (starting with a forward slash) and may contain
OSC wildcard expressions. You can pass in a string literal
or a juce String (they will be converted to an OSCAddressPattern
automatically).
@param arg1 the first argument of the message.
@param args an optional list of further arguments to add to the message.
*/
template <typename Arg1, typename... Args>
OSCMessage (const OSCAddressPattern& ap, Arg1&& arg1, Args&&... args);
/** Sets the address pattern of the OSCMessage.
@param ap the address pattern of the message. This must be a valid OSC
address (starting with a forward slash) and may contain
OSC wildcard expressions. You can pass in a string literal
or a juce String (they will be converted to an OSCAddressPattern
automatically).
*/
void setAddressPattern (const OSCAddressPattern& ap) noexcept;
/** Returns the address pattern of the OSCMessage. */
OSCAddressPattern getAddressPattern() const noexcept;
/** Returns the number of OSCArgument objects that belong to this OSCMessage. */
int size() const noexcept;
/** Returns true if the OSCMessage contains no OSCArgument objects; false otherwise. */
bool isEmpty() const noexcept;
/** Returns a reference to the OSCArgument at index i in the OSCMessage object.
This method does not check the range and results in undefined behaviour
in case i < 0 or i >= size().
*/
OSCArgument& operator[] (const int i) noexcept;
const OSCArgument& operator[] (const int i) const noexcept;
/** Returns a pointer to the first OSCArgument in the OSCMessage object.
This method is provided for compatibility with standard C++ iteration mechanisms.
*/
OSCArgument* begin() noexcept;
/** Returns a pointer to the first OSCArgument in the OSCMessage object.
This method is provided for compatibility with standard C++ iteration mechanisms.
*/
const OSCArgument* begin() const noexcept;
/** Returns a pointer to the last OSCArgument in the OSCMessage object.
This method is provided for compatibility with standard C++ iteration mechanisms.
*/
OSCArgument* end() noexcept;
/** Returns a pointer to the last OSCArgument in the OSCMessage object.
This method is provided for compatibility with standard C++ iteration mechanisms.
*/
const OSCArgument* end() const noexcept;
/** Removes all arguments from the OSCMessage. */
void clear();
//==============================================================================
/** Creates a new OSCArgument of type int32 with the given value,
and adds it to the OSCMessage object.
*/
void addInt32 (int32 value);
/** Creates a new OSCArgument of type float32 with the given value,
and adds it to the OSCMessage object.
*/
void addFloat32 (float value);
/** Creates a new OSCArgument of type string with the given value,
and adds it to the OSCMessage object.
*/
void addString (const String& value);
/** Creates a new OSCArgument of type blob with binary data content copied from
the given MemoryBlock.
Note: If the argument passed is an lvalue, this may copy the binary data.
*/
void addBlob (MemoryBlock blob);
/** Creates a new OSCArgument of type colour with the given value,
and adds it to the OSCMessage object.
*/
void addColour (OSCColour colour);
/** Adds the OSCArgument argument to the OSCMessage object.
Note: This method will result in a copy of the OSCArgument object if it is passed
as an lvalue. If the OSCArgument is of type blob, this will also copy the underlying
binary data. In general, you should use addInt32, addFloat32, etc. instead.
*/
void addArgument (OSCArgument argument);
private:
//==============================================================================
template <typename Arg1, typename... Args>
void addArguments (Arg1&& arg1, Args&&... args)
{
addArgument (arg1);
addArguments (std::forward<Args> (args)...);
}
void addArguments() {}
//==============================================================================
OSCAddressPattern addressPattern;
Array<OSCArgument> arguments;
};
//==============================================================================
template <typename Arg1, typename... Args>
OSCMessage::OSCMessage (const OSCAddressPattern& ap, Arg1&& arg1, Args&&... args)
: addressPattern (ap)
{
addArguments (std::forward<Arg1> (arg1), std::forward<Args> (args)...);
}
} // namespace juce
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/**
An OSC Message.
An OSCMessage consists of an OSCAddressPattern and zero or more OSCArguments.
OSC messages are the elementary objects that are used to exchange any data
via OSC. An OSCSender can send OSCMessage objects to an OSCReceiver.
@tags{OSC}
*/
class JUCE_API OSCMessage
{
public:
//==============================================================================
/** Constructs an OSCMessage object with the given address pattern and no
arguments.
@param ap the address pattern of the message. This must be a valid OSC
address (starting with a forward slash) and may contain
OSC wildcard expressions. You can pass in a string literal
or a juce String (they will be converted to an OSCAddressPattern
automatically).
*/
OSCMessage (const OSCAddressPattern& ap) noexcept;
/** Constructs an OSCMessage object with the given address pattern and list
of arguments.
@param ap the address pattern of the message. This must be a valid OSC
address (starting with a forward slash) and may contain
OSC wildcard expressions. You can pass in a string literal
or a juce String (they will be converted to an OSCAddressPattern
automatically).
@param arg1 the first argument of the message.
@param args an optional list of further arguments to add to the message.
*/
template <typename Arg1, typename... Args>
OSCMessage (const OSCAddressPattern& ap, Arg1&& arg1, Args&&... args);
/** Sets the address pattern of the OSCMessage.
@param ap the address pattern of the message. This must be a valid OSC
address (starting with a forward slash) and may contain
OSC wildcard expressions. You can pass in a string literal
or a juce String (they will be converted to an OSCAddressPattern
automatically).
*/
void setAddressPattern (const OSCAddressPattern& ap) noexcept;
/** Returns the address pattern of the OSCMessage. */
OSCAddressPattern getAddressPattern() const noexcept;
/** Returns the number of OSCArgument objects that belong to this OSCMessage. */
int size() const noexcept;
/** Returns true if the OSCMessage contains no OSCArgument objects; false otherwise. */
bool isEmpty() const noexcept;
/** Returns a reference to the OSCArgument at index i in the OSCMessage object.
This method does not check the range and results in undefined behaviour
in case i < 0 or i >= size().
*/
OSCArgument& operator[] (const int i) noexcept;
const OSCArgument& operator[] (const int i) const noexcept;
/** Returns a pointer to the first OSCArgument in the OSCMessage object.
This method is provided for compatibility with standard C++ iteration mechanisms.
*/
OSCArgument* begin() noexcept;
/** Returns a pointer to the first OSCArgument in the OSCMessage object.
This method is provided for compatibility with standard C++ iteration mechanisms.
*/
const OSCArgument* begin() const noexcept;
/** Returns a pointer to the last OSCArgument in the OSCMessage object.
This method is provided for compatibility with standard C++ iteration mechanisms.
*/
OSCArgument* end() noexcept;
/** Returns a pointer to the last OSCArgument in the OSCMessage object.
This method is provided for compatibility with standard C++ iteration mechanisms.
*/
const OSCArgument* end() const noexcept;
/** Removes all arguments from the OSCMessage. */
void clear();
//==============================================================================
/** Creates a new OSCArgument of type int32 with the given value,
and adds it to the OSCMessage object.
*/
void addInt32 (int32 value);
/** Creates a new OSCArgument of type float32 with the given value,
and adds it to the OSCMessage object.
*/
void addFloat32 (float value);
/** Creates a new OSCArgument of type string with the given value,
and adds it to the OSCMessage object.
*/
void addString (const String& value);
/** Creates a new OSCArgument of type blob with binary data content copied from
the given MemoryBlock.
Note: If the argument passed is an lvalue, this may copy the binary data.
*/
void addBlob (MemoryBlock blob);
/** Creates a new OSCArgument of type colour with the given value,
and adds it to the OSCMessage object.
*/
void addColour (OSCColour colour);
/** Adds the OSCArgument argument to the OSCMessage object.
Note: This method will result in a copy of the OSCArgument object if it is passed
as an lvalue. If the OSCArgument is of type blob, this will also copy the underlying
binary data. In general, you should use addInt32, addFloat32, etc. instead.
*/
void addArgument (OSCArgument argument);
private:
//==============================================================================
template <typename Arg1, typename... Args>
void addArguments (Arg1&& arg1, Args&&... args)
{
addArgument (arg1);
addArguments (std::forward<Args> (args)...);
}
void addArguments() {}
//==============================================================================
OSCAddressPattern addressPattern;
Array<OSCArgument> arguments;
};
//==============================================================================
template <typename Arg1, typename... Args>
OSCMessage::OSCMessage (const OSCAddressPattern& ap, Arg1&& arg1, Args&&... args)
: addressPattern (ap)
{
addArguments (std::forward<Arg1> (arg1), std::forward<Args> (args)...);
}
} // namespace juce

File diff suppressed because it is too large Load Diff

View File

@ -1,224 +1,224 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/**
A class for receiving OSC data.
An OSCReceiver object allows you to receive OSC bundles and messages.
It can connect to a network port, receive incoming OSC packets from the
network via UDP, parse them, and forward the included OSCMessage and OSCBundle
objects to its listeners.
@tags{OSC}
*/
class JUCE_API OSCReceiver
{
public:
//==============================================================================
/** Creates an OSCReceiver. */
OSCReceiver();
/** Creates an OSCReceiver with a specific name for its thread. */
OSCReceiver (const String& threadName);
/** Destructor. */
~OSCReceiver();
//==============================================================================
/** Connects to the specified UDP port using a datagram socket,
and starts listening to OSC packets arriving on this port.
@returns true if the connection was successful; false otherwise.
*/
bool connect (int portNumber);
/** Connects to a UDP datagram socket that is already set up,
and starts listening to OSC packets arriving on this port.
Make sure that the object you give it doesn't get deleted while this
object is still using it!
@returns true if the connection was successful; false otherwise.
*/
bool connectToSocket (DatagramSocket& socketToUse);
//==============================================================================
/** Disconnects from the currently used UDP port.
@returns true if the disconnection was successful; false otherwise.
*/
bool disconnect();
//==============================================================================
/** Use this struct as the template parameter for Listener and
ListenerWithOSCAddress to receive incoming OSC data on the message thread.
This should be used by OSC callbacks that are not realtime-critical, but
have significant work to do, for example updating Components in your app's
user interface.
This is the default type of OSC listener.
*/
struct JUCE_API MessageLoopCallback {};
/** Use this struct as the template parameter for Listener and
ListenerWithOSCAddress to receive incoming OSC data immediately after it
arrives, called directly on the network thread that listens to incoming
OSC traffic.
This type can be used by OSC callbacks that don't do much, but are
realtime-critical, for example, setting real-time audio parameters.
*/
struct JUCE_API RealtimeCallback {};
//==============================================================================
/** A class for receiving OSC data from an OSCReceiver.
The template argument CallbackType determines how the callback will be called
and has to be either MessageLoopCallback or RealtimeCallback. If not specified,
MessageLoopCallback will be used by default.
@see OSCReceiver::addListener, OSCReceiver::ListenerWithOSCAddress,
OSCReceiver::MessageLoopCallback, OSCReceiver::RealtimeCallback
*/
template <typename CallbackType = MessageLoopCallback>
class JUCE_API Listener
{
public:
/** Destructor. */
virtual ~Listener() = default;
/** Called when the OSCReceiver receives a new OSC message.
You must implement this function.
*/
virtual void oscMessageReceived (const OSCMessage& message) = 0;
/** Called when the OSCReceiver receives a new OSC bundle.
If you are not interested in OSC bundles, just ignore this method.
The default implementation provided here will simply do nothing.
*/
virtual void oscBundleReceived (const OSCBundle& /*bundle*/) {}
};
//==============================================================================
/** A class for receiving only those OSC messages from an OSCReceiver that match a
given OSC address.
Use this class if your app receives OSC messages with different address patterns
(for example "/juce/fader1", /juce/knob2" etc.) and you want to route those to
different objects. This class contains pre-build functionality for that OSC
address routing, including wildcard pattern matching (e.g. "/juce/fader[0-9]").
This class implements the concept of an "OSC Method" from the OpenSoundControl 1.0
specification.
The template argument CallbackType determines how the callback will be called
and has to be either MessageLoopCallback or RealtimeCallback. If not specified,
MessageLoopCallback will be used by default.
Note: This type of listener will ignore OSC bundles.
@see OSCReceiver::addListener, OSCReceiver::Listener,
OSCReceiver::MessageLoopCallback, OSCReceiver::RealtimeCallback
*/
template <typename CallbackType = MessageLoopCallback>
class JUCE_API ListenerWithOSCAddress
{
public:
/** Destructor. */
virtual ~ListenerWithOSCAddress() = default;
/** Called when the OSCReceiver receives an OSC message with an OSC address
pattern that matches the OSC address with which this listener was added.
*/
virtual void oscMessageReceived (const OSCMessage& message) = 0;
};
//==============================================================================
/** Adds a listener that listens to OSC messages and bundles.
This listener will be called on the application's message loop.
*/
void addListener (Listener<MessageLoopCallback>* listenerToAdd);
/** Adds a listener that listens to OSC messages and bundles.
This listener will be called in real-time directly on the network thread
that receives OSC data.
*/
void addListener (Listener<RealtimeCallback>* listenerToAdd);
/** Adds a filtered listener that listens to OSC messages matching the address
used to register the listener here.
The listener will be called on the application's message loop.
*/
void addListener (ListenerWithOSCAddress<MessageLoopCallback>* listenerToAdd,
OSCAddress addressToMatch);
/** Adds a filtered listener that listens to OSC messages matching the address
used to register the listener here.
The listener will be called on the application's message loop.
*/
void addListener (ListenerWithOSCAddress<RealtimeCallback>* listenerToAdd,
OSCAddress addressToMatch);
/** Removes a previously-registered listener. */
void removeListener (Listener<MessageLoopCallback>* listenerToRemove);
/** Removes a previously-registered listener. */
void removeListener (Listener<RealtimeCallback>* listenerToRemove);
/** Removes a previously-registered listener. */
void removeListener (ListenerWithOSCAddress<MessageLoopCallback>* listenerToRemove);
/** Removes a previously-registered listener. */
void removeListener (ListenerWithOSCAddress<RealtimeCallback>* listenerToRemove);
//==============================================================================
/** An error handler function for OSC format errors that can be called by the
OSCReceiver.
The arguments passed are the pointer to and the data of the buffer that
the OSCReceiver has failed to parse.
*/
using FormatErrorHandler = std::function<void (const char* data, int dataSize)>;
/** Installs a custom error handler which is called in case the receiver
encounters a stream it cannot parse as an OSC bundle or OSC message.
By default (i.e. if you never use this method), in case of a parsing error
nothing happens and the invalid packet is simply discarded.
*/
void registerFormatErrorHandler (FormatErrorHandler handler);
private:
//==============================================================================
struct Pimpl;
std::unique_ptr<Pimpl> pimpl;
friend struct OSCReceiverCallbackMessage;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OSCReceiver)
};
} // namespace juce
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/**
A class for receiving OSC data.
An OSCReceiver object allows you to receive OSC bundles and messages.
It can connect to a network port, receive incoming OSC packets from the
network via UDP, parse them, and forward the included OSCMessage and OSCBundle
objects to its listeners.
@tags{OSC}
*/
class JUCE_API OSCReceiver
{
public:
//==============================================================================
/** Creates an OSCReceiver. */
OSCReceiver();
/** Creates an OSCReceiver with a specific name for its thread. */
OSCReceiver (const String& threadName);
/** Destructor. */
~OSCReceiver();
//==============================================================================
/** Connects to the specified UDP port using a datagram socket,
and starts listening to OSC packets arriving on this port.
@returns true if the connection was successful; false otherwise.
*/
bool connect (int portNumber);
/** Connects to a UDP datagram socket that is already set up,
and starts listening to OSC packets arriving on this port.
Make sure that the object you give it doesn't get deleted while this
object is still using it!
@returns true if the connection was successful; false otherwise.
*/
bool connectToSocket (DatagramSocket& socketToUse);
//==============================================================================
/** Disconnects from the currently used UDP port.
@returns true if the disconnection was successful; false otherwise.
*/
bool disconnect();
//==============================================================================
/** Use this struct as the template parameter for Listener and
ListenerWithOSCAddress to receive incoming OSC data on the message thread.
This should be used by OSC callbacks that are not realtime-critical, but
have significant work to do, for example updating Components in your app's
user interface.
This is the default type of OSC listener.
*/
struct JUCE_API MessageLoopCallback {};
/** Use this struct as the template parameter for Listener and
ListenerWithOSCAddress to receive incoming OSC data immediately after it
arrives, called directly on the network thread that listens to incoming
OSC traffic.
This type can be used by OSC callbacks that don't do much, but are
realtime-critical, for example, setting real-time audio parameters.
*/
struct JUCE_API RealtimeCallback {};
//==============================================================================
/** A class for receiving OSC data from an OSCReceiver.
The template argument CallbackType determines how the callback will be called
and has to be either MessageLoopCallback or RealtimeCallback. If not specified,
MessageLoopCallback will be used by default.
@see OSCReceiver::addListener, OSCReceiver::ListenerWithOSCAddress,
OSCReceiver::MessageLoopCallback, OSCReceiver::RealtimeCallback
*/
template <typename CallbackType = MessageLoopCallback>
class JUCE_API Listener
{
public:
/** Destructor. */
virtual ~Listener() = default;
/** Called when the OSCReceiver receives a new OSC message.
You must implement this function.
*/
virtual void oscMessageReceived (const OSCMessage& message) = 0;
/** Called when the OSCReceiver receives a new OSC bundle.
If you are not interested in OSC bundles, just ignore this method.
The default implementation provided here will simply do nothing.
*/
virtual void oscBundleReceived (const OSCBundle& /*bundle*/) {}
};
//==============================================================================
/** A class for receiving only those OSC messages from an OSCReceiver that match a
given OSC address.
Use this class if your app receives OSC messages with different address patterns
(for example "/juce/fader1", /juce/knob2" etc.) and you want to route those to
different objects. This class contains pre-build functionality for that OSC
address routing, including wildcard pattern matching (e.g. "/juce/fader[0-9]").
This class implements the concept of an "OSC Method" from the OpenSoundControl 1.0
specification.
The template argument CallbackType determines how the callback will be called
and has to be either MessageLoopCallback or RealtimeCallback. If not specified,
MessageLoopCallback will be used by default.
Note: This type of listener will ignore OSC bundles.
@see OSCReceiver::addListener, OSCReceiver::Listener,
OSCReceiver::MessageLoopCallback, OSCReceiver::RealtimeCallback
*/
template <typename CallbackType = MessageLoopCallback>
class JUCE_API ListenerWithOSCAddress
{
public:
/** Destructor. */
virtual ~ListenerWithOSCAddress() = default;
/** Called when the OSCReceiver receives an OSC message with an OSC address
pattern that matches the OSC address with which this listener was added.
*/
virtual void oscMessageReceived (const OSCMessage& message) = 0;
};
//==============================================================================
/** Adds a listener that listens to OSC messages and bundles.
This listener will be called on the application's message loop.
*/
void addListener (Listener<MessageLoopCallback>* listenerToAdd);
/** Adds a listener that listens to OSC messages and bundles.
This listener will be called in real-time directly on the network thread
that receives OSC data.
*/
void addListener (Listener<RealtimeCallback>* listenerToAdd);
/** Adds a filtered listener that listens to OSC messages matching the address
used to register the listener here.
The listener will be called on the application's message loop.
*/
void addListener (ListenerWithOSCAddress<MessageLoopCallback>* listenerToAdd,
OSCAddress addressToMatch);
/** Adds a filtered listener that listens to OSC messages matching the address
used to register the listener here.
The listener will be called on the application's message loop.
*/
void addListener (ListenerWithOSCAddress<RealtimeCallback>* listenerToAdd,
OSCAddress addressToMatch);
/** Removes a previously-registered listener. */
void removeListener (Listener<MessageLoopCallback>* listenerToRemove);
/** Removes a previously-registered listener. */
void removeListener (Listener<RealtimeCallback>* listenerToRemove);
/** Removes a previously-registered listener. */
void removeListener (ListenerWithOSCAddress<MessageLoopCallback>* listenerToRemove);
/** Removes a previously-registered listener. */
void removeListener (ListenerWithOSCAddress<RealtimeCallback>* listenerToRemove);
//==============================================================================
/** An error handler function for OSC format errors that can be called by the
OSCReceiver.
The arguments passed are the pointer to and the data of the buffer that
the OSCReceiver has failed to parse.
*/
using FormatErrorHandler = std::function<void (const char* data, int dataSize)>;
/** Installs a custom error handler which is called in case the receiver
encounters a stream it cannot parse as an OSC bundle or OSC message.
By default (i.e. if you never use this method), in case of a parsing error
nothing happens and the invalid packet is simply discarded.
*/
void registerFormatErrorHandler (FormatErrorHandler handler);
private:
//==============================================================================
struct Pimpl;
std::unique_ptr<Pimpl> pimpl;
friend struct OSCReceiverCallbackMessage;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OSCReceiver)
};
} // namespace juce

File diff suppressed because it is too large Load Diff

View File

@ -1,163 +1,163 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/**
An OSC message sender.
An OSCSender object can connect to a network port. It then can send OSC
messages and bundles to a specified host over an UDP socket.
@tags{OSC}
*/
class JUCE_API OSCSender
{
public:
//==============================================================================
/** Constructs a new OSCSender. */
OSCSender();
/** Destructor. */
~OSCSender();
//==============================================================================
/** Connects to a datagram socket and prepares the socket for sending OSC
packets to the specified target.
Note: The operating system will choose which specific network adapter(s)
to bind your socket to, and which local port to use for the sender.
@param targetHostName The remote host to which messages will be send.
@param targetPortNumber The remote UDP port number on which the host will
receive the messages.
@returns true if the connection was successful; false otherwise.
@see send, disconnect.
*/
bool connect (const String& targetHostName, int targetPortNumber);
/** Uses an existing datagram socket for sending OSC packets to the specified target.
@param socket An existing datagram socket. Make sure this doesn't
get deleted while this class is still using it!
@param targetHostName The remote host to which messages will be send.
@param targetPortNumber The remote UDP port number on which the host will
receive the messages.
@returns true if the connection was successful; false otherwise.
@see connect, send, disconnect.
*/
bool connectToSocket (DatagramSocket& socket, const String& targetHostName, int targetPortNumber);
//==============================================================================
/** Disconnects from the currently used UDP port.
@returns true if the disconnection was successful; false otherwise.
@see connect.
*/
bool disconnect();
//==============================================================================
/** Sends an OSC message to the target.
@param message The OSC message to send.
@returns true if the operation was successful.
*/
bool send (const OSCMessage& message);
/** Send an OSC bundle to the target.
@param bundle The OSC bundle to send.
@returns true if the operation was successful.
*/
bool send (const OSCBundle& bundle);
/** Sends an OSC message to a specific IP address and port.
This overrides the address and port that was originally set for this sender.
@param targetIPAddress The IP address to send to
@param targetPortNumber The target port number
@param message The OSC message to send.
@returns true if the operation was successful.
*/
bool sendToIPAddress (const String& targetIPAddress, int targetPortNumber,
const OSCMessage& message);
/** Sends an OSC bundle to a specific IP address and port.
This overrides the address and port that was originally set for this sender.
@param targetIPAddress The IP address to send to
@param targetPortNumber The target port number
@param bundle The OSC bundle to send.
@returns true if the operation was successful.
*/
bool sendToIPAddress (const String& targetIPAddress, int targetPortNumber,
const OSCBundle& bundle);
/** Creates a new OSC message with the specified address pattern and list
of arguments, and sends it to the target.
@param address The OSC address pattern of the message
(you can use a string literal here).
@param args The list of arguments for the message.
*/
template <typename... Args>
bool send (const OSCAddressPattern& address, Args&&... args);
/** Creates a new OSC message with the specified address pattern and list
of arguments, and sends it to the target.
@param targetIPAddress The IP address to send to
@param targetPortNumber The target port number
@param address The OSC address pattern of the message
(you can use a string literal here).
@param args The list of arguments for the message.
*/
template <typename... Args>
bool sendToIPAddress (const String& targetIPAddress, int targetPortNumber,
const OSCAddressPattern& address, Args&&... args);
private:
//==============================================================================
struct Pimpl;
std::unique_ptr<Pimpl> pimpl;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OSCSender)
};
//==============================================================================
template <typename... Args>
bool OSCSender::send (const OSCAddressPattern& address, Args&&... args)
{
return send (OSCMessage (address, std::forward<Args> (args)...));
}
template <typename... Args>
bool OSCSender::sendToIPAddress (const String& targetIPAddress, int targetPortNumber,
const OSCAddressPattern& address, Args&&... args)
{
return sendToIPAddress (targetIPAddress, targetPortNumber, OSCMessage (address, std::forward<Args> (args)...));
}
} // namespace juce
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/**
An OSC message sender.
An OSCSender object can connect to a network port. It then can send OSC
messages and bundles to a specified host over an UDP socket.
@tags{OSC}
*/
class JUCE_API OSCSender
{
public:
//==============================================================================
/** Constructs a new OSCSender. */
OSCSender();
/** Destructor. */
~OSCSender();
//==============================================================================
/** Connects to a datagram socket and prepares the socket for sending OSC
packets to the specified target.
Note: The operating system will choose which specific network adapter(s)
to bind your socket to, and which local port to use for the sender.
@param targetHostName The remote host to which messages will be send.
@param targetPortNumber The remote UDP port number on which the host will
receive the messages.
@returns true if the connection was successful; false otherwise.
@see send, disconnect.
*/
bool connect (const String& targetHostName, int targetPortNumber);
/** Uses an existing datagram socket for sending OSC packets to the specified target.
@param socket An existing datagram socket. Make sure this doesn't
get deleted while this class is still using it!
@param targetHostName The remote host to which messages will be send.
@param targetPortNumber The remote UDP port number on which the host will
receive the messages.
@returns true if the connection was successful; false otherwise.
@see connect, send, disconnect.
*/
bool connectToSocket (DatagramSocket& socket, const String& targetHostName, int targetPortNumber);
//==============================================================================
/** Disconnects from the currently used UDP port.
@returns true if the disconnection was successful; false otherwise.
@see connect.
*/
bool disconnect();
//==============================================================================
/** Sends an OSC message to the target.
@param message The OSC message to send.
@returns true if the operation was successful.
*/
bool send (const OSCMessage& message);
/** Send an OSC bundle to the target.
@param bundle The OSC bundle to send.
@returns true if the operation was successful.
*/
bool send (const OSCBundle& bundle);
/** Sends an OSC message to a specific IP address and port.
This overrides the address and port that was originally set for this sender.
@param targetIPAddress The IP address to send to
@param targetPortNumber The target port number
@param message The OSC message to send.
@returns true if the operation was successful.
*/
bool sendToIPAddress (const String& targetIPAddress, int targetPortNumber,
const OSCMessage& message);
/** Sends an OSC bundle to a specific IP address and port.
This overrides the address and port that was originally set for this sender.
@param targetIPAddress The IP address to send to
@param targetPortNumber The target port number
@param bundle The OSC bundle to send.
@returns true if the operation was successful.
*/
bool sendToIPAddress (const String& targetIPAddress, int targetPortNumber,
const OSCBundle& bundle);
/** Creates a new OSC message with the specified address pattern and list
of arguments, and sends it to the target.
@param address The OSC address pattern of the message
(you can use a string literal here).
@param args The list of arguments for the message.
*/
template <typename... Args>
bool send (const OSCAddressPattern& address, Args&&... args);
/** Creates a new OSC message with the specified address pattern and list
of arguments, and sends it to the target.
@param targetIPAddress The IP address to send to
@param targetPortNumber The target port number
@param address The OSC address pattern of the message
(you can use a string literal here).
@param args The list of arguments for the message.
*/
template <typename... Args>
bool sendToIPAddress (const String& targetIPAddress, int targetPortNumber,
const OSCAddressPattern& address, Args&&... args);
private:
//==============================================================================
struct Pimpl;
std::unique_ptr<Pimpl> pimpl;
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OSCSender)
};
//==============================================================================
template <typename... Args>
bool OSCSender::send (const OSCAddressPattern& address, Args&&... args)
{
return send (OSCMessage (address, std::forward<Args> (args)...));
}
template <typename... Args>
bool OSCSender::sendToIPAddress (const String& targetIPAddress, int targetPortNumber,
const OSCAddressPattern& address, Args&&... args)
{
return sendToIPAddress (targetIPAddress, targetPortNumber, OSCMessage (address, std::forward<Args> (args)...));
}
} // namespace juce

View File

@ -1,155 +1,155 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
const OSCTimeTag OSCTimeTag::immediately;
static const uint64 millisecondsBetweenOscAndJuceEpochs = 2208988800000ULL;
static const uint64 rawTimeTagRepresentingImmediately = 0x0000000000000001ULL;
//==============================================================================
OSCTimeTag::OSCTimeTag() noexcept : rawTimeTag (rawTimeTagRepresentingImmediately)
{
}
OSCTimeTag::OSCTimeTag (uint64 t) noexcept : rawTimeTag (t)
{
}
OSCTimeTag::OSCTimeTag (Time time) noexcept
{
const uint64 milliseconds = (uint64) time.toMilliseconds() + millisecondsBetweenOscAndJuceEpochs;
uint64 seconds = milliseconds / 1000;
uint32 fractionalPart = uint32 (4294967.296 * (milliseconds % 1000));
rawTimeTag = (seconds << 32) + fractionalPart;
}
//==============================================================================
Time OSCTimeTag::toTime() const noexcept
{
const uint64 seconds = rawTimeTag >> 32;
const uint32 fractionalPart = (rawTimeTag & 0x00000000FFFFFFFFULL);
const auto fractionalPartInMillis = (double) fractionalPart / 4294967.296;
// now using signed integer, because this is allowed to become negative:
const auto juceTimeInMillis = (int64) (seconds * 1000)
+ (int64) roundToInt (fractionalPartInMillis)
- (int64) millisecondsBetweenOscAndJuceEpochs;
return Time (juceTimeInMillis);
}
//==============================================================================
bool OSCTimeTag::isImmediately() const noexcept
{
return rawTimeTag == rawTimeTagRepresentingImmediately;
}
//==============================================================================
//==============================================================================
#if JUCE_UNIT_TESTS
class OSCTimeTagTests : public UnitTest
{
public:
OSCTimeTagTests()
: UnitTest ("OSCTimeTag class", UnitTestCategories::osc)
{}
void runTest()
{
beginTest ("Basics");
{
OSCTimeTag tag;
expect (tag.isImmediately());
}
{
OSCTimeTag tag (3535653);
expect (! tag.isImmediately());
OSCTimeTag otherTag;
otherTag = tag;
expect (! otherTag.isImmediately());
OSCTimeTag copyTag (tag);
expect (! copyTag.isImmediately());
}
beginTest ("Conversion to/from JUCE Time");
{
Time time;
OSCTimeTag tag (time);
expect (! tag.isImmediately());
}
{
OSCTimeTag tag;
Time time = tag.toTime();
expect (time < Time::getCurrentTime());
}
{
Time currentTime (Time::currentTimeMillis());
double deltaInSeconds = 1.234;
RelativeTime delta (deltaInSeconds);
Time laterTime = currentTime + delta;
OSCTimeTag currentTimeTag (currentTime);
OSCTimeTag laterTimeTag (laterTime);
uint64 currentTimeTagRaw = currentTimeTag.getRawTimeTag();
uint64 laterTimeTagRaw = laterTimeTag.getRawTimeTag();
// in the raw time tag, the most significant 32 bits are seconds,
// so let's verify that the difference is right:
uint64 diff = laterTimeTagRaw - currentTimeTagRaw;
double acceptableErrorInSeconds = 0.000001; // definitely not audible anymore.
expect ((float) diff / float (1ULL << 32) < deltaInSeconds + acceptableErrorInSeconds );
expect ((float) diff / float (1ULL << 32) > deltaInSeconds - acceptableErrorInSeconds );
// round trip:
Time currentTime2 = currentTimeTag.toTime();
Time laterTime2 = laterTimeTag.toTime();
RelativeTime delta2 = laterTime2 - currentTime2;
expect (currentTime2 == currentTime);
expect (laterTime2 == laterTime);
expect (delta2 == delta);
}
}
};
static OSCTimeTagTests OSCTimeTagUnitTests;
#endif
} // namespace juce
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
const OSCTimeTag OSCTimeTag::immediately;
static const uint64 millisecondsBetweenOscAndJuceEpochs = 2208988800000ULL;
static const uint64 rawTimeTagRepresentingImmediately = 0x0000000000000001ULL;
//==============================================================================
OSCTimeTag::OSCTimeTag() noexcept : rawTimeTag (rawTimeTagRepresentingImmediately)
{
}
OSCTimeTag::OSCTimeTag (uint64 t) noexcept : rawTimeTag (t)
{
}
OSCTimeTag::OSCTimeTag (Time time) noexcept
{
const uint64 milliseconds = (uint64) time.toMilliseconds() + millisecondsBetweenOscAndJuceEpochs;
uint64 seconds = milliseconds / 1000;
uint32 fractionalPart = uint32 (4294967.296 * (milliseconds % 1000));
rawTimeTag = (seconds << 32) + fractionalPart;
}
//==============================================================================
Time OSCTimeTag::toTime() const noexcept
{
const uint64 seconds = rawTimeTag >> 32;
const uint32 fractionalPart = (rawTimeTag & 0x00000000FFFFFFFFULL);
const auto fractionalPartInMillis = (double) fractionalPart / 4294967.296;
// now using signed integer, because this is allowed to become negative:
const auto juceTimeInMillis = (int64) (seconds * 1000)
+ (int64) roundToInt (fractionalPartInMillis)
- (int64) millisecondsBetweenOscAndJuceEpochs;
return Time (juceTimeInMillis);
}
//==============================================================================
bool OSCTimeTag::isImmediately() const noexcept
{
return rawTimeTag == rawTimeTagRepresentingImmediately;
}
//==============================================================================
//==============================================================================
#if JUCE_UNIT_TESTS
class OSCTimeTagTests : public UnitTest
{
public:
OSCTimeTagTests()
: UnitTest ("OSCTimeTag class", UnitTestCategories::osc)
{}
void runTest()
{
beginTest ("Basics");
{
OSCTimeTag tag;
expect (tag.isImmediately());
}
{
OSCTimeTag tag (3535653);
expect (! tag.isImmediately());
OSCTimeTag otherTag;
otherTag = tag;
expect (! otherTag.isImmediately());
OSCTimeTag copyTag (tag);
expect (! copyTag.isImmediately());
}
beginTest ("Conversion to/from JUCE Time");
{
Time time;
OSCTimeTag tag (time);
expect (! tag.isImmediately());
}
{
OSCTimeTag tag;
Time time = tag.toTime();
expect (time < Time::getCurrentTime());
}
{
Time currentTime (Time::currentTimeMillis());
double deltaInSeconds = 1.234;
RelativeTime delta (deltaInSeconds);
Time laterTime = currentTime + delta;
OSCTimeTag currentTimeTag (currentTime);
OSCTimeTag laterTimeTag (laterTime);
uint64 currentTimeTagRaw = currentTimeTag.getRawTimeTag();
uint64 laterTimeTagRaw = laterTimeTag.getRawTimeTag();
// in the raw time tag, the most significant 32 bits are seconds,
// so let's verify that the difference is right:
uint64 diff = laterTimeTagRaw - currentTimeTagRaw;
double acceptableErrorInSeconds = 0.000001; // definitely not audible anymore.
expect ((float) diff / float (1ULL << 32) < deltaInSeconds + acceptableErrorInSeconds );
expect ((float) diff / float (1ULL << 32) > deltaInSeconds - acceptableErrorInSeconds );
// round trip:
Time currentTime2 = currentTimeTag.toTime();
Time laterTime2 = laterTimeTag.toTime();
RelativeTime delta2 = laterTime2 - currentTime2;
expect (currentTime2 == currentTime);
expect (laterTime2 == laterTime);
expect (delta2 == delta);
}
}
};
static OSCTimeTagTests OSCTimeTagUnitTests;
#endif
} // namespace juce

View File

@ -1,86 +1,86 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/**
An OSC time tag.
OSC time tags are part of OSCBundle objects.
In accordance with the OSC 1.0 specification, the internal timestamp stored in
OSCTimeTag uses the same binary format as NTP timestamps. The representation
is by a 64 bit fixed point number. The first 32 bits specify the number of
seconds since midnight on January 1, 1900, and the last 32 bits specify
fractional parts of a second to a precision of about 200 picoseconds.
The time tag value consisting of 63 zero bits followed by a one in the least
significant bit is a special case meaning "immediately".
For a more user-friendly time format, convert OSCTimeTag to a juce::Time object
using toTime().
@tags{OSC}
*/
class JUCE_API OSCTimeTag
{
public:
//==============================================================================
/** Default constructor.
Constructs an OSCTimeTag object with the special value representing "immediately".
*/
OSCTimeTag() noexcept;
/** Constructs an OSCTimeTag object from a raw binary OSC time tag. */
OSCTimeTag (uint64 rawTimeTag) noexcept;
/** Constructs an OSCTimeTag object from a juce::Time object. */
OSCTimeTag (Time time) noexcept;
/** Returns a juce::Time object representing the same time as the OSCTimeTag.
If the OSCTimeTag has the special value representing "immediately", the
resulting juce::Time object will represent an arbitrary point of time (but
guaranteed to be in the past), since juce::Time does not have such a special value.
*/
Time toTime() const noexcept;
/** Returns true if the OSCTimeTag object has the special value representing "immediately". */
bool isImmediately() const noexcept;
/** Returns the raw binary OSC time tag representation. */
uint64 getRawTimeTag() const noexcept { return rawTimeTag; }
/** The special value representing "immediately". */
static const OSCTimeTag immediately;
private:
//==============================================================================
uint64 rawTimeTag;
};
} // namespace juce
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/**
An OSC time tag.
OSC time tags are part of OSCBundle objects.
In accordance with the OSC 1.0 specification, the internal timestamp stored in
OSCTimeTag uses the same binary format as NTP timestamps. The representation
is by a 64 bit fixed point number. The first 32 bits specify the number of
seconds since midnight on January 1, 1900, and the last 32 bits specify
fractional parts of a second to a precision of about 200 picoseconds.
The time tag value consisting of 63 zero bits followed by a one in the least
significant bit is a special case meaning "immediately".
For a more user-friendly time format, convert OSCTimeTag to a juce::Time object
using toTime().
@tags{OSC}
*/
class JUCE_API OSCTimeTag
{
public:
//==============================================================================
/** Default constructor.
Constructs an OSCTimeTag object with the special value representing "immediately".
*/
OSCTimeTag() noexcept;
/** Constructs an OSCTimeTag object from a raw binary OSC time tag. */
OSCTimeTag (uint64 rawTimeTag) noexcept;
/** Constructs an OSCTimeTag object from a juce::Time object. */
OSCTimeTag (Time time) noexcept;
/** Returns a juce::Time object representing the same time as the OSCTimeTag.
If the OSCTimeTag has the special value representing "immediately", the
resulting juce::Time object will represent an arbitrary point of time (but
guaranteed to be in the past), since juce::Time does not have such a special value.
*/
Time toTime() const noexcept;
/** Returns true if the OSCTimeTag object has the special value representing "immediately". */
bool isImmediately() const noexcept;
/** Returns the raw binary OSC time tag representation. */
uint64 getRawTimeTag() const noexcept { return rawTimeTag; }
/** The special value representing "immediately". */
static const OSCTimeTag immediately;
private:
//==============================================================================
uint64 rawTimeTag;
};
} // namespace juce

View File

@ -1,48 +1,48 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
const OSCType OSCTypes::int32 = 'i';
const OSCType OSCTypes::float32 = 'f';
const OSCType OSCTypes::string = 's';
const OSCType OSCTypes::blob = 'b';
const OSCType OSCTypes::colour = 'r';
uint32 OSCColour::toInt32() const
{
return ByteOrder::makeInt (alpha, blue, green, red);
}
OSCColour OSCColour::fromInt32 (uint32 c)
{
return { (uint8) (c >> 24),
(uint8) (c >> 16),
(uint8) (c >> 8),
(uint8) c };
}
} // namespace juce
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
const OSCType OSCTypes::int32 = 'i';
const OSCType OSCTypes::float32 = 'f';
const OSCType OSCTypes::string = 's';
const OSCType OSCTypes::blob = 'b';
const OSCType OSCTypes::colour = 'r';
uint32 OSCColour::toInt32() const
{
return ByteOrder::makeInt (alpha, blue, green, red);
}
OSCColour OSCColour::fromInt32 (uint32 c)
{
return { (uint8) (c >> 24),
(uint8) (c >> 16),
(uint8) (c >> 8),
(uint8) c };
}
} // namespace juce

View File

@ -1,123 +1,123 @@
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2020 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 6 End-User License
Agreement and JUCE Privacy Policy (both effective as of the 16th June 2020).
End User License Agreement: www.juce.com/juce-6-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/** The type used for OSC type tags. */
using OSCType = char;
/** The type used for OSC type tag strings. */
using OSCTypeList = Array<OSCType>;
//==============================================================================
/** The definitions of supported OSC types and their associated OSC type tags,
as defined in the OpenSoundControl 1.0 specification.
Note: This implementation does not support any additional type tags that
are not part of the specification.
@tags{OSC}
*/
class JUCE_API OSCTypes
{
public:
static const OSCType int32;
static const OSCType float32;
static const OSCType string;
static const OSCType blob;
static const OSCType colour;
static bool isSupportedType (OSCType type) noexcept
{
return type == OSCTypes::int32
|| type == OSCTypes::float32
|| type == OSCTypes::string
|| type == OSCTypes::blob
|| type == OSCTypes::colour;
}
};
//==============================================================================
/**
Holds a 32-bit RGBA colour for passing to and from an OSCArgument.
@see OSCArgument, OSCTypes::colour
@tags{OSC}
*/
struct OSCColour
{
uint8 red, green, blue, alpha;
uint32 toInt32() const;
static OSCColour fromInt32 (uint32);
};
//==============================================================================
/** Base class for exceptions that can be thrown by methods in the OSC module.
@tags{OSC}
*/
struct OSCException : public std::exception
{
OSCException (const String& desc)
: description (desc)
{
#if ! JUCE_UNIT_TESTS
DBG ("OSCFormatError: " + description);
#endif
}
String description;
};
//==============================================================================
/** Exception type thrown when the OSC module fails to parse something because
of a data format not compatible with the OpenSoundControl 1.0 specification.
@tags{OSC}
*/
struct OSCFormatError : public OSCException
{
OSCFormatError (const String& desc) : OSCException (desc) {}
};
//==============================================================================
/** Exception type thrown in cases of unexpected errors in the OSC module.
Note: This should never happen, and all the places where this is thrown
should have a preceding jassertfalse to facilitate debugging.
@tags{OSC}
*/
struct OSCInternalError : public OSCException
{
OSCInternalError (const String& desc) : OSCException (desc) {}
};
} // namespace juce
/*
==============================================================================
This file is part of the JUCE library.
Copyright (c) 2022 - Raw Material Software Limited
JUCE is an open source library subject to commercial or open-source
licensing.
By using JUCE, you agree to the terms of both the JUCE 7 End-User License
Agreement and JUCE Privacy Policy.
End User License Agreement: www.juce.com/juce-7-licence
Privacy Policy: www.juce.com/juce-privacy-policy
Or: You may also use this code under the terms of the GPL v3 (see
www.gnu.org/licenses).
JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
DISCLAIMED.
==============================================================================
*/
namespace juce
{
//==============================================================================
/** The type used for OSC type tags. */
using OSCType = char;
/** The type used for OSC type tag strings. */
using OSCTypeList = Array<OSCType>;
//==============================================================================
/** The definitions of supported OSC types and their associated OSC type tags,
as defined in the OpenSoundControl 1.0 specification.
Note: This implementation does not support any additional type tags that
are not part of the specification.
@tags{OSC}
*/
class JUCE_API OSCTypes
{
public:
static const OSCType int32;
static const OSCType float32;
static const OSCType string;
static const OSCType blob;
static const OSCType colour;
static bool isSupportedType (OSCType type) noexcept
{
return type == OSCTypes::int32
|| type == OSCTypes::float32
|| type == OSCTypes::string
|| type == OSCTypes::blob
|| type == OSCTypes::colour;
}
};
//==============================================================================
/**
Holds a 32-bit RGBA colour for passing to and from an OSCArgument.
@see OSCArgument, OSCTypes::colour
@tags{OSC}
*/
struct OSCColour
{
uint8 red, green, blue, alpha;
uint32 toInt32() const;
static OSCColour fromInt32 (uint32);
};
//==============================================================================
/** Base class for exceptions that can be thrown by methods in the OSC module.
@tags{OSC}
*/
struct OSCException : public std::exception
{
OSCException (const String& desc)
: description (desc)
{
#if ! JUCE_UNIT_TESTS
DBG ("OSCFormatError: " + description);
#endif
}
String description;
};
//==============================================================================
/** Exception type thrown when the OSC module fails to parse something because
of a data format not compatible with the OpenSoundControl 1.0 specification.
@tags{OSC}
*/
struct OSCFormatError : public OSCException
{
OSCFormatError (const String& desc) : OSCException (desc) {}
};
//==============================================================================
/** Exception type thrown in cases of unexpected errors in the OSC module.
Note: This should never happen, and all the places where this is thrown
should have a preceding jassertfalse to facilitate debugging.
@tags{OSC}
*/
struct OSCInternalError : public OSCException
{
OSCInternalError (const String& desc) : OSCException (desc) {}
};
} // namespace juce