Support minimal dependency linux build.
This commit is contained in:
parent
92a35a5bc9
commit
7ce29ce8ae
14 changed files with 421 additions and 176 deletions
38
README.md
38
README.md
|
@ -1,5 +1,39 @@
|
||||||
# limmto
|
# MediaTool
|
||||||
limmto (Light Multi-Media Tool) is a free, low-dependency C++ library for working with digital media.
|
|
||||||
|
This is a collection of tools and apps for working with various media (Web, Desktop Publishing, Video/Audio) on different platforms (Linux, Windows).
|
||||||
|
|
||||||
|
It tries to have low dependencies and lots of things are built from scratch.
|
||||||
|
|
||||||
|
This is a personal/hobby project - things will break/change a lot.
|
||||||
|
|
||||||
|
# Build Dependencies
|
||||||
|
|
||||||
|
## Linux
|
||||||
|
|
||||||
|
### Minimal
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt-get install build-essential cmake
|
||||||
|
```
|
||||||
|
|
||||||
|
### Optional
|
||||||
|
|
||||||
|
#### Audio
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt-get install libasound2-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
#### Image Formats
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo apt-get install libpng-dev
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
# Build from Source
|
||||||
|
|
||||||
|
## Linux
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
mkdir build
|
mkdir build
|
||||||
|
|
|
@ -1,24 +1,9 @@
|
||||||
# Sample GUI
|
# Sample GUI
|
||||||
add_executable(sample_gui gui-main.cpp)
|
|
||||||
target_include_directories(sample_gui PUBLIC
|
add_subdirectory(sample-gui)
|
||||||
"${PROJECT_SOURCE_DIR}/src/console"
|
|
||||||
"${PROJECT_SOURCE_DIR}/src/client"
|
|
||||||
)
|
|
||||||
target_link_libraries(sample_gui PUBLIC client windows console core
|
|
||||||
network database geometry audio web)
|
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
add_executable(sample_gui_win WIN32 gui-main-win.cpp)
|
add_subdirectory(directx-practice)
|
||||||
target_include_directories(sample_gui PUBLIC
|
|
||||||
"${PROJECT_SOURCE_DIR}/src/console"
|
|
||||||
"${PROJECT_SOURCE_DIR}/src/client"
|
|
||||||
)
|
|
||||||
target_link_libraries(sample_gui_win PUBLIC client windows console core
|
|
||||||
network database geometry audio web)
|
|
||||||
set_property(TARGET sample_gui_win PROPERTY FOLDER apps)
|
|
||||||
|
|
||||||
add_subdirectory(directx-practice)
|
|
||||||
|
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# Sample Console
|
# Sample Console
|
||||||
|
@ -30,7 +15,6 @@ target_link_libraries(sample_console PUBLIC console core network
|
||||||
database geometry audio web)
|
database geometry audio web)
|
||||||
|
|
||||||
set_property(TARGET sample_console PROPERTY FOLDER apps)
|
set_property(TARGET sample_console PROPERTY FOLDER apps)
|
||||||
set_property(TARGET sample_gui PROPERTY FOLDER apps)
|
|
||||||
|
|
||||||
add_subdirectory(website-generator)
|
add_subdirectory(website-generator)
|
||||||
|
|
||||||
|
|
27
apps/sample-gui/CMakeLists.txt
Normal file
27
apps/sample-gui/CMakeLists.txt
Normal file
|
@ -0,0 +1,27 @@
|
||||||
|
|
||||||
|
if(WIN32)
|
||||||
|
add_executable(sample_gui_win WIN32 gui-main-win.cpp)
|
||||||
|
target_include_directories(sample_gui PUBLIC
|
||||||
|
"${PROJECT_SOURCE_DIR}/src/console"
|
||||||
|
"${PROJECT_SOURCE_DIR}/src/client"
|
||||||
|
)
|
||||||
|
target_link_libraries(sample_gui_win PUBLIC client windows console core
|
||||||
|
network database geometry audio web)
|
||||||
|
set_property(TARGET sample_gui_win PROPERTY FOLDER apps)
|
||||||
|
else()
|
||||||
|
find_package(X11 QUIET)
|
||||||
|
if(X11_FOUND)
|
||||||
|
add_executable(sample_gui gui-main.cpp)
|
||||||
|
target_include_directories(sample_gui PUBLIC
|
||||||
|
"${PROJECT_SOURCE_DIR}/src/console"
|
||||||
|
"${PROJECT_SOURCE_DIR}/src/client"
|
||||||
|
)
|
||||||
|
target_link_libraries(sample_gui PUBLIC client windows console core
|
||||||
|
network database geometry audio web)
|
||||||
|
set_property(TARGET sample_gui PROPERTY FOLDER apps)
|
||||||
|
else()
|
||||||
|
message(STATUS "Skipping sample GUI as no X11 dev support")
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -50,8 +50,7 @@ void WebsiteGenerator::parseTemplateFiles()
|
||||||
const auto template_files = Directory::getFilesWithExtension(template_path, ".html");
|
const auto template_files = Directory::getFilesWithExtension(template_path, ".html");
|
||||||
for (const auto& path : template_files)
|
for (const auto& path : template_files)
|
||||||
{
|
{
|
||||||
auto file = TemplateFile(path);
|
mTemplateFiles[path.stem().string()] = std::make_unique<TemplateFile>(path);
|
||||||
mTemplateFiles[path.stem().string()] = file;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@ public:
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
Path mPath;
|
Path mPath;
|
||||||
};
|
};
|
||||||
|
@ -80,5 +81,5 @@ private:
|
||||||
GeneratorConfig mConfig;
|
GeneratorConfig mConfig;
|
||||||
std::vector<ContentPage> mPages;
|
std::vector<ContentPage> mPages;
|
||||||
std::vector<ContentArticle> mArticles;
|
std::vector<ContentArticle> mArticles;
|
||||||
std::unordered_map<std::string, TemplateFile> mTemplateFiles;
|
std::unordered_map<std::string, std::unique_ptr<TemplateFile> > mTemplateFiles;
|
||||||
};
|
};
|
||||||
|
|
|
@ -3,17 +3,26 @@ set(platform_HEADERS "")
|
||||||
set(platform_INCLUDES "")
|
set(platform_INCLUDES "")
|
||||||
|
|
||||||
if (UNIX)
|
if (UNIX)
|
||||||
find_package(ALSA REQUIRED)
|
find_package(ALSA QUIET)
|
||||||
list(APPEND platform_HEADERS
|
if(ALSA_FOUND)
|
||||||
audio_interfaces/AlsaInterface.h
|
list(APPEND platform_HEADERS
|
||||||
${ALSA_INCLUDE_DIRS}
|
audio_interfaces/AlsaInterface.h
|
||||||
)
|
${ALSA_INCLUDE_DIRS})
|
||||||
list(APPEND platform_INCLUDES
|
list(APPEND platform_INCLUDES
|
||||||
audio_interfaces/AlsaInterface.cpp
|
audio_interfaces/AlsaInterface.cpp
|
||||||
)
|
)
|
||||||
list(APPEND platform_LIBS
|
list(APPEND platform_LIBS
|
||||||
${ALSA_LIBRARIES}
|
${ALSA_LIBRARIES}
|
||||||
)
|
)
|
||||||
|
else()
|
||||||
|
message(STATUS "ALSA package not found - not building audio interface.")
|
||||||
|
list(APPEND platform_HEADERS
|
||||||
|
audio_interfaces/NullAudioInterface.h
|
||||||
|
)
|
||||||
|
list(APPEND platform_INCLUDES
|
||||||
|
audio_interfaces/NullAudioInterface.cpp
|
||||||
|
)
|
||||||
|
endif()
|
||||||
else()
|
else()
|
||||||
list(APPEND platform_HEADERS
|
list(APPEND platform_HEADERS
|
||||||
audio_interfaces/WasapiInterface.h
|
audio_interfaces/WasapiInterface.h
|
||||||
|
|
141
src/audio/audio_interfaces/NullAudioInterface.cpp
Normal file
141
src/audio/audio_interfaces/NullAudioInterface.cpp
Normal file
|
@ -0,0 +1,141 @@
|
||||||
|
#include "AlsaInterface.h"
|
||||||
|
#include "FileLogger.h"
|
||||||
|
|
||||||
|
#include "AudioSynth.h"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
|
AlsaInterface::AlsaInterface()
|
||||||
|
:mHandle(),
|
||||||
|
mHardwareParams(),
|
||||||
|
mPeriodSize(8192)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
AlsaInterface::~AlsaInterface()
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<AlsaInterface> AlsaInterface::Create()
|
||||||
|
{
|
||||||
|
return std::make_unique<AlsaInterface>();
|
||||||
|
}
|
||||||
|
|
||||||
|
void AlsaInterface::OpenDevice(const AudioDevicePtr& device)
|
||||||
|
{
|
||||||
|
MLOG_INFO("Opening Device");
|
||||||
|
snd_pcm_stream_t stream = SND_PCM_STREAM_PLAYBACK;
|
||||||
|
if (snd_pcm_open(&mHandle, device->GetName().c_str(), stream, 0) < 0)
|
||||||
|
{
|
||||||
|
MLOG_ERROR("Error opening PCM device: " + device->GetName());
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
snd_pcm_hw_params_alloca(&mHardwareParams);
|
||||||
|
if (snd_pcm_hw_params_any(mHandle, mHardwareParams) < 0)
|
||||||
|
{
|
||||||
|
MLOG_ERROR("Can not configure this PCM device.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
SetAccessType(device);
|
||||||
|
SetSampleFormat(device);
|
||||||
|
SetSampleRate(device);
|
||||||
|
SetPeriod(device);
|
||||||
|
SetBufferSize(device);
|
||||||
|
SetChannelNumber(device);
|
||||||
|
|
||||||
|
/* Apply HW parameter settings to */
|
||||||
|
/* PCM device and prepare device */
|
||||||
|
if (snd_pcm_hw_params(mHandle, mHardwareParams) < 0) {
|
||||||
|
MLOG_ERROR("Error setting HW params.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AlsaInterface::SetAccessType(const AudioDevicePtr& device)
|
||||||
|
{
|
||||||
|
if (snd_pcm_hw_params_set_access(mHandle, mHardwareParams, SND_PCM_ACCESS_RW_INTERLEAVED) < 0) {
|
||||||
|
MLOG_ERROR("Error setting device access.");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AlsaInterface::SetSampleFormat(const AudioDevicePtr& device)
|
||||||
|
{
|
||||||
|
/* Set sample format */
|
||||||
|
if (snd_pcm_hw_params_set_format(mHandle, mHardwareParams, SND_PCM_FORMAT_S16_LE) < 0) {
|
||||||
|
MLOG_ERROR("Error setting format. ");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AlsaInterface::SetSampleRate(const AudioDevicePtr& device)
|
||||||
|
{
|
||||||
|
unsigned rate = device->GetSampleRate();
|
||||||
|
unsigned exact_rate = rate;
|
||||||
|
if (snd_pcm_hw_params_set_rate_near(mHandle, mHardwareParams, &exact_rate, 0) < 0)
|
||||||
|
{
|
||||||
|
MLOG_ERROR("Error setting rate. ");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (rate != exact_rate) {
|
||||||
|
MLOG_ERROR("The rate is not supported by your hardware.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AlsaInterface::SetPeriod(const AudioDevicePtr& device)
|
||||||
|
{
|
||||||
|
/* Set number of periods. Periods used to be called fragments. */
|
||||||
|
if (snd_pcm_hw_params_set_periods(mHandle, mHardwareParams, device->GetPeriod(), 0) < 0)
|
||||||
|
{
|
||||||
|
MLOG_ERROR("Error setting periods. ");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AlsaInterface::SetBufferSize(const AudioDevicePtr& device)
|
||||||
|
{
|
||||||
|
int periods = static_cast<int>(device->GetPeriod());
|
||||||
|
|
||||||
|
/* Set buffer size (in frames). The resulting latency is given by */
|
||||||
|
/* latency = periodsize * periods / (rate * bytes_per_frame) */
|
||||||
|
if (snd_pcm_hw_params_set_buffer_size(mHandle, mHardwareParams, (mPeriodSize * periods)>>2) < 0)
|
||||||
|
{
|
||||||
|
MLOG_ERROR("Error setting buffersize. ");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AlsaInterface::SetChannelNumber(const AudioDevicePtr& device)
|
||||||
|
{
|
||||||
|
/* Set number of channels */
|
||||||
|
if (snd_pcm_hw_params_set_channels(mHandle, mHardwareParams, device->GetNumChannels()) < 0)
|
||||||
|
{
|
||||||
|
MLOG_ERROR("Error setting channels");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void AlsaInterface::Play(const AudioDevicePtr& device)
|
||||||
|
{
|
||||||
|
MLOG_INFO("Playing audio");
|
||||||
|
AudioSynth synth;
|
||||||
|
const unsigned duration = 100;
|
||||||
|
double freq = 440;
|
||||||
|
auto data = synth.GetSineWave(freq, duration)->GetChannelData(0);
|
||||||
|
|
||||||
|
int numFrames = mPeriodSize >> 2;
|
||||||
|
for(int count = 0; count < duration; count++)
|
||||||
|
{
|
||||||
|
const auto offset= count*4*numFrames;
|
||||||
|
unsigned char frame[4] = {data[offset], data[offset+1], data[offset+2], data[offset+3]};
|
||||||
|
while ((snd_pcm_writei(mHandle, frame, numFrames)) < 0)
|
||||||
|
{
|
||||||
|
snd_pcm_prepare(mHandle);
|
||||||
|
MLOG_ERROR("<<<<<<<<<<<<<<< Buffer Underrun >>>>>>>>>>>>>>>");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
40
src/audio/audio_interfaces/NullAudioInterface.h
Normal file
40
src/audio/audio_interfaces/NullAudioInterface.h
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include "IAudioInterface.h"
|
||||||
|
#include "AudioDevice.h"
|
||||||
|
|
||||||
|
#include <memory>
|
||||||
|
#include <alsa/asoundlib.h>
|
||||||
|
|
||||||
|
class AlsaInterface : public IAudioInterface
|
||||||
|
{
|
||||||
|
snd_pcm_t* mHandle;
|
||||||
|
snd_pcm_hw_params_t* mHardwareParams;
|
||||||
|
snd_pcm_uframes_t mPeriodSize;
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
AlsaInterface();
|
||||||
|
|
||||||
|
~AlsaInterface();
|
||||||
|
|
||||||
|
static std::unique_ptr<AlsaInterface> Create();
|
||||||
|
|
||||||
|
void OpenDevice(const AudioDevicePtr& device) override;
|
||||||
|
|
||||||
|
void SetAccessType(const AudioDevicePtr& device);
|
||||||
|
|
||||||
|
void SetSampleFormat(const AudioDevicePtr& device);
|
||||||
|
|
||||||
|
void SetSampleRate(const AudioDevicePtr& device);
|
||||||
|
|
||||||
|
void SetPeriod(const AudioDevicePtr& device);
|
||||||
|
|
||||||
|
void SetBufferSize(const AudioDevicePtr& device);
|
||||||
|
|
||||||
|
void SetChannelNumber(const AudioDevicePtr& device);
|
||||||
|
|
||||||
|
void Play(const AudioDevicePtr& device) override;
|
||||||
|
};
|
||||||
|
|
||||||
|
using AlsaInterfacePtr = std::shared_ptr<AlsaInterface>;
|
|
@ -2,151 +2,152 @@
|
||||||
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
TomlTable::TomlTable(const std::string& header)
|
TomlTable::TomlTable(const std::string& header)
|
||||||
: mHeader(header)
|
: mHeader(header)
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void TomlTable::addComment(const Comment& comment)
|
void TomlTable::addComment(const Comment& comment)
|
||||||
{
|
{
|
||||||
mComments.push_back(comment);
|
mComments.push_back(comment);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TomlTable::addTable(std::unique_ptr<TomlTable> table)
|
void TomlTable::addTable(std::unique_ptr<TomlTable> table)
|
||||||
{
|
{
|
||||||
mTables[table->getHeader()] = std::move(table);
|
mTables[table->getHeader()] = std::move(table);
|
||||||
}
|
}
|
||||||
|
|
||||||
void TomlTable::addKeyValuePair(const std::string& key, const std::string& value)
|
void TomlTable::addKeyValuePair(const std::string& key, const std::string& value)
|
||||||
{
|
{
|
||||||
mMap[key] = value;
|
mMap[key] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string TomlTable::getHeader() const
|
std::string TomlTable::getHeader() const
|
||||||
{
|
{
|
||||||
return mHeader;
|
return mHeader;
|
||||||
}
|
}
|
||||||
|
|
||||||
TomlTable* TomlTable::getTable(const std::string& path)
|
TomlTable* TomlTable::getTable(const std::string& path)
|
||||||
{
|
{
|
||||||
return mTables[path].get();
|
return mTables[path].get();
|
||||||
}
|
}
|
||||||
|
|
||||||
TomlTable::KeyValuePairs TomlTable::getKeyValuePairs() const
|
TomlTable::KeyValuePairs TomlTable::getKeyValuePairs() const
|
||||||
{
|
{
|
||||||
return mMap;
|
return mMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
TomlContent::TomlContent()
|
TomlContent::TomlContent()
|
||||||
: mRootTable(std::make_unique<TomlTable>("root"))
|
: mRootTable(std::make_unique<TomlTable>("root"))
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TomlTable* TomlContent::getRootTable() const
|
TomlTable* TomlContent::getRootTable() const
|
||||||
{
|
{
|
||||||
return mRootTable.get();
|
return mRootTable.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
TomlTable* TomlContent::getTable(const std::string& path) const
|
TomlTable* TomlContent::getTable(const std::string& path) const
|
||||||
{
|
{
|
||||||
return mRootTable->getTable(path);
|
return mRootTable->getTable(path);
|
||||||
}
|
}
|
||||||
|
|
||||||
TomlReader::TomlReader()
|
TomlReader::TomlReader()
|
||||||
: mContent(std::make_unique<TomlContent>())
|
: mContent(std::make_unique<TomlContent>())
|
||||||
{
|
{
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
TomlContent* TomlReader::getContent() const
|
TomlContent* TomlReader::getContent() const
|
||||||
{
|
{
|
||||||
return mContent.get();
|
return mContent.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
void TomlReader::read(const Path& input_path)
|
void TomlReader::read(const Path& input_path)
|
||||||
{
|
{
|
||||||
const auto lines = File(input_path).readLines();
|
const auto lines = File(input_path).readLines();
|
||||||
mLastSectionOffset = 0;
|
mLastSectionOffset = 0;
|
||||||
mWorkingTable = mContent->getRootTable();
|
mWorkingTable = mContent->getRootTable();
|
||||||
|
|
||||||
for (const auto& line : lines)
|
for (const auto& line : lines)
|
||||||
{
|
{
|
||||||
processLine(line);
|
processLine(line);
|
||||||
mLastSectionOffset++;
|
mLastSectionOffset++;
|
||||||
}
|
}
|
||||||
|
|
||||||
mWorkingTable = nullptr;
|
mWorkingTable = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TomlReader::processLine(const std::string& line)
|
void TomlReader::processLine(const std::string& line)
|
||||||
{
|
{
|
||||||
bool in_comment{ false };
|
bool in_comment{ false };
|
||||||
bool in_header{ false };
|
bool in_header{ false };
|
||||||
bool found_key{ false };
|
bool found_key{ false };
|
||||||
std::string working_string;
|
std::string working_string;
|
||||||
std::string key_string;
|
std::string key_string;
|
||||||
for (auto c : line)
|
for (auto c : line)
|
||||||
{
|
{
|
||||||
if (c == '#' && !in_comment)
|
if (c == '#' && !in_comment)
|
||||||
{
|
{
|
||||||
in_comment = true;
|
in_comment = true;
|
||||||
}
|
}
|
||||||
else if (c == '[' && !in_comment && !in_header)
|
else if (c == '[' && !in_comment && !in_header)
|
||||||
{
|
{
|
||||||
in_header = true;
|
in_header = true;
|
||||||
}
|
}
|
||||||
else if (c == '=' && !in_comment && !in_header)
|
else if (c == '=' && !in_comment && !in_header)
|
||||||
{
|
{
|
||||||
found_key = true;
|
found_key = true;
|
||||||
key_string = working_string;
|
key_string = working_string;
|
||||||
working_string = "";
|
working_string = "";
|
||||||
}
|
}
|
||||||
else if (c == ']' && in_header)
|
else if (c == ']' && in_header)
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
working_string += c;
|
working_string += c;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (in_comment)
|
if (in_comment)
|
||||||
{
|
{
|
||||||
mWorkingTable->addComment({ mLastSectionOffset, working_string });
|
mWorkingTable->addComment({ mLastSectionOffset, working_string });
|
||||||
}
|
}
|
||||||
else if (in_header)
|
else if (in_header)
|
||||||
{
|
{
|
||||||
onHeader(working_string);
|
onHeader(working_string);
|
||||||
}
|
}
|
||||||
else if (found_key)
|
else if (found_key)
|
||||||
{
|
{
|
||||||
std::locale locale;
|
std::locale locale;
|
||||||
key_string.erase(std::remove_if(key_string.begin(), key_string.end(), [locale](unsigned char c) {return std::isspace(c, locale); }), key_string.end());
|
key_string.erase(std::remove_if(key_string.begin(), key_string.end(), [locale](unsigned char c) {return std::isspace(c, locale); }), key_string.end());
|
||||||
working_string.erase(std::remove_if(working_string.begin(), working_string.end(), [locale](unsigned char c) {return std::isspace(c, locale); }), working_string.end());
|
working_string.erase(std::remove_if(working_string.begin(), working_string.end(), [locale](unsigned char c) {return std::isspace(c, locale); }), working_string.end());
|
||||||
|
|
||||||
if (working_string.size()>2 && working_string[0] == '"' && working_string[working_string.size() - 1] == '"')
|
if (working_string.size()>2 && working_string[0] == '"' && working_string[working_string.size() - 1] == '"')
|
||||||
{
|
{
|
||||||
working_string = working_string.substr(1, working_string.size() - 2);
|
working_string = working_string.substr(1, working_string.size() - 2);
|
||||||
}
|
}
|
||||||
|
|
||||||
onKeyValuePair(key_string, working_string);
|
onKeyValuePair(key_string, working_string);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void TomlReader::onHeader(const std::string& header)
|
void TomlReader::onHeader(const std::string& header)
|
||||||
{
|
{
|
||||||
auto new_table = std::make_unique<TomlTable>(header);
|
auto new_table = std::make_unique<TomlTable>(header);
|
||||||
auto table_temp = new_table.get();
|
auto table_temp = new_table.get();
|
||||||
mWorkingTable->addTable(std::move(new_table));
|
mWorkingTable->addTable(std::move(new_table));
|
||||||
mWorkingTable = table_temp;
|
mWorkingTable = table_temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TomlReader::onKeyValuePair(const std::string key, const std::string value)
|
void TomlReader::onKeyValuePair(const std::string key, const std::string value)
|
||||||
{
|
{
|
||||||
mWorkingTable->addKeyValuePair(key, value);
|
mWorkingTable->addKeyValuePair(key, value);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,32 +3,29 @@ set(platform_INCLUDE_DIRS "")
|
||||||
set(platform_HEADERS "")
|
set(platform_HEADERS "")
|
||||||
set(platform_LIBS "")
|
set(platform_LIBS "")
|
||||||
|
|
||||||
if (UNIX)
|
|
||||||
list(APPEND platform_LIBSs
|
|
||||||
GL
|
|
||||||
)
|
|
||||||
else()
|
|
||||||
list(APPEND platform_LIBS
|
|
||||||
OpenGL32.lib
|
|
||||||
)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
list(APPEND graphics_LIB_INCLUDES
|
list(APPEND graphics_LIB_INCLUDES
|
||||||
DrawingContext.cpp
|
DrawingContext.cpp
|
||||||
DrawingManager.cpp
|
DrawingManager.cpp
|
||||||
DrawingSurface.cpp
|
DrawingSurface.cpp
|
||||||
Rasterizer.cpp
|
Rasterizer.cpp
|
||||||
opengl/OpenGlInterface.cpp
|
${platform_LIB_INCLUDES}
|
||||||
${platform_LIB_INCLUDES}
|
|
||||||
)
|
)
|
||||||
|
|
||||||
list(APPEND graphics_HEADERS
|
list(APPEND graphics_HEADERS
|
||||||
opengl/OpenGlInterface.h
|
|
||||||
${platform_HEADERS}
|
${platform_HEADERS}
|
||||||
Rasterizer.h
|
Rasterizer.h
|
||||||
INativeDrawingSurface.h
|
INativeDrawingSurface.h
|
||||||
INativeDrawingContext.h)
|
INativeDrawingContext.h
|
||||||
|
)
|
||||||
|
|
||||||
|
find_package(OpenGL QUIET)
|
||||||
|
if (OpenGL_FOUND)
|
||||||
|
list(APPEND platform_LIBS OpenGL::GL)
|
||||||
|
list(APPEND graphics_LIB_INCLUDES opengl/OpenGlInterface.cpp)
|
||||||
|
list(APPEND graphics_HEADERS opengl/OpenGlInterface.h)
|
||||||
|
else()
|
||||||
|
message(STATUS "OpenGL headers not found - skipping OpenGL support")
|
||||||
|
endif()
|
||||||
|
|
||||||
add_library(graphics SHARED
|
add_library(graphics SHARED
|
||||||
${graphics_LIB_INCLUDES}
|
${graphics_LIB_INCLUDES}
|
||||||
|
|
|
@ -4,50 +4,51 @@ set (platform_LIBS "")
|
||||||
set(_HAS_WAYLAND Off)
|
set(_HAS_WAYLAND Off)
|
||||||
|
|
||||||
if(UNIX)
|
if(UNIX)
|
||||||
list(APPEND platform_INCLUDES
|
find_package(X11 QUIET)
|
||||||
ui_interfaces/x11/XcbInterface.cpp
|
if(X11_FOUND)
|
||||||
ui_interfaces/x11/XcbEventInterface.cpp
|
list(APPEND platform_INCLUDES
|
||||||
ui_interfaces/x11/XcbWindow.cpp
|
ui_interfaces/x11/XcbInterface.cpp
|
||||||
ui_interfaces/x11/XcbScreen.cpp
|
ui_interfaces/x11/XcbEventInterface.cpp
|
||||||
ui_interfaces/x11/XcbWindowInterface.cpp
|
ui_interfaces/x11/XcbWindow.cpp
|
||||||
ui_interfaces/x11/XcbLayerInterface.cpp
|
ui_interfaces/x11/XcbScreen.cpp
|
||||||
ui_interfaces/x11/XcbTextInterface.cpp
|
ui_interfaces/x11/XcbWindowInterface.cpp
|
||||||
ui_interfaces/x11/XcbKeyboard.cpp
|
ui_interfaces/x11/XcbLayerInterface.cpp
|
||||||
ui_interfaces/x11/GlxInterface.cpp
|
ui_interfaces/x11/XcbTextInterface.cpp
|
||||||
|
ui_interfaces/x11/XcbKeyboard.cpp
|
||||||
|
ui_interfaces/x11/GlxInterface.cpp
|
||||||
|
)
|
||||||
|
list(APPEND platform_LIBS ${X11_LIBRARIES} ${X11_xcb_LIB} ${X11_X11_xcb_LIB})
|
||||||
|
else()
|
||||||
|
message(STATUS "x11 development headers not found - skipping support")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
find_path(WAYLAND_CLIENT_INCLUDE_DIR NAMES wayland-client.h)
|
||||||
|
if (NOT ${WAYLAND_CLIENT_INCLUDE_DIR-NOTFOUND})
|
||||||
|
list(APPEND WAYLAND_INCLUDE_DIRS ${WAYLAND_CLIENT_INCLUDE_DIR})
|
||||||
|
|
||||||
|
find_path(WAYLAND_EXTENSIONS_INCLUDE_DIR NAMES xdg-shell-client-protocol.h
|
||||||
|
HINTS ENV WAYLAND_EXTENSION_DIR
|
||||||
)
|
)
|
||||||
|
if(NOT ${WAYLAND_EXTENSIONS_INCLUDE_DIR-NOTFOUND})
|
||||||
|
find_library(
|
||||||
|
WAYLAND_CLIENT_LIBRARY
|
||||||
|
NAMES wayland-client libwayland-client
|
||||||
|
)
|
||||||
|
|
||||||
list(APPEND platform_LIBS
|
list(APPEND WAYLAND_INCLUDE_DIRS ${WAYLAND_EXTENSIONS_INCLUDE_DIR})
|
||||||
X11 X11-xcb xcb )
|
|
||||||
|
|
||||||
|
list(APPEND platform_INCLUDES
|
||||||
find_path(
|
ui_interfaces/wayland/WaylandWindowInterface.cpp
|
||||||
WAYLAND_CLIENT_INCLUDE_DIR
|
ui_interfaces/wayland/WaylandSurface.cpp
|
||||||
NAMES wayland-client.h
|
ui_interfaces/wayland/WaylandBuffer.cpp
|
||||||
)
|
${WAYLAND_EXTENSIONS_INCLUDE_DIR}/xdg-shell-protocol.cpp
|
||||||
list(APPEND WAYLAND_INCLUDE_DIRS ${WAYLAND_CLIENT_INCLUDE_DIR})
|
)
|
||||||
|
set(_HAS_WAYLAND ON)
|
||||||
find_path(
|
else()
|
||||||
WAYLAND_EXTENSIONS_INCLUDE_DIR
|
message(STATUS "Wayland Extensions Header not found - not building Wayland support")
|
||||||
NAMES xdg-shell-client-protocol.h
|
endif()
|
||||||
HINTS ENV WAYLAND_EXTENSION_DIR
|
|
||||||
)
|
|
||||||
if(NOT ${WAYLAND_EXTENSIONS_INCLUDE_DIR-NOTFOUND})
|
|
||||||
find_library(
|
|
||||||
WAYLAND_CLIENT_LIBRARY
|
|
||||||
NAMES wayland-client libwayland-client
|
|
||||||
)
|
|
||||||
|
|
||||||
list(APPEND WAYLAND_INCLUDE_DIRS ${WAYLAND_EXTENSIONS_INCLUDE_DIR})
|
|
||||||
|
|
||||||
list(APPEND platform_INCLUDES
|
|
||||||
ui_interfaces/wayland/WaylandWindowInterface.cpp
|
|
||||||
ui_interfaces/wayland/WaylandSurface.cpp
|
|
||||||
ui_interfaces/wayland/WaylandBuffer.cpp
|
|
||||||
${WAYLAND_EXTENSIONS_INCLUDE_DIR}/xdg-shell-protocol.cpp
|
|
||||||
)
|
|
||||||
set(_HAS_WAYLAND ON)
|
|
||||||
else()
|
else()
|
||||||
message(STATUS "Wayland Extensions Header not found - not building Wayland support")
|
message(STATUS "Wayland Client Header not found - not building Wayland support")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
else()
|
else()
|
||||||
|
|
|
@ -11,15 +11,13 @@ list(APPEND TestFiles
|
||||||
audio/TestAudioWriter.cpp
|
audio/TestAudioWriter.cpp
|
||||||
audio/TestMidiReader.cpp
|
audio/TestMidiReader.cpp
|
||||||
core/TestBinaryStream.cpp
|
core/TestBinaryStream.cpp
|
||||||
core/TestTomlReader.cpp
|
core/TestTomlReader.cpp
|
||||||
compiler/TestLexer.cpp
|
compiler/TestLexer.cpp
|
||||||
compiler/TestTemplatingEngine.cpp
|
compiler/TestTemplatingEngine.cpp
|
||||||
compression/TestStreamCompressor.cpp
|
compression/TestStreamCompressor.cpp
|
||||||
database/TestDatabase.cpp
|
database/TestDatabase.cpp
|
||||||
fonts/TestFontReader.cpp
|
fonts/TestFontReader.cpp
|
||||||
graphics/TestOpenGlRendering.cpp
|
|
||||||
graphics/TestRasterizer.cpp
|
graphics/TestRasterizer.cpp
|
||||||
ipc/TestDbus.cpp
|
|
||||||
image/TestPngReader.cpp
|
image/TestPngReader.cpp
|
||||||
image/TestPngWriter.cpp
|
image/TestPngWriter.cpp
|
||||||
network/TestNetworkManagerClient.cpp
|
network/TestNetworkManagerClient.cpp
|
||||||
|
@ -30,20 +28,33 @@ list(APPEND TestFiles
|
||||||
|
|
||||||
if (${HAS_FFMPEG})
|
if (${HAS_FFMPEG})
|
||||||
list(APPEND TestFiles
|
list(APPEND TestFiles
|
||||||
video/TestVideoDecoder.cpp
|
video/TestVideoDecoder.cpp
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if (${HAS_WAYLAND})
|
if (${HAS_WAYLAND})
|
||||||
list(APPEND TestFiles
|
list(APPEND TestFiles
|
||||||
windows/TestWaylandWindow.cpp
|
windows/TestWaylandWindow.cpp
|
||||||
)
|
)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
find_package(OpenGL QUIET)
|
||||||
|
if (OpenGL_FOUND)
|
||||||
|
list(APPEND TestFiles
|
||||||
|
graphics/TestOpenGlRendering.cpp
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
find_package(PkgConfig)
|
find_package(PkgConfig)
|
||||||
pkg_check_modules(DBUS dbus-1)
|
pkg_check_modules(DBUS dbus-1)
|
||||||
include_directories(${DBUS_INCLUDE_DIRS})
|
if (DBUS_FOUND)
|
||||||
link_directories(${DBUS_LIBRARY_DIRS})
|
include_directories(${DBUS_INCLUDE_DIRS})
|
||||||
|
link_directories(${DBUS_LIBRARY_DIRS})
|
||||||
|
list(APPEND TestFiles
|
||||||
|
ipc/TestDbus.cpp
|
||||||
|
)
|
||||||
|
endif()
|
||||||
|
|
||||||
foreach(TestFile ${TestFiles})
|
foreach(TestFile ${TestFiles})
|
||||||
cmake_path(GET TestFile FILENAME TestFileName)
|
cmake_path(GET TestFile FILENAME TestFileName)
|
||||||
|
|
Loading…
Reference in a new issue