Fix clang-tidy-19 errors

This commit is contained in:
Chris Thrasher 2024-09-23 13:55:33 -06:00
parent 1f11e91bed
commit c8cf84511d
24 changed files with 287 additions and 306 deletions

View File

@ -19,6 +19,7 @@ Checks: >
-bugprone-narrowing-conversions, -bugprone-narrowing-conversions,
-bugprone-signed-char-misuse, -bugprone-signed-char-misuse,
-bugprone-string-integer-assignment, -bugprone-string-integer-assignment,
-bugprone-suspicious-stringview-data-usage,
-bugprone-switch-missing-default-case, -bugprone-switch-missing-default-case,
-bugprone-unchecked-optional-access, -bugprone-unchecked-optional-access,
-clang-analyzer-nullability.NullablePassedToNonnull, -clang-analyzer-nullability.NullablePassedToNonnull,
@ -27,6 +28,7 @@ Checks: >
-clang-analyzer-optin.osx.*, -clang-analyzer-optin.osx.*,
-clang-analyzer-osx.*, -clang-analyzer-osx.*,
-clang-analyzer-unix.Malloc, -clang-analyzer-unix.Malloc,
-clang-analyzer-unix.StdCLibraryFunctions,
-cppcoreguidelines-avoid-c-arrays, -cppcoreguidelines-avoid-c-arrays,
-cppcoreguidelines-avoid-const-or-ref-data-members, -cppcoreguidelines-avoid-const-or-ref-data-members,
-cppcoreguidelines-avoid-do-while, -cppcoreguidelines-avoid-do-while,
@ -62,11 +64,13 @@ Checks: >
-readability-avoid-nested-conditional-operator, -readability-avoid-nested-conditional-operator,
-readability-braces-around-statements, -readability-braces-around-statements,
-readability-convert-member-functions-to-static, -readability-convert-member-functions-to-static,
-readability-enum-initial-value,
-readability-function-cognitive-complexity, -readability-function-cognitive-complexity,
-readability-function-size, -readability-function-size,
-readability-identifier-length, -readability-identifier-length,
-readability-implicit-bool-conversion, -readability-implicit-bool-conversion,
-readability-magic-numbers, -readability-magic-numbers,
-readability-math-missing-parentheses,
-readability-named-parameter, -readability-named-parameter,
-readability-redundant-casting, -readability-redundant-casting,
-readability-uppercase-literal-suffix, -readability-uppercase-literal-suffix,

View File

@ -7,6 +7,8 @@
#include <optional> #include <optional>
namespace
{
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Print a FTP response into a standard output stream /// Print a FTP response into a standard output stream
/// ///
@ -15,6 +17,7 @@ std::ostream& operator<<(std::ostream& stream, const sf::Ftp::Response& response
{ {
return stream << static_cast<int>(response.getStatus()) << response.getMessage(); return stream << static_cast<int>(response.getStatus()) << response.getMessage();
} }
} // namespace
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@ -69,208 +69,6 @@ float snowcapHeight = 0.6f;
float heightFactor = static_cast<float>(windowSize.y) / 2.0f; float heightFactor = static_cast<float>(windowSize.y) / 2.0f;
float heightFlatten = 3.0f; float heightFlatten = 3.0f;
float lightFactor = 0.7f; float lightFactor = 0.7f;
} // namespace
// Forward declarations of the functions we define further down
void threadFunction();
void generateTerrain(sf::Vertex* vertexBuffer);
////////////////////////////////////////////////////////////
/// Entry point of application
///
/// \return Application exit code
///
////////////////////////////////////////////////////////////
int main()
{
// Create the window of the application
sf::RenderWindow window(sf::VideoMode(windowSize), "SFML Island", sf::Style::Titlebar | sf::Style::Close);
window.setVerticalSyncEnabled(true);
const sf::Font font("resources/tuffy.ttf");
// Create all of our graphics resources
sf::Text hudText(font);
sf::Text statusText(font);
sf::Shader terrainShader;
sf::RenderStates terrainStates;
sf::VertexBuffer terrain(sf::PrimitiveType::Triangles, sf::VertexBuffer::Usage::Static);
// Set up our text drawables
statusText.setCharacterSize(28);
statusText.setFillColor(sf::Color::White);
statusText.setOutlineColor(sf::Color::Black);
statusText.setOutlineThickness(2.0f);
hudText.setCharacterSize(14);
hudText.setFillColor(sf::Color::White);
hudText.setOutlineColor(sf::Color::Black);
hudText.setOutlineThickness(2.0f);
hudText.setPosition({5.0f, 5.0f});
// Staging buffer for our terrain data that we will upload to our VertexBuffer
std::vector<sf::Vertex> terrainStagingBuffer;
// Set up our graphics resources and set the status text accordingly
if (!sf::VertexBuffer::isAvailable() || !sf::Shader::isAvailable())
{
statusText.setString("Shaders and/or Vertex Buffers Unsupported");
}
else if (!terrainShader.loadFromFile("resources/terrain.vert", "resources/terrain.frag"))
{
statusText.setString("Failed to load shader program");
}
else
{
// Start up our thread pool
for (unsigned int i = 0; i < threadCount; ++i)
{
threads.emplace_back(threadFunction);
}
// Create our VertexBuffer with enough space to hold all the terrain geometry
if (!terrain.create(resolution.x * resolution.y * 6))
{
std::cerr << "Failed to create vertex buffer" << std::endl;
return EXIT_FAILURE;
}
// Resize the staging buffer to be able to hold all the terrain geometry
terrainStagingBuffer.resize(resolution.x * resolution.y * 6);
// Generate the initial terrain
generateTerrain(terrainStagingBuffer.data());
statusText.setString("Generating Terrain...");
// Set up the render states
terrainStates = sf::RenderStates(&terrainShader);
}
// Center the status text
statusText.setPosition((sf::Vector2f(windowSize) - statusText.getLocalBounds().size) / 2.f);
// Set up an array of pointers to our settings for arrow navigation
constexpr std::array<Setting, 9> settings = {
{{"perlinFrequency", &perlinFrequency},
{"perlinFrequencyBase", &perlinFrequencyBase},
{"heightBase", &heightBase},
{"edgeFactor", &edgeFactor},
{"edgeDropoffExponent", &edgeDropoffExponent},
{"snowcapHeight", &snowcapHeight},
{"heightFactor", &heightFactor},
{"heightFlatten", &heightFlatten},
{"lightFactor", &lightFactor}}};
std::size_t currentSetting = 0;
std::ostringstream osstr;
sf::Clock clock;
while (window.isOpen())
{
// Handle events
while (const std::optional event = window.pollEvent())
{
// Window closed or escape key pressed: exit
if (event->is<sf::Event::Closed>() ||
(event->is<sf::Event::KeyPressed>() &&
event->getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Escape))
{
window.close();
break;
}
// Arrow key pressed:
// TODO Replace use of getNativeHandle() when validity function is added
if (terrainShader.getNativeHandle() != 0 && event->is<sf::Event::KeyPressed>())
{
switch (event->getIf<sf::Event::KeyPressed>()->code)
{
case sf::Keyboard::Key::Enter:
generateTerrain(terrainStagingBuffer.data());
break;
case sf::Keyboard::Key::Down:
currentSetting = (currentSetting + 1) % settings.size();
break;
case sf::Keyboard::Key::Up:
currentSetting = (currentSetting + settings.size() - 1) % settings.size();
break;
case sf::Keyboard::Key::Left:
*(settings[currentSetting].value) -= 0.1f;
break;
case sf::Keyboard::Key::Right:
*(settings[currentSetting].value) += 0.1f;
break;
default:
break;
}
}
}
// Clear, draw graphics objects and display
window.clear();
window.draw(statusText);
if (terrainShader.getNativeHandle() != 0)
{
{
const std::lock_guard lock(workQueueMutex);
// Don't bother updating/drawing the VertexBuffer while terrain is being regenerated
if (!pendingWorkCount)
{
// If there is new data pending to be uploaded to the VertexBuffer, do it now
if (bufferUploadPending)
{
if (!terrain.update(terrainStagingBuffer.data()))
{
std::cerr << "Failed to update vertex buffer" << std::endl;
return EXIT_FAILURE;
}
bufferUploadPending = false;
}
terrainShader.setUniform("lightFactor", lightFactor);
window.draw(terrain, terrainStates);
}
}
// Update and draw the HUD text
osstr.str("");
osstr << "Frame: " << clock.restart().asMilliseconds() << "ms\n"
<< "perlinOctaves: " << perlinOctaves << "\n\n"
<< "Use the arrow keys to change the values.\nUse the return key to regenerate the terrain.\n\n";
for (std::size_t i = 0; i < settings.size(); ++i)
osstr << ((i == currentSetting) ? ">> " : " ") << settings[i].name << ": "
<< *(settings[i].value) << '\n';
hudText.setString(osstr.str());
window.draw(hudText);
}
// Display things on screen
window.display();
}
// Shut down our thread pool
{
const std::lock_guard lock(workQueueMutex);
workPending = false;
}
while (!threads.empty())
{
threads.back().join();
threads.pop_back();
}
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
@ -620,3 +418,200 @@ void generateTerrain(sf::Vertex* buffer)
pendingWorkCount = blockCount; pendingWorkCount = blockCount;
} }
} }
} // namespace
////////////////////////////////////////////////////////////
/// Entry point of application
///
/// \return Application exit code
///
////////////////////////////////////////////////////////////
int main()
{
// Create the window of the application
sf::RenderWindow window(sf::VideoMode(windowSize), "SFML Island", sf::Style::Titlebar | sf::Style::Close);
window.setVerticalSyncEnabled(true);
const sf::Font font("resources/tuffy.ttf");
// Create all of our graphics resources
sf::Text hudText(font);
sf::Text statusText(font);
sf::Shader terrainShader;
sf::RenderStates terrainStates;
sf::VertexBuffer terrain(sf::PrimitiveType::Triangles, sf::VertexBuffer::Usage::Static);
// Set up our text drawables
statusText.setCharacterSize(28);
statusText.setFillColor(sf::Color::White);
statusText.setOutlineColor(sf::Color::Black);
statusText.setOutlineThickness(2.0f);
hudText.setCharacterSize(14);
hudText.setFillColor(sf::Color::White);
hudText.setOutlineColor(sf::Color::Black);
hudText.setOutlineThickness(2.0f);
hudText.setPosition({5.0f, 5.0f});
// Staging buffer for our terrain data that we will upload to our VertexBuffer
std::vector<sf::Vertex> terrainStagingBuffer;
// Set up our graphics resources and set the status text accordingly
if (!sf::VertexBuffer::isAvailable() || !sf::Shader::isAvailable())
{
statusText.setString("Shaders and/or Vertex Buffers Unsupported");
}
else if (!terrainShader.loadFromFile("resources/terrain.vert", "resources/terrain.frag"))
{
statusText.setString("Failed to load shader program");
}
else
{
// Start up our thread pool
for (unsigned int i = 0; i < threadCount; ++i)
{
threads.emplace_back(threadFunction);
}
// Create our VertexBuffer with enough space to hold all the terrain geometry
if (!terrain.create(resolution.x * resolution.y * 6))
{
std::cerr << "Failed to create vertex buffer" << std::endl;
return EXIT_FAILURE;
}
// Resize the staging buffer to be able to hold all the terrain geometry
terrainStagingBuffer.resize(resolution.x * resolution.y * 6);
// Generate the initial terrain
generateTerrain(terrainStagingBuffer.data());
statusText.setString("Generating Terrain...");
// Set up the render states
terrainStates = sf::RenderStates(&terrainShader);
}
// Center the status text
statusText.setPosition((sf::Vector2f(windowSize) - statusText.getLocalBounds().size) / 2.f);
// Set up an array of pointers to our settings for arrow navigation
constexpr std::array<Setting, 9> settings = {
{{"perlinFrequency", &perlinFrequency},
{"perlinFrequencyBase", &perlinFrequencyBase},
{"heightBase", &heightBase},
{"edgeFactor", &edgeFactor},
{"edgeDropoffExponent", &edgeDropoffExponent},
{"snowcapHeight", &snowcapHeight},
{"heightFactor", &heightFactor},
{"heightFlatten", &heightFlatten},
{"lightFactor", &lightFactor}}};
std::size_t currentSetting = 0;
std::ostringstream osstr;
sf::Clock clock;
while (window.isOpen())
{
// Handle events
while (const std::optional event = window.pollEvent())
{
// Window closed or escape key pressed: exit
if (event->is<sf::Event::Closed>() ||
(event->is<sf::Event::KeyPressed>() &&
event->getIf<sf::Event::KeyPressed>()->code == sf::Keyboard::Key::Escape))
{
window.close();
break;
}
// Arrow key pressed:
// TODO Replace use of getNativeHandle() when validity function is added
if (terrainShader.getNativeHandle() != 0 && event->is<sf::Event::KeyPressed>())
{
switch (event->getIf<sf::Event::KeyPressed>()->code)
{
case sf::Keyboard::Key::Enter:
generateTerrain(terrainStagingBuffer.data());
break;
case sf::Keyboard::Key::Down:
currentSetting = (currentSetting + 1) % settings.size();
break;
case sf::Keyboard::Key::Up:
currentSetting = (currentSetting + settings.size() - 1) % settings.size();
break;
case sf::Keyboard::Key::Left:
*(settings[currentSetting].value) -= 0.1f;
break;
case sf::Keyboard::Key::Right:
*(settings[currentSetting].value) += 0.1f;
break;
default:
break;
}
}
}
// Clear, draw graphics objects and display
window.clear();
window.draw(statusText);
if (terrainShader.getNativeHandle() != 0)
{
{
const std::lock_guard lock(workQueueMutex);
// Don't bother updating/drawing the VertexBuffer while terrain is being regenerated
if (!pendingWorkCount)
{
// If there is new data pending to be uploaded to the VertexBuffer, do it now
if (bufferUploadPending)
{
if (!terrain.update(terrainStagingBuffer.data()))
{
std::cerr << "Failed to update vertex buffer" << std::endl;
return EXIT_FAILURE;
}
bufferUploadPending = false;
}
terrainShader.setUniform("lightFactor", lightFactor);
window.draw(terrain, terrainStates);
}
}
// Update and draw the HUD text
osstr.str("");
osstr << "Frame: " << clock.restart().asMilliseconds() << "ms\n"
<< "perlinOctaves: " << perlinOctaves << "\n\n"
<< "Use the arrow keys to change the values.\nUse the return key to regenerate the terrain.\n\n";
for (std::size_t i = 0; i < settings.size(); ++i)
osstr << ((i == currentSetting) ? ">> " : " ") << settings[i].name << ": "
<< *(settings[i].value) << '\n';
hudText.setString(osstr.str());
window.draw(hudText);
}
// Display things on screen
window.display();
}
// Shut down our thread pool
{
const std::lock_guard lock(workQueueMutex);
workPending = false;
}
while (!threads.empty())
{
threads.back().join();
threads.pop_back();
}
}

View File

@ -20,6 +20,8 @@
#define GL_SRGB8_ALPHA8 0x8C43 #define GL_SRGB8_ALPHA8 0x8C43
#endif #endif
namespace
{
std::filesystem::path resourcesDir() std::filesystem::path resourcesDir()
{ {
#ifdef SFML_SYSTEM_IOS #ifdef SFML_SYSTEM_IOS
@ -28,6 +30,7 @@ std::filesystem::path resourcesDir()
return "resources"; return "resources";
#endif #endif
} }
} // namespace
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Entry point of application /// Entry point of application

View File

@ -1,15 +1,12 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include "TCP.hpp"
#include "UDP.hpp"
#include <iostream> #include <iostream>
void runTcpServer(unsigned short port);
void runTcpClient(unsigned short port);
void runUdpServer(unsigned short port);
void runUdpClient(unsigned short port);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Entry point of application /// Entry point of application
/// ///

View File

@ -1,6 +1,8 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include "TCP.hpp"
#include <SFML/Network.hpp> #include <SFML/Network.hpp>
#include <iomanip> #include <iomanip>

4
examples/sockets/TCP.hpp Normal file
View File

@ -0,0 +1,4 @@
#pragma once
void runTcpServer(unsigned short port);
void runTcpClient(unsigned short port);

View File

@ -1,6 +1,8 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include "UDP.hpp"
#include <SFML/Network.hpp> #include <SFML/Network.hpp>
#include <iomanip> #include <iomanip>

4
examples/sockets/UDP.hpp Normal file
View File

@ -0,0 +1,4 @@
#pragma once
void runUdpServer(unsigned short port);
void runUdpClient(unsigned short port);

View File

@ -6,6 +6,8 @@
#include <iostream> #include <iostream>
namespace
{
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Play a sound /// Play a sound
/// ///
@ -69,6 +71,7 @@ void playMusic(const std::filesystem::path& filename)
std::cout << '\n' << std::endl; std::cout << '\n' << std::endl;
} }
} // namespace
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////

View File

@ -16,6 +16,8 @@
#include <SFML/Main.hpp> #include <SFML/Main.hpp>
#endif #endif
namespace
{
std::filesystem::path resourcesDir() std::filesystem::path resourcesDir()
{ {
#ifdef SFML_SYSTEM_IOS #ifdef SFML_SYSTEM_IOS
@ -24,6 +26,7 @@ std::filesystem::path resourcesDir()
return "resources"; return "resources";
#endif #endif
} }
} // namespace
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Entry point of application /// Entry point of application

View File

@ -1,6 +1,8 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include "Client.hpp"
#include <SFML/Audio.hpp> #include <SFML/Audio.hpp>
#include <SFML/Network.hpp> #include <SFML/Network.hpp>

3
examples/voip/Client.hpp Normal file
View File

@ -0,0 +1,3 @@
#pragma once
void doClient(unsigned short port);

View File

@ -1,6 +1,8 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include "Server.hpp"
#include <SFML/Audio.hpp> #include <SFML/Audio.hpp>
#include <SFML/Network.hpp> #include <SFML/Network.hpp>

3
examples/voip/Server.hpp Normal file
View File

@ -0,0 +1,3 @@
#pragma once
void doServer(unsigned short port);

View File

@ -1,17 +1,12 @@
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
// Headers // Headers
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
#include "Client.hpp"
#include "Server.hpp"
#include <iostream> #include <iostream>
////////////////////////////////////////////////////////////
// Function prototypes
// (I'm too lazy to put them into separate headers...)
////////////////////////////////////////////////////////////
void doClient(unsigned short port);
void doServer(unsigned short port);
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// Entry point of application /// Entry point of application
/// ///

View File

@ -50,7 +50,7 @@
#endif #endif
namespace sf::priv namespace
{ {
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void extensionSanityCheck() void extensionSanityCheck()
@ -82,8 +82,10 @@ void extensionSanityCheck()
check(GLEXT_copy_buffer_dependencies); check(GLEXT_copy_buffer_dependencies);
#endif #endif
} }
} // namespace
namespace sf::priv
{
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
void ensureExtensionsInit() void ensureExtensionsInit()
{ {

View File

@ -31,6 +31,7 @@
#include <SFML/System/Err.hpp> #include <SFML/System/Err.hpp>
#include <algorithm>
#include <memory> #include <memory>
#include <ostream> #include <ostream>
#include <utility> #include <utility>
@ -119,8 +120,7 @@ void SocketSelector::add(Socket& socket)
} }
// SocketHandle is an int in POSIX // SocketHandle is an int in POSIX
if (m_impl->maxSocket < handle) m_impl->maxSocket = std::max(m_impl->maxSocket, handle);
m_impl->maxSocket = handle;
#endif #endif

View File

@ -388,7 +388,7 @@ struct GlContext::TransientContext
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
static std::optional<TransientContext>& get() static std::optional<TransientContext>& get()
{ {
thread_local std::optional<TransientContext> transientContext; static thread_local std::optional<TransientContext> transientContext;
return transientContext; return transientContext;
} }

View File

@ -75,33 +75,40 @@ namespace
/// Share 'modifiers' state with all windows to correctly fire pressed/released events /// Share 'modifiers' state with all windows to correctly fire pressed/released events
ModifiersState state; ModifiersState state;
BOOL isStateInitialized = NO; BOOL isStateInitialized = NO;
////////////////////////////////////////////////////////
BOOL isKeyMaskActive(NSUInteger modifiers, NSUInteger mask)
{
// Here we need to make sure it's exactly the mask since some masks
// share some bits such that the & operation would result in a non zero
// value without corresponding to the processed key.
return (modifiers & mask) == mask;
} }
////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
// Local & Private Functions
////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////
/// \brief Carefully observe if the key mask is on in the modifiers
///
////////////////////////////////////////////////////////////
BOOL isKeyMaskActive(NSUInteger modifiers, NSUInteger mask);
////////////////////////////////////////////////////////////
/// \brief Handle one modifier key mask
///
/// Update the key state and send events to the requester
///
////////////////////////////////////////////////////////////
void processOneModifier(NSUInteger modifiers, void processOneModifier(NSUInteger modifiers,
NSUInteger mask, NSUInteger mask,
BOOL& wasDown, BOOL& wasDown,
sf::Keyboard::Key key, sf::Keyboard::Key key,
sf::Keyboard::Scancode code, sf::Keyboard::Scancode code,
sf::priv::WindowImplCocoa& requester); sf::priv::WindowImplCocoa& requester)
{
// State
const BOOL isDown = isKeyMaskActive(modifiers, mask);
// Check for key pressed event
if (isDown && !wasDown)
requester.keyDown(keyPressedEventWithModifiers(modifiers, key, code));
// And check for key released event
else if (!isDown && wasDown)
requester.keyUp(keyReleasedEventWithModifiers(modifiers, key, code));
// else isDown == wasDown, so no change
// Update state
wasDown = isDown;
}
//////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////
/// \brief Handle left & right modifier keys /// \brief Handle left & right modifier keys
@ -119,12 +126,12 @@ void processLeftRightModifiers(
sf::Keyboard::Key rightKey, sf::Keyboard::Key rightKey,
sf::Keyboard::Scancode leftCode, sf::Keyboard::Scancode leftCode,
sf::Keyboard::Scancode rightCode, sf::Keyboard::Scancode rightCode,
sf::priv::WindowImplCocoa& requester); sf::priv::WindowImplCocoa& requester)
{
processOneModifier(modifiers, leftMask, leftWasDown, leftKey, leftCode, requester);
//////////////////////////////////////////////////////////// processOneModifier(modifiers, rightMask, rightWasDown, rightKey, rightCode, requester);
// Implementations }
//////////////////////////////////////////////////////////// }
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
@ -237,57 +244,3 @@ void handleModifiersChanged(NSUInteger modifiers, sf::priv::WindowImplCocoa& req
sf::Keyboard::Scan::CapsLock, sf::Keyboard::Scan::CapsLock,
requester); requester);
} }
////////////////////////////////////////////////////////
BOOL isKeyMaskActive(NSUInteger modifiers, NSUInteger mask)
{
// Here we need to make sure it's exactly the mask since some masks
// share some bits such that the & operation would result in a non zero
// value without corresponding to the processed key.
return (modifiers & mask) == mask;
}
////////////////////////////////////////////////////////
void processOneModifier(NSUInteger modifiers,
NSUInteger mask,
BOOL& wasDown,
sf::Keyboard::Key key,
sf::Keyboard::Scancode code,
sf::priv::WindowImplCocoa& requester)
{
// State
const BOOL isDown = isKeyMaskActive(modifiers, mask);
// Check for key pressed event
if (isDown && !wasDown)
requester.keyDown(keyPressedEventWithModifiers(modifiers, key, code));
// And check for key released event
else if (!isDown && wasDown)
requester.keyUp(keyReleasedEventWithModifiers(modifiers, key, code));
// else isDown == wasDown, so no change
// Update state
wasDown = isDown;
}
////////////////////////////////////////////////////////
void processLeftRightModifiers(
NSUInteger modifiers,
NSUInteger leftMask,
NSUInteger rightMask,
BOOL& leftWasDown,
BOOL& rightWasDown,
sf::Keyboard::Key leftKey,
sf::Keyboard::Key rightKey,
sf::Keyboard::Scancode leftCode,
sf::Keyboard::Scancode rightCode,
sf::priv::WindowImplCocoa& requester)
{
processOneModifier(modifiers, leftMask, leftWasDown, leftKey, leftCode, requester);
processOneModifier(modifiers, rightMask, rightWasDown, rightKey, rightCode, requester);
}

View File

@ -69,7 +69,6 @@ NSString* sfStringToNSString(const sf::String& string)
NSString* const str = [[NSString alloc] initWithBytes:data length:length encoding:encoding]; NSString* const str = [[NSString alloc] initWithBytes:data length:length encoding:encoding];
return [str autorelease]; return [str autorelease];
} }
}
//////////////////////////////////////////////////////// ////////////////////////////////////////////////////////
@ -94,6 +93,7 @@ void showMouseCursor()
isCursorHidden = false; isCursorHidden = false;
} }
} }
}
#pragma mark #pragma mark
#pragma mark WindowImplCocoa's ctor/dtor #pragma mark WindowImplCocoa's ctor/dtor

View File

@ -11,6 +11,8 @@
namespace sf namespace sf
{ {
struct BlendMode; struct BlendMode;
enum class StencilComparison;
enum class StencilUpdateOperation;
struct StencilMode; struct StencilMode;
class Color; class Color;
class Transform; class Transform;
@ -19,6 +21,8 @@ template <typename>
class Rect; class Rect;
std::ostream& operator<<(std::ostream& os, const BlendMode& blendMode); std::ostream& operator<<(std::ostream& os, const BlendMode& blendMode);
std::ostream& operator<<(std::ostream& os, const StencilComparison& comparison);
std::ostream& operator<<(std::ostream& os, const StencilUpdateOperation& updateOperation);
std::ostream& operator<<(std::ostream& os, const StencilMode& stencilMode); std::ostream& operator<<(std::ostream& os, const StencilMode& stencilMode);
std::ostream& operator<<(std::ostream& os, Color color); std::ostream& operator<<(std::ostream& os, Color color);
std::ostream& operator<<(std::ostream& os, const Transform& transform); std::ostream& operator<<(std::ostream& os, const Transform& transform);

View File

@ -1,4 +1,5 @@
// Note: No need to increase compile time by including TestUtilities/Window.hpp #include "WindowUtil.hpp"
#include <SFML/Window/VideoMode.hpp> #include <SFML/Window/VideoMode.hpp>
#include <ostream> #include <ostream>

View File

@ -8,8 +8,6 @@
#include <SystemUtil.hpp> #include <SystemUtil.hpp>
#include <string> #include <string>
// Required because WindowUtil.cpp doesn't include WindowUtil.hpp
// NOLINTNEXTLINE(readability-redundant-declaration)
std::string runDisplayTests(); std::string runDisplayTests();
// String conversions for Catch2 // String conversions for Catch2
@ -17,7 +15,5 @@ namespace sf
{ {
class VideoMode; class VideoMode;
// Required because WindowUtil.cpp doesn't include WindowUtil.hpp
// NOLINTNEXTLINE(readability-redundant-declaration)
std::ostream& operator<<(std::ostream& os, const VideoMode& videoMode); std::ostream& operator<<(std::ostream& os, const VideoMode& videoMode);
} // namespace sf } // namespace sf