From 0fd9d5bef3986b5d4ab97d74e7efdaf04ef49b01 Mon Sep 17 00:00:00 2001 From: new house Date: Sat, 14 May 2016 23:47:58 +0200 Subject: [PATCH 01/92] modified makefile to put .o in obj dir --- makefile | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) diff --git a/makefile b/makefile index 4002fff..84431b9 100644 --- a/makefile +++ b/makefile @@ -1,18 +1,40 @@ CXX=g++ CXXFLAGS=-std=c++11 -Wall -Wextra -pedantic -Iinclude -LIBS=-pthread -lsfml-system -lsfml-audio -lmpg123 -lboost_system -lboost_filesystem -lboost_program_options -ltag -lsqlite3 - -DEPS = include/manager.h include/config.h include/music.h include/musiclist.h include/database.h include/mp3.h include/song.h -OBJ = src/main.o src/manager.o src/config.o src/music.o src/musiclist.o src/database.o src/mp3.o src/song.o - -src/%.o: src/%.cpp $(DEPS) +SRCDIR=src +INCDIR=include +OBJDIR=obj + +SOURCES=$(shell find $(SRCDIR) -name "*.cpp") +INCLUDE=$(shell find $(INCDIR) -name "*.h") + +LIBS=-pthread \ + -lsfml-system \ + -lsfml-audio \ + -lmpg123 \ + -lboost_system \ + -lboost_filesystem \ + -lboost_program_options \ + -ltag -lsqlite3 + +_OBJ = main.o \ + manager.o \ + config.o \ + music.o \ + musiclist.o \ + database.o \ + mp3.o \ + song.o + +OBJ = $(patsubst %, $(OBJDIR)/%, $(_OBJ)) + +$(OBJDIR)/%.o: $(SRCDIR)/%.cpp $(INCLUDE) $(CXX) -c -o $@ $< $(CXXFLAGS) release: clean release: CXXFLAGS += -O3 -flto release: LIBS += -flto -release: player++ +release: player++ address: CXXFLAGS += -fsanitize=address address: LIBS += -fsanitize=address @@ -24,18 +46,16 @@ thread: debug debug: clean debug: CXXFLAGS += -ggdb -Og -DDEBUG - debug: player++ player++: $(OBJ) $(CXX) -o dplayer++ $(OBJ) $(LIBS) clean: - rm -f dplayer++ src/*.o + rm -f dplayer++ $(OBJDIR)/*.o *~ install: cp dplayer++ /usr/local/bin/ uninstall: rm /usr/local/bin/dplayer++ - From ba3df80c2b5e34f404e374d5c2cd8cd55cea83ba Mon Sep 17 00:00:00 2001 From: new house Date: Sat, 14 May 2016 23:58:30 +0200 Subject: [PATCH 02/92] added new rule to create obj folder if not exist --- makefile | 1 + 1 file changed, 1 insertion(+) diff --git a/makefile b/makefile index 84431b9..d8b6fbb 100644 --- a/makefile +++ b/makefile @@ -5,6 +5,7 @@ SRCDIR=src INCDIR=include OBJDIR=obj +CREATE_OBJ_DIR := $(shell mkdir -p $(OBJDIR)) SOURCES=$(shell find $(SRCDIR) -name "*.cpp") INCLUDE=$(shell find $(INCDIR) -name "*.h") From eaf2740cb8e4d727ef1aea2c364e3ff18397b2ab Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Sun, 15 May 2016 15:44:29 +0200 Subject: [PATCH 03/92] catch exceptions in main --- src/main.cpp | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index ad107cf..90ee874 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -2,6 +2,9 @@ #include +#include +#include + //Copied from the net. void daemonize() { pid_t pid, sid; @@ -52,7 +55,10 @@ int main() { #ifndef DEBUG daemonize(); #endif - - Manager manager; - manager.StartServer(); + try { + Manager manager; + manager.StartServer(); + } catch(std::exception& e) { + std::cerr << e.what() << std::endl; + } } \ No newline at end of file From e50915e93522849a37c8af96de0447dd612bc890 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Sun, 15 May 2016 15:51:20 +0200 Subject: [PATCH 04/92] update example --- player++.config.example | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/player++.config.example b/player++.config.example index abe2e06..7584ae1 100644 --- a/player++.config.example +++ b/player++.config.example @@ -1,5 +1,5 @@ #daemon_pipe = /tmp/dplayer++ #client_pipe = /tmp/cplayer++ -music_folder = /home/david/Music +music_folder = ~/Music auto_start = false pid_file = /tmp/player++.pid From 752e80e0566dece4ea92bf4f687c11fea95d98ca Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Mon, 16 May 2016 01:15:10 +0200 Subject: [PATCH 05/92] POC of filter feature --- include/commands.h | 1 + include/music.h | 30 ++++++++++++++++++++++++++++++ include/musiclist.h | 12 +++++++++--- src/manager.cpp | 15 +++++++++++++++ src/music.cpp | 10 +++++++++- src/musiclist.cpp | 25 +++++++++++++++++++++++-- 6 files changed, 87 insertions(+), 6 deletions(-) diff --git a/include/commands.h b/include/commands.h index 764e95e..10fe6d8 100644 --- a/include/commands.h +++ b/include/commands.h @@ -11,4 +11,5 @@ enum class Command : char { GET_ARTIST, GET_TITLE, GET_FILE, + FILTER_ARTIST, }; \ No newline at end of file diff --git a/include/music.h b/include/music.h index d67d8c3..85c168b 100644 --- a/include/music.h +++ b/include/music.h @@ -24,6 +24,35 @@ enum class Status { Restart, }; + +class Semaphore { +public: + Semaphore (int count_ = 0) + : count(count_) {} + + inline void notify() + { + std::unique_lock lock(mtx); + count++; + cv.notify_one(); + } + + inline void wait() + { + std::unique_lock lock(mtx); + + while(count == 0){ + cv.wait(lock); + } + count--; + } + +private: + std::mutex mtx; + std::condition_variable cv; + int count; +}; + class Music { public: void PlayList(); @@ -50,6 +79,7 @@ class Music { sf::Music music; sfe::mp3 mp3music; + Semaphore sem{1}; std::condition_variable cv; }; \ No newline at end of file diff --git a/include/musiclist.h b/include/musiclist.h index 695f5d6..68e9e54 100644 --- a/include/musiclist.h +++ b/include/musiclist.h @@ -14,15 +14,21 @@ enum class Order { class MusicList { public: + ~MusicList(); //Search music recursively in the "dir" path and add it to the db void LoadDir(path dir); void Sort(Order s); - const std::vector& GetSongList() const; + void FilterArtist(const char* artist); + + const std::vector& GetSongList() const; private: bool IsSupported(path p); - //List of songs paths - std::vector song_list; + //List of songs that will be reproduced + std::vector song_list; + + //List with all songs; + std::vector full_list; }; \ No newline at end of file diff --git a/src/manager.cpp b/src/manager.cpp index 43b02e0..66be4bc 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -132,5 +132,20 @@ void Manager::ExecuteCommand(Command c) { file.close(); } break; + case Command::FILTER_ARTIST: + { + std::string s; + std::fstream file(conf.GetDaemonPipe()); + getline(file, s); + file.close(); + music.GetList().FilterArtist(s.c_str()); + + //Stop the execution and restore to the previous status + //so we can use the new playlist + auto tmp = music.GetStatus(); + music.SetStatus(Status::Stoped); + music.SetStatus(tmp); + } + break; } } diff --git a/src/music.cpp b/src/music.cpp index 9243599..16909b2 100644 --- a/src/music.cpp +++ b/src/music.cpp @@ -21,7 +21,9 @@ void Music::PlayList() { if(state == Status::Exit || state == Status::Stoped) break; if(state == Status::Forwarding) SetStatus(Status::Playing); - song = *s; + sem.notify(); + + song = **s; Play(); if(GetStatus() == Status::Backing) { @@ -29,6 +31,7 @@ void Music::PlayList() { SetStatus(Status::Playing); } } + sem.notify(); } } @@ -43,8 +46,13 @@ Status Music::GetStatus() const { } void Music::SetStatus(Status s) { + //Wait the previous status to be processed + sem.wait(); + std::lock_guard song_guard(song_mutex); + status = s; + cv.notify_one(); } diff --git a/src/musiclist.cpp b/src/musiclist.cpp index 8b8d019..7707db1 100644 --- a/src/musiclist.cpp +++ b/src/musiclist.cpp @@ -7,6 +7,11 @@ //Public functions +MusicList::~MusicList() { + for(auto s : full_list) + delete s; +} + void MusicList::LoadDir(path p) { if(!is_directory(p)) { throw std::runtime_error("Error con el directorio"); @@ -17,9 +22,14 @@ void MusicList::LoadDir(path p) { if(is_directory(pathSong)) LoadDir(pathSong); - if(IsSupported(pathSong)) song_list.emplace_back(Song(pathSong)); + if(IsSupported(pathSong)) full_list.emplace_back(new Song(pathSong)); } + //Copy pointers of full_list so song_list + //So all the songs are able to be reproduced + for(auto s : full_list) + song_list.emplace_back(s); + #ifdef DEBUG std::cerr << "Loaded " << p << std::endl; #endif @@ -34,7 +44,18 @@ void MusicList::Sort(Order s) { } } -const std::vector& MusicList::GetSongList() const { +void MusicList::FilterArtist(const char* artist) { + song_list.clear(); + for(auto s : full_list ) { + #ifdef DEBUG + std::cout << "Analyzing " << s->GetFile() << std::endl; + #endif + if(s->GetArtist() == artist) + song_list.emplace_back(s); + } +} + +const std::vector& MusicList::GetSongList() const { return song_list; } From 7601e1403db314d2fb34f67eee5c40a749949581 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Mon, 16 May 2016 11:00:20 +0200 Subject: [PATCH 06/92] update filterArtist --- include/musiclist.h | 3 ++- src/manager.cpp | 2 +- src/musiclist.cpp | 2 +- 3 files changed, 4 insertions(+), 3 deletions(-) diff --git a/include/musiclist.h b/include/musiclist.h index 68e9e54..de89a07 100644 --- a/include/musiclist.h +++ b/include/musiclist.h @@ -5,6 +5,7 @@ #include #include +#include using namespace boost::filesystem; @@ -20,7 +21,7 @@ class MusicList { void Sort(Order s); - void FilterArtist(const char* artist); + void FilterArtist(const std::string artist); const std::vector& GetSongList() const; private: diff --git a/src/manager.cpp b/src/manager.cpp index 66be4bc..cad380c 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -138,7 +138,7 @@ void Manager::ExecuteCommand(Command c) { std::fstream file(conf.GetDaemonPipe()); getline(file, s); file.close(); - music.GetList().FilterArtist(s.c_str()); + music.GetList().FilterArtist(s); //Stop the execution and restore to the previous status //so we can use the new playlist diff --git a/src/musiclist.cpp b/src/musiclist.cpp index 7707db1..f659ba6 100644 --- a/src/musiclist.cpp +++ b/src/musiclist.cpp @@ -44,7 +44,7 @@ void MusicList::Sort(Order s) { } } -void MusicList::FilterArtist(const char* artist) { +void MusicList::FilterArtist(const std::string artist) { song_list.clear(); for(auto s : full_list ) { #ifdef DEBUG From 93a32351f0d0775970d6536eea7874b1cbe2f4be Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Mon, 16 May 2016 11:01:12 +0200 Subject: [PATCH 07/92] wait Status to be processed --- include/music.h | 20 ++++++++++---------- src/music.cpp | 40 +++++++++++++++++++++++++--------------- 2 files changed, 35 insertions(+), 25 deletions(-) diff --git a/include/music.h b/include/music.h index 85c168b..b53c7ee 100644 --- a/include/music.h +++ b/include/music.h @@ -25,15 +25,12 @@ enum class Status { }; -class Semaphore { +class MyMutex { public: - Semaphore (int count_ = 0) - : count(count_) {} - inline void notify() { std::unique_lock lock(mtx); - count++; + count = 1; cv.notify_one(); } @@ -41,16 +38,15 @@ class Semaphore { { std::unique_lock lock(mtx); - while(count == 0){ - cv.wait(lock); - } + cv.wait(lock, [this]{return count>0;}); + count--; } private: std::mutex mtx; std::condition_variable cv; - int count; + int count {1}; }; class Music { @@ -72,6 +68,10 @@ class Music { template void Reproduce(T&, const char* song); + bool IsStatus(Status s); + bool IsNotStatus(Status s); + + Status status {Status::Stoped}; MusicList list; Song song; @@ -79,7 +79,7 @@ class Music { sf::Music music; sfe::mp3 mp3music; - Semaphore sem{1}; + MyMutex mymutex; std::condition_variable cv; }; \ No newline at end of file diff --git a/src/music.cpp b/src/music.cpp index 16909b2..d9d4fa5 100644 --- a/src/music.cpp +++ b/src/music.cpp @@ -13,25 +13,23 @@ void Music::PlayList() { //Wait here until state is not Stoped std::mutex cv_m; std::unique_lock lk{cv_m}; - cv.wait(lk, [this]{return GetStatus() != Status::Stoped;}); + cv.wait(lk, [this]{return IsNotStatus(Status::Stoped);}); auto& musicList = list.GetSongList(); for(auto s = musicList.begin(); s != musicList.end(); ++s) { - auto state = GetStatus(); - if(state == Status::Exit || state == Status::Stoped) break; - if(state == Status::Forwarding) SetStatus(Status::Playing); + if(IsStatus(Status::Exit) || IsStatus(Status::Stoped)) break; + if(IsStatus(Status::Forwarding)) SetStatus(Status::Playing); - sem.notify(); - - song = **s; - Play(); + if(IsStatus(Status::Playing)) { + song = **s; + Play(); + } - if(GetStatus() == Status::Backing) { + if(IsStatus(Status::Backing)) { s-=2; SetStatus(Status::Playing); } } - sem.notify(); } } @@ -47,7 +45,7 @@ Status Music::GetStatus() const { void Music::SetStatus(Status s) { //Wait the previous status to be processed - sem.wait(); + mymutex.wait(); std::lock_guard song_guard(song_mutex); @@ -56,6 +54,18 @@ void Music::SetStatus(Status s) { cv.notify_one(); } +bool Music::IsStatus(Status s) { + bool tmp = GetStatus()==s; + if(tmp) mymutex.notify(); + return tmp; +} + +bool Music::IsNotStatus(Status s) { + bool tmp = GetStatus()!=s; + if(tmp) mymutex.notify(); + return tmp; +} + MusicList& Music::GetList() { return list; } @@ -108,14 +118,14 @@ void Music::Reproduce(T& music, const char* song) { #endif //Wait until we have something to do or until the song finish - cv.wait_for(lk, std::chrono::milliseconds(sleep_time), [this]{return GetStatus() != Status::Playing;}); + cv.wait_for(lk, std::chrono::milliseconds(sleep_time), [this]{return IsNotStatus(Status::Playing);}); - if(GetStatus() == Status::Paused) { + if(IsStatus(Status::Paused)) { music.pause(); - cv.wait(lk, [this]{return GetStatus() != Status::Paused;}); + cv.wait(lk, [this]{return IsNotStatus(Status::Paused);}); music.play(); loop = true; - } else if(GetStatus() == Status::Restart) { + } else if(IsStatus(Status::Restart)) { music.setPlayingOffset(sf::seconds(0)); status = Status::Playing; } From 5f095f767803bff9a3a512484423fcb8b8eec47f Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Mon, 16 May 2016 11:08:57 +0200 Subject: [PATCH 08/92] fix data race --- include/musiclist.h | 8 ++++---- src/musiclist.cpp | 9 ++------- 2 files changed, 6 insertions(+), 11 deletions(-) diff --git a/include/musiclist.h b/include/musiclist.h index de89a07..b2407ba 100644 --- a/include/musiclist.h +++ b/include/musiclist.h @@ -6,6 +6,7 @@ #include #include #include +#include using namespace boost::filesystem; @@ -15,7 +16,6 @@ enum class Order { class MusicList { public: - ~MusicList(); //Search music recursively in the "dir" path and add it to the db void LoadDir(path dir); @@ -23,13 +23,13 @@ class MusicList { void FilterArtist(const std::string artist); - const std::vector& GetSongList() const; + const std::vector>& GetSongList() const; private: bool IsSupported(path p); //List of songs that will be reproduced - std::vector song_list; + std::vector> song_list; //List with all songs; - std::vector full_list; + std::vector> full_list; }; \ No newline at end of file diff --git a/src/musiclist.cpp b/src/musiclist.cpp index f659ba6..afc1e65 100644 --- a/src/musiclist.cpp +++ b/src/musiclist.cpp @@ -7,11 +7,6 @@ //Public functions -MusicList::~MusicList() { - for(auto s : full_list) - delete s; -} - void MusicList::LoadDir(path p) { if(!is_directory(p)) { throw std::runtime_error("Error con el directorio"); @@ -22,7 +17,7 @@ void MusicList::LoadDir(path p) { if(is_directory(pathSong)) LoadDir(pathSong); - if(IsSupported(pathSong)) full_list.emplace_back(new Song(pathSong)); + if(IsSupported(pathSong)) full_list.emplace_back(std::make_shared(pathSong)); } //Copy pointers of full_list so song_list @@ -55,7 +50,7 @@ void MusicList::FilterArtist(const std::string artist) { } } -const std::vector& MusicList::GetSongList() const { +const std::vector>& MusicList::GetSongList() const { return song_list; } From 29d853125c855ef43d7bd7d77453b8cfd8f5e7f9 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Mon, 16 May 2016 16:45:56 +0200 Subject: [PATCH 09/92] make status member atomic so we don't need locks. --- include/music.h | 4 ++-- src/music.cpp | 6 ------ 2 files changed, 2 insertions(+), 8 deletions(-) diff --git a/include/music.h b/include/music.h index b53c7ee..76e3c21 100644 --- a/include/music.h +++ b/include/music.h @@ -9,6 +9,7 @@ #include #include #include +#include using namespace boost::filesystem; @@ -71,8 +72,7 @@ class Music { bool IsStatus(Status s); bool IsNotStatus(Status s); - - Status status {Status::Stoped}; + std::atomic status{Status::Stoped}; MusicList list; Song song; diff --git a/src/music.cpp b/src/music.cpp index d9d4fa5..d937e62 100644 --- a/src/music.cpp +++ b/src/music.cpp @@ -4,8 +4,6 @@ #include "music.h" -static std::mutex song_mutex; - //Public functions void Music::PlayList() { @@ -39,7 +37,6 @@ void Music::Play() { } Status Music::GetStatus() const { - std::lock_guard song_guard(song_mutex); return status; } @@ -47,8 +44,6 @@ void Music::SetStatus(Status s) { //Wait the previous status to be processed mymutex.wait(); - std::lock_guard song_guard(song_mutex); - status = s; cv.notify_one(); @@ -71,7 +66,6 @@ MusicList& Music::GetList() { } Song& Music::GetCurrent() { - std::lock_guard song_guard(song_mutex); return song; } From ba2f26036b995d574ad526a69f2d1afc0e9219fd Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Mon, 16 May 2016 17:16:38 +0200 Subject: [PATCH 10/92] simplify copy --- src/musiclist.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/musiclist.cpp b/src/musiclist.cpp index afc1e65..f7da091 100644 --- a/src/musiclist.cpp +++ b/src/musiclist.cpp @@ -22,8 +22,7 @@ void MusicList::LoadDir(path p) { //Copy pointers of full_list so song_list //So all the songs are able to be reproduced - for(auto s : full_list) - song_list.emplace_back(s); + song_list = full_list; #ifdef DEBUG std::cerr << "Loaded " << p << std::endl; From aacd907595fcc1a56860bf65b90c9606725475bc Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Mon, 16 May 2016 17:30:42 +0200 Subject: [PATCH 11/92] use boost recursive iterator --- src/musiclist.cpp | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/src/musiclist.cpp b/src/musiclist.cpp index f7da091..e271c17 100644 --- a/src/musiclist.cpp +++ b/src/musiclist.cpp @@ -12,21 +12,21 @@ void MusicList::LoadDir(path p) { throw std::runtime_error("Error con el directorio"); } - for(auto& entry : boost::make_iterator_range(directory_iterator(p), {})) { - const auto pathSong = entry.path(); - if(is_directory(pathSong)) LoadDir(pathSong); - - - if(IsSupported(pathSong)) full_list.emplace_back(std::make_shared(pathSong)); + for(recursive_directory_iterator dir(p), end; dir != end; ++dir) { + const auto pathSong = dir->path(); + + if(!is_directory(pathSong) && IsSupported(pathSong)) { + #ifdef DEBUG + std::cerr << "Loaded " << pathSong << std::endl; + #endif + + full_list.emplace_back(std::make_shared(pathSong)); + } } //Copy pointers of full_list so song_list //So all the songs are able to be reproduced song_list = full_list; - - #ifdef DEBUG - std::cerr << "Loaded " << p << std::endl; - #endif } void MusicList::Sort(Order s) { From 3ac0c8898e22bc9c806813bae46687b7df06c502 Mon Sep 17 00:00:00 2001 From: David Date: Sat, 21 May 2016 17:05:44 +0200 Subject: [PATCH 12/92] Update README.md --- README.md | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+) diff --git a/README.md b/README.md index 595166e..12baee0 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,25 @@ # cppplayer Reproductor de música sencillo que busca la simplicidad y facilidad de configuración (se podría ver como alternativa a mpd) + +El programa usa las librerías mpg123, sfml, TagLib boost-program-options y boost-filesystem. + +#### Instalación en Debian/Ubuntu + +**# apt-get install libmpg123-dev libsfml-dev libboost-filesystem-dev libboost-program-options-dev libtag1-dev** + +#### Features + +- Avanzar/Retroceder/Pausar/Reproducir etc +- Distintos sorts (actualmente solo funciona el modo aleatorio) +- Distintos filtros (actualmente solo funciona el filtro por artista) +- Fácilmente "scripteable" + + +#### TODO + +- Playlists +- Base de datos SQL +- Soporte para plugins +- Ecualizador +- Cache de canciones recientes (para agilizar la búsqueda) From 0607ded735faad645b3ba0cb6fdc46085c0c2367 Mon Sep 17 00:00:00 2001 From: David Date: Sun, 22 May 2016 02:03:49 +0200 Subject: [PATCH 13/92] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 12baee0..c99a6f0 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,10 @@ El programa usa las librerías mpg123, sfml, TagLib boost-program-options y boos **# apt-get install libmpg123-dev libsfml-dev libboost-filesystem-dev libboost-program-options-dev libtag1-dev** +#### Configuración + +El programa al iniciar lee la configuración de ~/.config/player++/daemon.conf + #### Features - Avanzar/Retroceder/Pausar/Reproducir etc From afdd48d01a40801f1b66e936e880893d9005c3e8 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Sun, 22 May 2016 12:20:02 +0200 Subject: [PATCH 14/92] update mp3.cpp --- src/mp3.cpp | 37 +++++++++++++++++-------------------- 1 file changed, 17 insertions(+), 20 deletions(-) diff --git a/src/mp3.cpp b/src/mp3.cpp index cccdf07..b25d229 100644 --- a/src/mp3.cpp +++ b/src/mp3.cpp @@ -8,6 +8,19 @@ myHandle (NULL), myBufferSize(0), myBuffer (NULL) { + int err = MPG123_OK; + if ((err = mpg123_init()) != MPG123_OK) + { + std::cerr << mpg123_plain_strerror(err) << std::endl; + return; + } + + myHandle = mpg123_new(NULL, &err); + if (!myHandle) + { + std::cerr << "Unable to create mpg123 handle: " << mpg123_plain_strerror(err) << std::endl; + return; + } } @@ -35,27 +48,11 @@ bool mp3::openFromFile(const std::string& filename) stop(); if (myBuffer) - { delete [] myBuffer; - myBuffer = NULL; - } - mpg123_close(myHandle); - mpg123_delete(myHandle); - mpg123_exit(); + + if(myHandle) + mpg123_close(myHandle); - int err = MPG123_OK; - if ((err = mpg123_init()) != MPG123_OK) - { - std::cerr << mpg123_plain_strerror(err) << std::endl; - return false; - } - - myHandle = mpg123_new(NULL, &err); - if (!myHandle) - { - std::cerr << "Unable to create mpg123 handle: " << mpg123_plain_strerror(err) << std::endl; - return false; - } mpg123_param(myHandle, MPG123_RESYNC_LIMIT, -1, 0); #ifndef DEBUG @@ -71,7 +68,7 @@ bool mp3::openFromFile(const std::string& filename) //This should improve myDuration calculation, but generates frankenstein streams¿? //Warning: Real sample count 9505152 differs from given gapless sample count -1152. Frankenstein stream if(mpg123_scan(myHandle) != MPG123_OK) { - std::cerr << "Failed when scanning: " << mpg123_plain_strerror(err) << std::endl; + std::cerr << "Failed when scanning " << std::endl; return false; } From 7dda1393acf70f3886753dc39bcddb27281dcb20 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Sun, 22 May 2016 12:20:53 +0200 Subject: [PATCH 15/92] add commands ADD_FILE & ADD_FOLDER Add commands to add songs into the current playlist. --- include/commands.h | 2 ++ include/musiclist.h | 3 +++ src/manager.cpp | 18 ++++++++++++++++++ src/musiclist.cpp | 23 +++++++++++------------ 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/include/commands.h b/include/commands.h index 10fe6d8..aac4c43 100644 --- a/include/commands.h +++ b/include/commands.h @@ -12,4 +12,6 @@ enum class Command : char { GET_TITLE, GET_FILE, FILTER_ARTIST, + ADD_FOLDER, + ADD_FILE, }; \ No newline at end of file diff --git a/include/musiclist.h b/include/musiclist.h index b2407ba..b90dda5 100644 --- a/include/musiclist.h +++ b/include/musiclist.h @@ -19,6 +19,9 @@ class MusicList { //Search music recursively in the "dir" path and add it to the db void LoadDir(path dir); + void LoadFile(const path pathSong); + + void Sort(Order s); void FilterArtist(const std::string artist); diff --git a/src/manager.cpp b/src/manager.cpp index cad380c..9562e58 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -147,5 +147,23 @@ void Manager::ExecuteCommand(Command c) { music.SetStatus(tmp); } break; + case Command::ADD_FOLDER: + { + std::string s; + std::fstream file(conf.GetDaemonPipe()); + getline(file, s); + file.close(); + music.GetList().LoadDir(s); + } + break; + case Command::ADD_FILE: + { + std::string s; + std::fstream file(conf.GetDaemonPipe()); + getline(file, s); + file.close(); + music.GetList().LoadFile(s); + } + break; } } diff --git a/src/musiclist.cpp b/src/musiclist.cpp index e271c17..e883b2b 100644 --- a/src/musiclist.cpp +++ b/src/musiclist.cpp @@ -13,20 +13,19 @@ void MusicList::LoadDir(path p) { } for(recursive_directory_iterator dir(p), end; dir != end; ++dir) { - const auto pathSong = dir->path(); - - if(!is_directory(pathSong) && IsSupported(pathSong)) { - #ifdef DEBUG - std::cerr << "Loaded " << pathSong << std::endl; - #endif - - full_list.emplace_back(std::make_shared(pathSong)); - } + LoadFile(dir->path()); } +} - //Copy pointers of full_list so song_list - //So all the songs are able to be reproduced - song_list = full_list; +void MusicList::LoadFile(const path pathSong) { + if(!is_directory(pathSong) && IsSupported(pathSong)) { + #ifdef DEBUG + std::cerr << "Loaded " << pathSong << std::endl; + #endif + auto song = std::make_shared(pathSong); + full_list.emplace_back(song); + song_list.emplace_back(song); + } } void MusicList::Sort(Order s) { From 402d42d130bea48b7c95650b0fb9d1e9237044b8 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Thu, 26 May 2016 16:20:25 +0200 Subject: [PATCH 16/92] create global config_folder constat --- include/config.h | 15 +++++++++++---- src/config.cpp | 4 ++-- 2 files changed, 13 insertions(+), 6 deletions(-) diff --git a/include/config.h b/include/config.h index 637a4cc..489683c 100644 --- a/include/config.h +++ b/include/config.h @@ -1,3 +1,5 @@ +#pragma once + #include #include @@ -6,6 +8,8 @@ using namespace boost::program_options; using namespace boost::filesystem; +const std::string CONFIG_FOLDER = "~/.config/player++/"; + class Config { public: void Load(); @@ -20,16 +24,19 @@ class Config { std::string GetHome(); struct Options { //Pipe used by the daemon to write to client - std::string daemonpipe = "/tmp/dplayer++"; + std::string daemonpipe = "/tmp/dplayer++"; //Pipe used by the client to write to daemon - std::string clientpipe = "/tmp/cplayer++"; + std::string clientpipe = "/tmp/cplayer++"; //File to store the pid number so we can check if the daemon is really running - std::string pidfile = "/tmp/player++.pid"; + std::string pidfile = "/tmp/player++.pid"; //Database file - std::string dbfile = "~/.config/player++/db.sql"; + std::string dbfile = CONFIG_FOLDER+"db.sql"; + + //Playlist folder + std::string playlistfolder = CONFIG_FOLDER+"playlist/"; //Location of the songs path dir = "."; diff --git a/src/config.cpp b/src/config.cpp index 26190cd..0f23472 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -10,10 +10,10 @@ using namespace boost::program_options; void Config::Load() { #ifdef DEBUG - std::cout << "Using config file " << MakeAbsolute("~/.config/player++/daemon.conf") << std::endl; + std::cout << "Using config file " << MakeAbsolute(CONFIG_FOLDER+"daemon.conf") << std::endl; #endif - std::ifstream config(MakeAbsolute("~/.config/player++/daemon.conf")); + std::ifstream config(MakeAbsolute(CONFIG_FOLDER+"daemon.conf")); if(!config.is_open()) { std::cerr << "Config file could not be open, using default values" << std::endl; } else { From 6606b2280bed95e540f3137e5205ffdb4412b735 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Thu, 26 May 2016 23:59:42 +0200 Subject: [PATCH 17/92] create CMakeLists.txt --- .gitignore | 2 ++ CMakeLists.txt | 8 ++++++++ README.md | 3 +++ 3 files changed, 13 insertions(+) create mode 100644 CMakeLists.txt diff --git a/.gitignore b/.gitignore index 6091885..b19fce4 100644 --- a/.gitignore +++ b/.gitignore @@ -27,3 +27,5 @@ *.out *.app player++ + +build/* diff --git a/CMakeLists.txt b/CMakeLists.txt new file mode 100644 index 0000000..ab3762e --- /dev/null +++ b/CMakeLists.txt @@ -0,0 +1,8 @@ +cmake_minimum_required (VERSION 2.6) +project (cppplayer) + +set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wextra -pedantic") +set( CMAKE_EXE_LINKER_FLAGS "-pthread -lsfml-system -lsfml-audio -lmpg123 -lboost_system -lboost_filesystem -lboost_program_options -ltag -lsqlite3" ) + +include_directories(include) +add_executable(dplayer++ src/main.cpp src/config.cpp src/database.cpp src/mp3.cpp src/manager.cpp src/music.cpp src/musiclist.cpp src/song.cpp) diff --git a/README.md b/README.md index c99a6f0..dd06c0c 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,9 @@ El programa usa las librerías mpg123, sfml, TagLib boost-program-options y boos **# apt-get install libmpg123-dev libsfml-dev libboost-filesystem-dev libboost-program-options-dev libtag1-dev** +Para compilarlo + mkdir -p build; cd build; cmake ..; make + #### Configuración El programa al iniciar lee la configuración de ~/.config/player++/daemon.conf From b08d7542010aaaf7f2138ac391014102f30b9c11 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Fri, 27 May 2016 00:09:25 +0200 Subject: [PATCH 18/92] update CMakeLists.txt --- CMakeLists.txt | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index ab3762e..b46592a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,10 @@ -cmake_minimum_required (VERSION 2.6) +cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR) project (cppplayer) -set(CMAKE_CXX_FLAGS "-std=c++11 -Wall -Wextra -pedantic") -set( CMAKE_EXE_LINKER_FLAGS "-pthread -lsfml-system -lsfml-audio -lmpg123 -lboost_system -lboost_filesystem -lboost_program_options -ltag -lsqlite3" ) - include_directories(include) add_executable(dplayer++ src/main.cpp src/config.cpp src/database.cpp src/mp3.cpp src/manager.cpp src/music.cpp src/musiclist.cpp src/song.cpp) +target_compile_features(dplayer++ PUBLIC cxx_range_for cxx_auto_type cxx_lambdas cxx_aggregate_default_initializers) + +set(CMAKE_CXX_FLAGS "-Wall -Wextra -pedantic") +set( CMAKE_EXE_LINKER_FLAGS "-pthread -lsfml-system -lsfml-audio -lmpg123 -lboost_system -lboost_filesystem -lboost_program_options -ltag -lsqlite3" ) + From 7c00c4e25720937e065d761d5827f0ea06a58965 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Fri, 27 May 2016 00:17:47 +0200 Subject: [PATCH 19/92] cmake: use glob to search for source files --- CMakeLists.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index b46592a..718c54d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -2,7 +2,9 @@ cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR) project (cppplayer) include_directories(include) -add_executable(dplayer++ src/main.cpp src/config.cpp src/database.cpp src/mp3.cpp src/manager.cpp src/music.cpp src/musiclist.cpp src/song.cpp) +file(GLOB_RECURSE SRC_FILES src/*.cpp) +add_executable(dplayer++ ${SRC_FILES}) + target_compile_features(dplayer++ PUBLIC cxx_range_for cxx_auto_type cxx_lambdas cxx_aggregate_default_initializers) set(CMAKE_CXX_FLAGS "-Wall -Wextra -pedantic") From d56e0805425f136b6376d8a813ed917898692e4b Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Fri, 27 May 2016 00:26:51 +0200 Subject: [PATCH 20/92] add debug build types --- CMakeLists.txt | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 718c54d..c00fec0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,5 +8,21 @@ add_executable(dplayer++ ${SRC_FILES}) target_compile_features(dplayer++ PUBLIC cxx_range_for cxx_auto_type cxx_lambdas cxx_aggregate_default_initializers) set(CMAKE_CXX_FLAGS "-Wall -Wextra -pedantic") -set( CMAKE_EXE_LINKER_FLAGS "-pthread -lsfml-system -lsfml-audio -lmpg123 -lboost_system -lboost_filesystem -lboost_program_options -ltag -lsqlite3" ) +set(CMAKE_EXE_LINKER_FLAGS "-pthread -lsfml-system -lsfml-audio -lmpg123 -lboost_system -lboost_filesystem -lboost_program_options -ltag -lsqlite3" ) + +#RELEASE +set(CMAKE_CXX_FLAGS_RELEASE "-O3 -flto") +#DEBUG +set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -Og -DDEBUG") +#THREAD SANITIZER +set(CMAKE_BUILD_TYPE thread) +set(CMAKE_CXX_FLAGS_THREAD "-fsanitize=thread") +set(CMAKE_EXE_LINKER_FLAGS_THREAD "-fsanitize=thread") +#ADDRESS SANITIZER +set(CMAKE_BUILD_TYPE address) +set(CMAKE_CXX_FLAGS_THREAD "-fsanitize=address") +set(CMAKE_EXE_LINKER_FLAGS_THREAD "-fsanitize=address") + + + From 47317e33ad50d80eb42d6417784ac4637f1a3544 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Fri, 27 May 2016 00:37:41 +0200 Subject: [PATCH 21/92] cmake: search boost library automatically --- CMakeLists.txt | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index c00fec0..a0f2a27 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,16 +8,33 @@ add_executable(dplayer++ ${SRC_FILES}) target_compile_features(dplayer++ PUBLIC cxx_range_for cxx_auto_type cxx_lambdas cxx_aggregate_default_initializers) set(CMAKE_CXX_FLAGS "-Wall -Wextra -pedantic") -set(CMAKE_EXE_LINKER_FLAGS "-pthread -lsfml-system -lsfml-audio -lmpg123 -lboost_system -lboost_filesystem -lboost_program_options -ltag -lsqlite3" ) +set(CMAKE_EXE_LINKER_FLAGS "-pthread -lsfml-system -lsfml-audio -lmpg123 -ltag -lsqlite3" ) + +#Check if boost exists +set(Boost_USE_STATIC_LIBS OFF) +set(Boost_USE_MULTITHREADED ON) +set(Boost_USE_STATIC_RUNTIME OFF) +find_package(Boost 1.60.0 COMPONENTS filesystem program_options ) + +if(NOT Boost_FOUND) + message( FATAL_ERROR "Boost libraries not found." ) +endif() + +include_directories(${Boost_INCLUDE_DIRS}) +target_link_libraries(dplayer++ ${Boost_LIBRARIES}) + #RELEASE set(CMAKE_CXX_FLAGS_RELEASE "-O3 -flto") + #DEBUG set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -Og -DDEBUG") + #THREAD SANITIZER set(CMAKE_BUILD_TYPE thread) set(CMAKE_CXX_FLAGS_THREAD "-fsanitize=thread") set(CMAKE_EXE_LINKER_FLAGS_THREAD "-fsanitize=thread") + #ADDRESS SANITIZER set(CMAKE_BUILD_TYPE address) set(CMAKE_CXX_FLAGS_THREAD "-fsanitize=address") From 8e4fdf73fc8c3f2a70fea88191bfedb77b6cfb3f Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Fri, 27 May 2016 00:48:16 +0200 Subject: [PATCH 22/92] cmake: search for thread support --- CMakeLists.txt | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a0f2a27..2b6a2bf 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ add_executable(dplayer++ ${SRC_FILES}) target_compile_features(dplayer++ PUBLIC cxx_range_for cxx_auto_type cxx_lambdas cxx_aggregate_default_initializers) set(CMAKE_CXX_FLAGS "-Wall -Wextra -pedantic") -set(CMAKE_EXE_LINKER_FLAGS "-pthread -lsfml-system -lsfml-audio -lmpg123 -ltag -lsqlite3" ) +set(CMAKE_EXE_LINKER_FLAGS "-lsfml-system -lsfml-audio -lmpg123 -ltag -lsqlite3" ) #Check if boost exists set(Boost_USE_STATIC_LIBS OFF) @@ -23,6 +23,15 @@ endif() include_directories(${Boost_INCLUDE_DIRS}) target_link_libraries(dplayer++ ${Boost_LIBRARIES}) +#Find thread library +find_package(Threads) + +if(NOT Threads_FOUND) + message(FATAL_ERROR "This system doesn't support threads.") +endif() + +target_link_libraries(dplayer++ ${CMAKE_THREAD_LIBS_INIT}) + #RELEASE set(CMAKE_CXX_FLAGS_RELEASE "-O3 -flto") From 9616adb3d5220da64b390bf3d2afc5b2be5373b1 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Fri, 27 May 2016 00:56:12 +0200 Subject: [PATCH 23/92] fix cmake and delete old makefile --- CMakeLists.txt | 13 ++++++----- makefile | 62 -------------------------------------------------- 2 files changed, 7 insertions(+), 68 deletions(-) delete mode 100644 makefile diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b6a2bf..4ceef43 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -34,20 +34,21 @@ target_link_libraries(dplayer++ ${CMAKE_THREAD_LIBS_INIT}) #RELEASE -set(CMAKE_CXX_FLAGS_RELEASE "-O3 -flto") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O3 -flto") +set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -flto") #DEBUG -set(CMAKE_CXX_FLAGS_DEBUG "-ggdb -Og -DDEBUG") +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -ggdb -Og -DDEBUG") #THREAD SANITIZER set(CMAKE_BUILD_TYPE thread) -set(CMAKE_CXX_FLAGS_THREAD "-fsanitize=thread") -set(CMAKE_EXE_LINKER_FLAGS_THREAD "-fsanitize=thread") +set(CMAKE_CXX_FLAGS_THREAD "${CMAKE_CXX_FLAGS} -fsanitize=thread") +set(CMAKE_EXE_LINKER_FLAGS_THREAD "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=thread") #ADDRESS SANITIZER set(CMAKE_BUILD_TYPE address) -set(CMAKE_CXX_FLAGS_THREAD "-fsanitize=address") -set(CMAKE_EXE_LINKER_FLAGS_THREAD "-fsanitize=address") +set(CMAKE_CXX_FLAGS_THREAD "${CMAKE_CXX_FLAGS} -fsanitize=address") +set(CMAKE_EXE_LINKER_FLAGS_THREAD "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address") diff --git a/makefile b/makefile deleted file mode 100644 index d8b6fbb..0000000 --- a/makefile +++ /dev/null @@ -1,62 +0,0 @@ -CXX=g++ -CXXFLAGS=-std=c++11 -Wall -Wextra -pedantic -Iinclude - -SRCDIR=src -INCDIR=include -OBJDIR=obj - -CREATE_OBJ_DIR := $(shell mkdir -p $(OBJDIR)) -SOURCES=$(shell find $(SRCDIR) -name "*.cpp") -INCLUDE=$(shell find $(INCDIR) -name "*.h") - -LIBS=-pthread \ - -lsfml-system \ - -lsfml-audio \ - -lmpg123 \ - -lboost_system \ - -lboost_filesystem \ - -lboost_program_options \ - -ltag -lsqlite3 - -_OBJ = main.o \ - manager.o \ - config.o \ - music.o \ - musiclist.o \ - database.o \ - mp3.o \ - song.o - -OBJ = $(patsubst %, $(OBJDIR)/%, $(_OBJ)) - -$(OBJDIR)/%.o: $(SRCDIR)/%.cpp $(INCLUDE) - $(CXX) -c -o $@ $< $(CXXFLAGS) - -release: clean -release: CXXFLAGS += -O3 -flto -release: LIBS += -flto -release: player++ - -address: CXXFLAGS += -fsanitize=address -address: LIBS += -fsanitize=address -address: debug - -thread: CXXFLAGS += -fsanitize=thread -thread: LIBS += -fsanitize=thread -thread: debug - -debug: clean -debug: CXXFLAGS += -ggdb -Og -DDEBUG -debug: player++ - -player++: $(OBJ) - $(CXX) -o dplayer++ $(OBJ) $(LIBS) - -clean: - rm -f dplayer++ $(OBJDIR)/*.o *~ - -install: - cp dplayer++ /usr/local/bin/ - -uninstall: - rm /usr/local/bin/dplayer++ From 4591719154c22b6807a95112139adba5710fc37d Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Fri, 27 May 2016 23:32:38 +0200 Subject: [PATCH 24/92] delete default options --- CMakeLists.txt | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ceef43..d1c7893 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,10 +11,7 @@ set(CMAKE_CXX_FLAGS "-Wall -Wextra -pedantic") set(CMAKE_EXE_LINKER_FLAGS "-lsfml-system -lsfml-audio -lmpg123 -ltag -lsqlite3" ) #Check if boost exists -set(Boost_USE_STATIC_LIBS OFF) -set(Boost_USE_MULTITHREADED ON) -set(Boost_USE_STATIC_RUNTIME OFF) -find_package(Boost 1.60.0 COMPONENTS filesystem program_options ) +find_package(Boost 1.60.0 COMPONENTS filesystem program_options) if(NOT Boost_FOUND) message( FATAL_ERROR "Boost libraries not found." ) From 1896ce11b6cd68952d45e2d3bec9331a6620df1f Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Fri, 27 May 2016 23:33:14 +0200 Subject: [PATCH 25/92] minor fixes & delete redundant code --- src/config.cpp | 2 -- src/manager.cpp | 11 ++++------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/src/config.cpp b/src/config.cpp index 0f23472..6bf28c7 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -31,8 +31,6 @@ void Config::Load() { variables_map vm = variables_map(); store(parse_config_file(config , desc, true), vm); notify(vm); - - config.close(); } opt.daemonpipe =MakeAbsolute(opt.daemonpipe); diff --git a/src/manager.cpp b/src/manager.cpp index 9562e58..c5fb42a 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -81,7 +81,6 @@ Command Manager::ReadCommand() { } auto tmp = static_cast(f.get()); - f.close(); return tmp; } @@ -115,21 +114,18 @@ void Manager::ExecuteCommand(Command c) { { std::fstream file(conf.GetClientPipe()); file << music.GetCurrent().GetArtist() << std::endl; - file.close(); } break; case Command::GET_TITLE: { std::fstream file(conf.GetClientPipe()); file << music.GetCurrent().GetTitle() << std::endl; - file.close(); } break; case Command::GET_FILE: { std::fstream file(conf.GetClientPipe()); file << music.GetCurrent().GetFile() << std::endl; - file.close(); } break; case Command::FILTER_ARTIST: @@ -138,12 +134,11 @@ void Manager::ExecuteCommand(Command c) { std::fstream file(conf.GetDaemonPipe()); getline(file, s); file.close(); - music.GetList().FilterArtist(s); - //Stop the execution and restore to the previous status - //so we can use the new playlist + //Stop reproduction while we are filtering the list auto tmp = music.GetStatus(); music.SetStatus(Status::Stoped); + music.GetList().FilterArtist(s); music.SetStatus(tmp); } break; @@ -165,5 +160,7 @@ void Manager::ExecuteCommand(Command c) { music.GetList().LoadFile(s); } break; + case Command::SAVE_FILE: + break; } } From 88f806a1bb7be6e504381d6612d6f21f0980950a Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Tue, 31 May 2016 00:28:24 +0200 Subject: [PATCH 26/92] comment unimplemented features --- src/manager.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/manager.cpp b/src/manager.cpp index c5fb42a..7c5aa61 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -55,8 +55,8 @@ Manager::~Manager() { } void Manager::StartServer() { - if(!db.Connect(conf.GetDbFile().c_str())) - throw std::runtime_error("Database could not be opened"); + //if(!db.Connect(conf.GetDbFile().c_str())) + // throw std::runtime_error("Database could not be opened"); music.GetList().LoadDir(conf.GetDir()); std::thread mplayer( [this] { music.PlayList(); } ); @@ -160,7 +160,7 @@ void Manager::ExecuteCommand(Command c) { music.GetList().LoadFile(s); } break; - case Command::SAVE_FILE: - break; + //case Command::SAVE_FILE: + // break; } } From 916cc72ef3ede945b6ae54aa5781670dd07d22da Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Tue, 31 May 2016 01:15:33 +0200 Subject: [PATCH 27/92] fix segmentation fault --- src/music.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/music.cpp b/src/music.cpp index d937e62..8d3e155 100644 --- a/src/music.cpp +++ b/src/music.cpp @@ -24,7 +24,9 @@ void Music::PlayList() { } if(IsStatus(Status::Backing)) { - s-=2; + if(s-1 > musicList.begin()) { + s -= 2; + } SetStatus(Status::Playing); } } From e74181461107daaac5a9b7e71bb8d4215e108141 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Tue, 31 May 2016 01:16:03 +0200 Subject: [PATCH 28/92] fix cmakelists --- CMakeLists.txt | 17 ++++++----------- 1 file changed, 6 insertions(+), 11 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index d1c7893..4fbbb83 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,8 +7,6 @@ add_executable(dplayer++ ${SRC_FILES}) target_compile_features(dplayer++ PUBLIC cxx_range_for cxx_auto_type cxx_lambdas cxx_aggregate_default_initializers) -set(CMAKE_CXX_FLAGS "-Wall -Wextra -pedantic") -set(CMAKE_EXE_LINKER_FLAGS "-lsfml-system -lsfml-audio -lmpg123 -ltag -lsqlite3" ) #Check if boost exists find_package(Boost 1.60.0 COMPONENTS filesystem program_options) @@ -29,24 +27,21 @@ endif() target_link_libraries(dplayer++ ${CMAKE_THREAD_LIBS_INIT}) +set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic") +set(CMAKE_EXE_LINKER_FLAGS "-lsfml-system -lsfml-audio -lmpg123 -ltag -lsqlite3" ) #RELEASE -set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS} -O3 -flto") +set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -flto") set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -flto") #DEBUG -set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS} -ggdb -Og -DDEBUG") +set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -ggdb -Og -DDEBUG") #THREAD SANITIZER -set(CMAKE_BUILD_TYPE thread) -set(CMAKE_CXX_FLAGS_THREAD "${CMAKE_CXX_FLAGS} -fsanitize=thread") +set(CMAKE_CXX_FLAGS_THREAD "${CMAKE_CXX_FLAGS_THREAD} -fsanitize=thread -DDEBUG -Og -ggdb") set(CMAKE_EXE_LINKER_FLAGS_THREAD "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=thread") #ADDRESS SANITIZER -set(CMAKE_BUILD_TYPE address) -set(CMAKE_CXX_FLAGS_THREAD "${CMAKE_CXX_FLAGS} -fsanitize=address") +set(CMAKE_CXX_FLAGS_ADDRESS "${CMAKE_CXX_FLAGS_ADDRESS} -fsanitize=address -DDEBUG -Og -ggdb") set(CMAKE_EXE_LINKER_FLAGS_THREAD "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address") - - - From 15536be83dceb6505d1b3d8165daae99d758b7a8 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Tue, 31 May 2016 22:48:13 +0200 Subject: [PATCH 29/92] create config directory --- src/config.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/config.cpp b/src/config.cpp index 6bf28c7..8afc478 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -7,6 +7,12 @@ using namespace boost::program_options; +Config::Config() { + path dir(MakeAbsolute(CONFIG_FOLDER)); + if(!exists(dir) && !create_directory(dir)) + throw std::runtime_error("Could not create config directory"); + +} void Config::Load() { #ifdef DEBUG From 821cee59b847948acbb46d5e0573391177344ceb Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Tue, 31 May 2016 22:48:37 +0200 Subject: [PATCH 30/92] change default values. --- include/config.h | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/include/config.h b/include/config.h index 489683c..7744c57 100644 --- a/include/config.h +++ b/include/config.h @@ -12,6 +12,7 @@ const std::string CONFIG_FOLDER = "~/.config/player++/"; class Config { public: + Config(); void Load(); std::string GetDaemonPipe() const; std::string GetClientPipe() const; @@ -24,13 +25,13 @@ class Config { std::string GetHome(); struct Options { //Pipe used by the daemon to write to client - std::string daemonpipe = "/tmp/dplayer++"; + std::string daemonpipe = CONFIG_FOLDER+"dplayer++"; //Pipe used by the client to write to daemon - std::string clientpipe = "/tmp/cplayer++"; + std::string clientpipe = CONFIG_FOLDER+"cplayer++"; //File to store the pid number so we can check if the daemon is really running - std::string pidfile = "/tmp/player++.pid"; + std::string pidfile = CONFIG_FOLDER+"player++.pid"; //Database file std::string dbfile = CONFIG_FOLDER+"db.sql"; From 8a87d7ecf8ebcb8fd554a45e60ae42a157714e84 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Wed, 1 Jun 2016 23:47:56 +0200 Subject: [PATCH 31/92] use command flag to switch daemonize --- src/main.cpp | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index 90ee874..2daa1b2 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,6 +5,8 @@ #include #include +using namespace std::string_literals; + //Copied from the net. void daemonize() { pid_t pid, sid; @@ -51,10 +53,11 @@ void daemonize() { exit(EXIT_FAILURE); } -int main() { - #ifndef DEBUG - daemonize(); - #endif +int main(int argc, char* argv[]) { + + if(argc == 2 && argv[1] == "-d"s) + daemonize(); + try { Manager manager; manager.StartServer(); From 11535618843150e00fe5ca5baa7c9dfcd3fe89aa Mon Sep 17 00:00:00 2001 From: David Date: Thu, 2 Jun 2016 00:32:10 +0200 Subject: [PATCH 32/92] Update README.md --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index dd06c0c..02e7c22 100644 --- a/README.md +++ b/README.md @@ -25,6 +25,7 @@ El programa al iniciar lee la configuración de ~/.config/player++/daemon.conf #### TODO +- usar libxdg para buscar el directorio por defecto donde buscar cancioens (parsear ~/.config/user-dirs.dirs si existe) - Playlists - Base de datos SQL - Soporte para plugins From 6726ae0516187be4142fb17aee1979746e868fd6 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Thu, 2 Jun 2016 00:49:08 +0200 Subject: [PATCH 33/92] print message --- src/main.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index 2daa1b2..facbb88 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -55,8 +55,11 @@ void daemonize() { int main(int argc, char* argv[]) { - if(argc == 2 && argv[1] == "-d"s) + if(argc == 2 && argv[1] == "-d"s) { daemonize(); + } else { + std::cout << "If you want to run it as a daemon restart it with \"-d\" flag" << std::endl; + } try { Manager manager; From 7b335e478c1f0aebc076acf94b2d2fdd8d988844 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Thu, 2 Jun 2016 00:49:36 +0200 Subject: [PATCH 34/92] autodetect if ~/Music exists --- src/config.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/src/config.cpp b/src/config.cpp index 8afc478..6a98c4a 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -19,6 +19,15 @@ void Config::Load() { std::cout << "Using config file " << MakeAbsolute(CONFIG_FOLDER+"daemon.conf") << std::endl; #endif + + //Try to autodetect music dir + //Here we should use libxdg to parse ~/.config/user-dirs.dirs (if exists) + //and get the default music dir. + path default_music(MakeAbsolute("~/Music/")); + if(exists(default_music)) + opt.dir = default_music.c_str(); + + std::ifstream config(MakeAbsolute(CONFIG_FOLDER+"daemon.conf")); if(!config.is_open()) { std::cerr << "Config file could not be open, using default values" << std::endl; From 27155d2a6d39fd707a7412f3c564424633f2258e Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Thu, 2 Jun 2016 11:45:51 +0200 Subject: [PATCH 35/92] add install command --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4fbbb83..01dadcc 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,6 +4,7 @@ project (cppplayer) include_directories(include) file(GLOB_RECURSE SRC_FILES src/*.cpp) add_executable(dplayer++ ${SRC_FILES}) +install(PROGRAMS build/dplayer++ DESTINATION /usr/local/bin) target_compile_features(dplayer++ PUBLIC cxx_range_for cxx_auto_type cxx_lambdas cxx_aggregate_default_initializers) From 3a1969d79e0fccbe0e7867829c362b39e32e3b1a Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Thu, 2 Jun 2016 20:41:33 +0200 Subject: [PATCH 36/92] . --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 01dadcc..d0942ef 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -6,7 +6,7 @@ file(GLOB_RECURSE SRC_FILES src/*.cpp) add_executable(dplayer++ ${SRC_FILES}) install(PROGRAMS build/dplayer++ DESTINATION /usr/local/bin) -target_compile_features(dplayer++ PUBLIC cxx_range_for cxx_auto_type cxx_lambdas cxx_aggregate_default_initializers) +target_compile_features(dplayer++ PUBLIC cxx_range_for cxx_auto_type cxx_lambdas) #Check if boost exists From cb0355e6a3b5761c5ec316976d8589cdf15f3ef1 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 2 Jun 2016 20:52:40 +0200 Subject: [PATCH 37/92] Update README.md --- README.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 02e7c22..5347305 100644 --- a/README.md +++ b/README.md @@ -9,7 +9,9 @@ El programa usa las librerías mpg123, sfml, TagLib boost-program-options y boos **# apt-get install libmpg123-dev libsfml-dev libboost-filesystem-dev libboost-program-options-dev libtag1-dev** Para compilarlo - mkdir -p build; cd build; cmake ..; make +> mkdir -p build; cd build; cmake ..; make + +Nota: En debian stable (jessie) no hay la versión necesaria de cmake, para arreglarlo se puede pasar a debian testing, que si tiene la versión necesaria. #### Configuración From 910999d2fac44969cb57fef5bef48eead937953c Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Thu, 2 Jun 2016 21:01:23 +0200 Subject: [PATCH 38/92] seems that some people don't have FindBoost.cmake by default --- CMakeLists.txt | 2 +- cmake/FindBoost.cmake | 1749 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 1750 insertions(+), 1 deletion(-) create mode 100644 cmake/FindBoost.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index d0942ef..e399523 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,7 +8,7 @@ install(PROGRAMS build/dplayer++ DESTINATION /usr/local/bin) target_compile_features(dplayer++ PUBLIC cxx_range_for cxx_auto_type cxx_lambdas) - +list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") #Check if boost exists find_package(Boost 1.60.0 COMPONENTS filesystem program_options) diff --git a/cmake/FindBoost.cmake b/cmake/FindBoost.cmake new file mode 100644 index 0000000..564513b --- /dev/null +++ b/cmake/FindBoost.cmake @@ -0,0 +1,1749 @@ +#.rst: +# FindBoost +# --------- +# +# Find Boost include dirs and libraries +# +# Use this module by invoking find_package with the form:: +# +# find_package(Boost +# [version] [EXACT] # Minimum or EXACT version e.g. 1.36.0 +# [REQUIRED] # Fail with error if Boost is not found +# [COMPONENTS ...] # Boost libraries by their canonical name +# ) # e.g. "date_time" for "libboost_date_time" +# +# This module finds headers and requested component libraries OR a CMake +# package configuration file provided by a "Boost CMake" build. For the +# latter case skip to the "Boost CMake" section below. For the former +# case results are reported in variables:: +# +# Boost_FOUND - True if headers and requested libraries were found +# Boost_INCLUDE_DIRS - Boost include directories +# Boost_LIBRARY_DIRS - Link directories for Boost libraries +# Boost_LIBRARIES - Boost component libraries to be linked +# Boost__FOUND - True if component was found ( is upper-case) +# Boost__LIBRARY - Libraries to link for component (may include +# target_link_libraries debug/optimized keywords) +# Boost_VERSION - BOOST_VERSION value from boost/version.hpp +# Boost_LIB_VERSION - Version string appended to library filenames +# Boost_MAJOR_VERSION - Boost major version number (X in X.y.z) +# Boost_MINOR_VERSION - Boost minor version number (Y in x.Y.z) +# Boost_SUBMINOR_VERSION - Boost subminor version number (Z in x.y.Z) +# Boost_LIB_DIAGNOSTIC_DEFINITIONS (Windows) +# - Pass to add_definitions() to have diagnostic +# information about Boost's automatic linking +# displayed during compilation +# +# This module reads hints about search locations from variables:: +# +# BOOST_ROOT - Preferred installation prefix +# (or BOOSTROOT) +# BOOST_INCLUDEDIR - Preferred include directory e.g. /include +# BOOST_LIBRARYDIR - Preferred library directory e.g. /lib +# Boost_NO_SYSTEM_PATHS - Set to ON to disable searching in locations not +# specified by these hint variables. Default is OFF. +# Boost_ADDITIONAL_VERSIONS +# - List of Boost versions not known to this module +# (Boost install locations may contain the version) +# +# and saves search results persistently in CMake cache entries:: +# +# Boost_INCLUDE_DIR - Directory containing Boost headers +# Boost_LIBRARY_DIR_RELEASE - Directory containing release Boost libraries +# Boost_LIBRARY_DIR_DEBUG - Directory containing debug Boost libraries +# Boost__LIBRARY_DEBUG - Component library debug variant +# Boost__LIBRARY_RELEASE - Component library release variant +# +# The following :prop_tgt:`IMPORTED` targets are also defined:: +# +# Boost::boost - Target for header-only dependencies +# (Boost include directory) +# Boost:: - Target for specific component dependency +# (shared or static library); is lower- +# case +# Boost::diagnostic_definitions - interface target to enable diagnostic +# information about Boost's automatic linking +# during compilation (adds BOOST_LIB_DIAGNOSTIC) +# Boost::disable_autolinking - interface target to disable automatic +# linking with MSVC (adds BOOST_ALL_NO_LIB) +# Boost::dynamic_linking - interface target to enable dynamic linking +# linking with MSVC (adds BOOST_ALL_DYN_LINK) +# +# Implicit dependencies such as Boost::filesystem requiring +# Boost::system will be automatically detected and satisfied, even +# if system is not specified when using find_package and if +# Boost::system is not added to target_link_libraries. If using +# Boost::thread, then Thread::Thread will also be added automatically. +# +# It is important to note that the imported targets behave differently +# than variables created by this module: multiple calls to +# find_package(Boost) in the same directory or sub-directories with +# different options (e.g. static or shared) will not override the +# values of the targets created by the first call. +# +# Users may set these hints or results as cache entries. Projects +# should not read these entries directly but instead use the above +# result variables. Note that some hint names start in upper-case +# "BOOST". One may specify these as environment variables if they are +# not specified as CMake variables or cache entries. +# +# This module first searches for the Boost header files using the above +# hint variables (excluding BOOST_LIBRARYDIR) and saves the result in +# Boost_INCLUDE_DIR. Then it searches for requested component libraries +# using the above hints (excluding BOOST_INCLUDEDIR and +# Boost_ADDITIONAL_VERSIONS), "lib" directories near Boost_INCLUDE_DIR, +# and the library name configuration settings below. It saves the +# library directories in Boost_LIBRARY_DIR_DEBUG and +# Boost_LIBRARY_DIR_RELEASE and individual library +# locations in Boost__LIBRARY_DEBUG and Boost__LIBRARY_RELEASE. +# When one changes settings used by previous searches in the same build +# tree (excluding environment variables) this module discards previous +# search results affected by the changes and searches again. +# +# Boost libraries come in many variants encoded in their file name. +# Users or projects may tell this module which variant to find by +# setting variables:: +# +# Boost_USE_MULTITHREADED - Set to OFF to use the non-multithreaded +# libraries ('mt' tag). Default is ON. +# Boost_USE_STATIC_LIBS - Set to ON to force the use of the static +# libraries. Default is OFF. +# Boost_USE_STATIC_RUNTIME - Set to ON or OFF to specify whether to use +# libraries linked statically to the C++ runtime +# ('s' tag). Default is platform dependent. +# Boost_USE_DEBUG_RUNTIME - Set to ON or OFF to specify whether to use +# libraries linked to the MS debug C++ runtime +# ('g' tag). Default is ON. +# Boost_USE_DEBUG_PYTHON - Set to ON to use libraries compiled with a +# debug Python build ('y' tag). Default is OFF. +# Boost_USE_STLPORT - Set to ON to use libraries compiled with +# STLPort ('p' tag). Default is OFF. +# Boost_USE_STLPORT_DEPRECATED_NATIVE_IOSTREAMS +# - Set to ON to use libraries compiled with +# STLPort deprecated "native iostreams" +# ('n' tag). Default is OFF. +# Boost_COMPILER - Set to the compiler-specific library suffix +# (e.g. "-gcc43"). Default is auto-computed +# for the C++ compiler in use. +# Boost_THREADAPI - Suffix for "thread" component library name, +# such as "pthread" or "win32". Names with +# and without this suffix will both be tried. +# Boost_NAMESPACE - Alternate namespace used to build boost with +# e.g. if set to "myboost", will search for +# myboost_thread instead of boost_thread. +# +# Other variables one may set to control this module are:: +# +# Boost_DEBUG - Set to ON to enable debug output from FindBoost. +# Please enable this before filing any bug report. +# Boost_DETAILED_FAILURE_MSG +# - Set to ON to add detailed information to the +# failure message even when the REQUIRED option +# is not given to the find_package call. +# Boost_REALPATH - Set to ON to resolve symlinks for discovered +# libraries to assist with packaging. For example, +# the "system" component library may be resolved to +# "/usr/lib/libboost_system.so.1.42.0" instead of +# "/usr/lib/libboost_system.so". This does not +# affect linking and should not be enabled unless +# the user needs this information. +# Boost_LIBRARY_DIR - Default value for Boost_LIBRARY_DIR_RELEASE and +# Boost_LIBRARY_DIR_DEBUG. +# +# On Visual Studio and Borland compilers Boost headers request automatic +# linking to corresponding libraries. This requires matching libraries +# to be linked explicitly or available in the link library search path. +# In this case setting Boost_USE_STATIC_LIBS to OFF may not achieve +# dynamic linking. Boost automatic linking typically requests static +# libraries with a few exceptions (such as Boost.Python). Use:: +# +# add_definitions(${Boost_LIB_DIAGNOSTIC_DEFINITIONS}) +# +# to ask Boost to report information about automatic linking requests. +# +# Example to find Boost headers only:: +# +# find_package(Boost 1.36.0) +# if(Boost_FOUND) +# include_directories(${Boost_INCLUDE_DIRS}) +# add_executable(foo foo.cc) +# endif() +# +# Example to find Boost libraries and use imported targets:: +# +# find_package(Boost 1.56 REQUIRED COMPONENTS +# date_time filesystem iostreams) +# add_executable(foo foo.cc) +# target_link_libraries(foo Boost::date_time Boost::filesystem +# Boost::iostreams) +# +# Example to find Boost headers and some *static* libraries:: +# +# set(Boost_USE_STATIC_LIBS ON) # only find static libs +# set(Boost_USE_MULTITHREADED ON) +# set(Boost_USE_STATIC_RUNTIME OFF) +# find_package(Boost 1.36.0 COMPONENTS date_time filesystem system ...) +# if(Boost_FOUND) +# include_directories(${Boost_INCLUDE_DIRS}) +# add_executable(foo foo.cc) +# target_link_libraries(foo ${Boost_LIBRARIES}) +# endif() +# +# Boost CMake +# ^^^^^^^^^^^ +# +# If Boost was built using the boost-cmake project it provides a package +# configuration file for use with find_package's Config mode. This +# module looks for the package configuration file called +# BoostConfig.cmake or boost-config.cmake and stores the result in cache +# entry "Boost_DIR". If found, the package configuration file is loaded +# and this module returns with no further action. See documentation of +# the Boost CMake package configuration for details on what it provides. +# +# Set Boost_NO_BOOST_CMAKE to ON to disable the search for boost-cmake. + +#============================================================================= +# Copyright 2006-2012 Kitware, Inc. +# Copyright 2006-2008 Andreas Schneider +# Copyright 2007 Wengo +# Copyright 2007 Mike Jackson +# Copyright 2008 Andreas Pakulat +# Copyright 2008-2012 Philip Lowman +# +# Distributed under the OSI-approved BSD License (the "License"); +# see accompanying file Copyright.txt for details. +# +# This software is distributed WITHOUT ANY WARRANTY; without even the +# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# See the License for more information. +#============================================================================= +# (To distribute this file outside of CMake, substitute the full +# License text for the above reference.) + + +#------------------------------------------------------------------------------- +# Before we go searching, check whether boost-cmake is available, unless the +# user specifically asked NOT to search for boost-cmake. +# +# If Boost_DIR is set, this behaves as any find_package call would. If not, +# it looks at BOOST_ROOT and BOOSTROOT to find Boost. +# +if (NOT Boost_NO_BOOST_CMAKE) + # If Boost_DIR is not set, look for BOOSTROOT and BOOST_ROOT as alternatives, + # since these are more conventional for Boost. + if ("$ENV{Boost_DIR}" STREQUAL "") + if (NOT "$ENV{BOOST_ROOT}" STREQUAL "") + set(ENV{Boost_DIR} $ENV{BOOST_ROOT}) + elseif (NOT "$ENV{BOOSTROOT}" STREQUAL "") + set(ENV{Boost_DIR} $ENV{BOOSTROOT}) + endif() + endif() + + # Do the same find_package call but look specifically for the CMake version. + # Note that args are passed in the Boost_FIND_xxxxx variables, so there is no + # need to delegate them to this find_package call. + find_package(Boost QUIET NO_MODULE) + mark_as_advanced(Boost_DIR) + + # If we found boost-cmake, then we're done. Print out what we found. + # Otherwise let the rest of the module try to find it. + if (Boost_FOUND) + message("Boost ${Boost_FIND_VERSION} found.") + if (Boost_FIND_COMPONENTS) + message("Found Boost components:") + message(" ${Boost_FIND_COMPONENTS}") + endif() + return() + endif() +endif() + + +#------------------------------------------------------------------------------- +# FindBoost functions & macros +# + +############################################ +# +# Check the existence of the libraries. +# +############################################ +# This macro was taken directly from the FindQt4.cmake file that is included +# with the CMake distribution. This is NOT my work. All work was done by the +# original authors of the FindQt4.cmake file. Only minor modifications were +# made to remove references to Qt and make this file more generally applicable +# And ELSE/ENDIF pairs were removed for readability. +######################################################################### + +macro(_Boost_ADJUST_LIB_VARS basename) + if(Boost_INCLUDE_DIR ) + if(Boost_${basename}_LIBRARY_DEBUG AND Boost_${basename}_LIBRARY_RELEASE) + # if the generator supports configuration types then set + # optimized and debug libraries, or if the CMAKE_BUILD_TYPE has a value + if(CMAKE_CONFIGURATION_TYPES OR CMAKE_BUILD_TYPE) + set(Boost_${basename}_LIBRARY optimized ${Boost_${basename}_LIBRARY_RELEASE} debug ${Boost_${basename}_LIBRARY_DEBUG}) + else() + # if there are no configuration types and CMAKE_BUILD_TYPE has no value + # then just use the release libraries + set(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY_RELEASE} ) + endif() + # FIXME: This probably should be set for both cases + set(Boost_${basename}_LIBRARIES optimized ${Boost_${basename}_LIBRARY_RELEASE} debug ${Boost_${basename}_LIBRARY_DEBUG}) + endif() + + # if only the release version was found, set the debug variable also to the release version + if(Boost_${basename}_LIBRARY_RELEASE AND NOT Boost_${basename}_LIBRARY_DEBUG) + set(Boost_${basename}_LIBRARY_DEBUG ${Boost_${basename}_LIBRARY_RELEASE}) + set(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY_RELEASE}) + set(Boost_${basename}_LIBRARIES ${Boost_${basename}_LIBRARY_RELEASE}) + endif() + + # if only the debug version was found, set the release variable also to the debug version + if(Boost_${basename}_LIBRARY_DEBUG AND NOT Boost_${basename}_LIBRARY_RELEASE) + set(Boost_${basename}_LIBRARY_RELEASE ${Boost_${basename}_LIBRARY_DEBUG}) + set(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY_DEBUG}) + set(Boost_${basename}_LIBRARIES ${Boost_${basename}_LIBRARY_DEBUG}) + endif() + + # If the debug & release library ends up being the same, omit the keywords + if(${Boost_${basename}_LIBRARY_RELEASE} STREQUAL ${Boost_${basename}_LIBRARY_DEBUG}) + set(Boost_${basename}_LIBRARY ${Boost_${basename}_LIBRARY_RELEASE} ) + set(Boost_${basename}_LIBRARIES ${Boost_${basename}_LIBRARY_RELEASE} ) + endif() + + if(Boost_${basename}_LIBRARY) + set(Boost_${basename}_FOUND ON) + endif() + + endif() + # Make variables changeable to the advanced user + mark_as_advanced( + Boost_${basename}_LIBRARY_RELEASE + Boost_${basename}_LIBRARY_DEBUG + ) +endmacro() + +# Detect changes in used variables. +# Compares the current variable value with the last one. +# In short form: +# v != v_LAST -> CHANGED = 1 +# v is defined, v_LAST not -> CHANGED = 1 +# v is not defined, but v_LAST is -> CHANGED = 1 +# otherwise -> CHANGED = 0 +# CHANGED is returned in variable named ${changed_var} +macro(_Boost_CHANGE_DETECT changed_var) + set(${changed_var} 0) + foreach(v ${ARGN}) + if(DEFINED _Boost_COMPONENTS_SEARCHED) + if(${v}) + if(_${v}_LAST) + string(COMPARE NOTEQUAL "${${v}}" "${_${v}_LAST}" _${v}_CHANGED) + else() + set(_${v}_CHANGED 1) + endif() + elseif(_${v}_LAST) + set(_${v}_CHANGED 1) + endif() + if(_${v}_CHANGED) + set(${changed_var} 1) + endif() + else() + set(_${v}_CHANGED 0) + endif() + endforeach() +endmacro() + +# +# Find the given library (var). +# Use 'build_type' to support different lib paths for RELEASE or DEBUG builds +# +macro(_Boost_FIND_LIBRARY var build_type) + + find_library(${var} ${ARGN}) + + if(${var}) + # If this is the first library found then save Boost_LIBRARY_DIR_[RELEASE,DEBUG]. + if(NOT Boost_LIBRARY_DIR_${build_type}) + get_filename_component(_dir "${${var}}" PATH) + set(Boost_LIBRARY_DIR_${build_type} "${_dir}" CACHE PATH "Boost library directory ${build_type}" FORCE) + endif() + elseif(_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT) + # Try component-specific hints but do not save Boost_LIBRARY_DIR_[RELEASE,DEBUG]. + find_library(${var} HINTS ${_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT} ${ARGN}) + endif() + + # If Boost_LIBRARY_DIR_[RELEASE,DEBUG] is known then search only there. + if(Boost_LIBRARY_DIR_${build_type}) + set(_boost_LIBRARY_SEARCH_DIRS_${build_type} ${Boost_LIBRARY_DIR_${build_type}} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) + if(Boost_DEBUG) + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + " Boost_LIBRARY_DIR_${build_type} = ${Boost_LIBRARY_DIR_${build_type}}" + " _boost_LIBRARY_SEARCH_DIRS_${build_type} = ${_boost_LIBRARY_SEARCH_DIRS_${build_type}}") + endif() + endif() +endmacro() + +#------------------------------------------------------------------------------- + +# +# Runs compiler with "-dumpversion" and parses major/minor +# version with a regex. +# +function(_Boost_COMPILER_DUMPVERSION _OUTPUT_VERSION) + + exec_program(${CMAKE_CXX_COMPILER} + ARGS ${CMAKE_CXX_COMPILER_ARG1} -dumpversion + OUTPUT_VARIABLE _boost_COMPILER_VERSION + ) + string(REGEX REPLACE "([0-9])\\.([0-9])(\\.[0-9])?" "\\1\\2" + _boost_COMPILER_VERSION ${_boost_COMPILER_VERSION}) + + set(${_OUTPUT_VERSION} ${_boost_COMPILER_VERSION} PARENT_SCOPE) +endfunction() + +# +# Take a list of libraries with "thread" in it +# and prepend duplicates with "thread_${Boost_THREADAPI}" +# at the front of the list +# +function(_Boost_PREPEND_LIST_WITH_THREADAPI _output) + set(_orig_libnames ${ARGN}) + string(REPLACE "thread" "thread_${Boost_THREADAPI}" _threadapi_libnames "${_orig_libnames}") + set(${_output} ${_threadapi_libnames} ${_orig_libnames} PARENT_SCOPE) +endfunction() + +# +# If a library is found, replace its cache entry with its REALPATH +# +function(_Boost_SWAP_WITH_REALPATH _library _docstring) + if(${_library}) + get_filename_component(_boost_filepathreal ${${_library}} REALPATH) + unset(${_library} CACHE) + set(${_library} ${_boost_filepathreal} CACHE FILEPATH "${_docstring}") + endif() +endfunction() + +function(_Boost_CHECK_SPELLING _var) + if(${_var}) + string(TOUPPER ${_var} _var_UC) + message(FATAL_ERROR "ERROR: ${_var} is not the correct spelling. The proper spelling is ${_var_UC}.") + endif() +endfunction() + +# Guesses Boost's compiler prefix used in built library names +# Returns the guess by setting the variable pointed to by _ret +function(_Boost_GUESS_COMPILER_PREFIX _ret) + if(CMAKE_CXX_COMPILER_ID STREQUAL "Intel" + OR CMAKE_CXX_COMPILER MATCHES "icl" + OR CMAKE_CXX_COMPILER MATCHES "icpc") + if(WIN32) + set (_boost_COMPILER "-iw") + else() + set (_boost_COMPILER "-il") + endif() + elseif (GHSMULTI) + set(_boost_COMPILER "-ghs") + elseif (MSVC14) + set(_boost_COMPILER "-vc140") + elseif (MSVC12) + set(_boost_COMPILER "-vc120") + elseif (MSVC11) + set(_boost_COMPILER "-vc110") + elseif (MSVC10) + set(_boost_COMPILER "-vc100") + elseif (MSVC90) + set(_boost_COMPILER "-vc90") + elseif (MSVC80) + set(_boost_COMPILER "-vc80") + elseif (MSVC71) + set(_boost_COMPILER "-vc71") + elseif (MSVC70) # Good luck! + set(_boost_COMPILER "-vc7") # yes, this is correct + elseif (MSVC60) # Good luck! + set(_boost_COMPILER "-vc6") # yes, this is correct + elseif (BORLAND) + set(_boost_COMPILER "-bcb") + elseif(CMAKE_CXX_COMPILER_ID STREQUAL "SunPro") + set(_boost_COMPILER "-sw") + elseif (MINGW) + if(${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION} VERSION_LESS 1.34) + set(_boost_COMPILER "-mgw") # no GCC version encoding prior to 1.34 + else() + _Boost_COMPILER_DUMPVERSION(_boost_COMPILER_VERSION) + set(_boost_COMPILER "-mgw${_boost_COMPILER_VERSION}") + endif() + elseif (UNIX) + if (CMAKE_COMPILER_IS_GNUCXX) + if(${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION} VERSION_LESS 1.34) + set(_boost_COMPILER "-gcc") # no GCC version encoding prior to 1.34 + else() + _Boost_COMPILER_DUMPVERSION(_boost_COMPILER_VERSION) + # Determine which version of GCC we have. + if(APPLE) + if(Boost_MINOR_VERSION) + if(${Boost_MINOR_VERSION} GREATER 35) + # In Boost 1.36.0 and newer, the mangled compiler name used + # on Mac OS X/Darwin is "xgcc". + set(_boost_COMPILER "-xgcc${_boost_COMPILER_VERSION}") + else() + # In Boost <= 1.35.0, there is no mangled compiler name for + # the Mac OS X/Darwin version of GCC. + set(_boost_COMPILER "") + endif() + else() + # We don't know the Boost version, so assume it's + # pre-1.36.0. + set(_boost_COMPILER "") + endif() + else() + set(_boost_COMPILER "-gcc${_boost_COMPILER_VERSION}") + endif() + endif() + endif () + else() + # TODO at least Boost_DEBUG here? + set(_boost_COMPILER "") + endif() + set(${_ret} ${_boost_COMPILER} PARENT_SCOPE) +endfunction() + +# +# Get component dependencies. Requires the dependencies to have been +# defined for the Boost release version. +# +# component - the component to check +# _ret - list of library dependencies +# +function(_Boost_COMPONENT_DEPENDENCIES component _ret) + # Note: to add a new Boost release, run + # + # % cmake -DBOOST_DIR=/path/to/boost/source -P Utilities/Scripts/BoostScanDeps.cmake + # + # The output may be added in a new block below. If it's the same as + # the previous release, simply update the version range of the block + # for the previous release. + # + # This information was originally generated by running + # BoostScanDeps.cmake against every boost release to date supported + # by FindBoost: + # + # % for version in /path/to/boost/sources/* + # do + # cmake -DBOOST_DIR=$version -P Utilities/Scripts/BoostScanDeps.cmake + # done + # + # The output was then updated by search and replace with these regexes: + # + # - Strip message(STATUS) prefix dashes + # s;^-- ;; + # - Indent + # s;^set(; set(;; + # - Add conditionals + # s;Scanning /path/to/boost/sources/boost_\(.*\)_\(.*\)_\(.*); elseif(NOT Boost_VERSION VERSION_LESS \10\20\3 AND Boost_VERSION VERSION_LESS xxxx); + # + # This results in the logic seen below, but will require the xxxx + # replacing with the following Boost release version (or the next + # minor version to be released, e.g. 1.59 was the latest at the time + # of writing, making 1.60 the next, so 106000 is the needed version + # number). Identical consecutive releases were then merged together + # by updating the end range of the first block and removing the + # following redundant blocks. + # + # Running the script against all historical releases should be + # required only if the BoostScanDeps.cmake script logic is changed. + # The addition of a new release should only require it to be run + # against the new release. + set(_Boost_IMPORTED_TARGETS TRUE) + if(NOT Boost_VERSION VERSION_LESS 103300 AND Boost_VERSION VERSION_LESS 103500) + set(_Boost_IOSTREAMS_DEPENDENCIES regex thread) + set(_Boost_REGEX_DEPENDENCIES thread) + set(_Boost_WAVE_DEPENDENCIES filesystem thread) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(NOT Boost_VERSION VERSION_LESS 103500 AND Boost_VERSION VERSION_LESS 103600) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_WAVE_DEPENDENCIES filesystem system thread) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(NOT Boost_VERSION VERSION_LESS 103600 AND Boost_VERSION VERSION_LESS 103800) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_WAVE_DEPENDENCIES filesystem system thread) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(NOT Boost_VERSION VERSION_LESS 103800 AND Boost_VERSION VERSION_LESS 104300) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_THREAD_DEPENDENCIES date_time) + set(_Boost_WAVE_DEPENDENCIES filesystem system thread date_time) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(NOT Boost_VERSION VERSION_LESS 104300 AND Boost_VERSION VERSION_LESS 104400) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_THREAD_DEPENDENCIES date_time) + set(_Boost_WAVE_DEPENDENCIES filesystem system thread date_time) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(NOT Boost_VERSION VERSION_LESS 104400 AND Boost_VERSION VERSION_LESS 104500) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random serialization) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_THREAD_DEPENDENCIES date_time) + set(_Boost_WAVE_DEPENDENCIES serialization filesystem system thread date_time) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(NOT Boost_VERSION VERSION_LESS 104500 AND Boost_VERSION VERSION_LESS 104700) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_THREAD_DEPENDENCIES date_time) + set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread date_time) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(NOT Boost_VERSION VERSION_LESS 104700 AND Boost_VERSION VERSION_LESS 104800) + set(_Boost_CHRONO_DEPENDENCIES system) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_THREAD_DEPENDENCIES date_time) + set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread date_time) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(NOT Boost_VERSION VERSION_LESS 104800 AND Boost_VERSION VERSION_LESS 105000) + set(_Boost_CHRONO_DEPENDENCIES system) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l random) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_THREAD_DEPENDENCIES date_time) + set(_Boost_TIMER_DEPENDENCIES chrono system) + set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread date_time) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(NOT Boost_VERSION VERSION_LESS 105000 AND Boost_VERSION VERSION_LESS 105300) + set(_Boost_CHRONO_DEPENDENCIES system) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l regex random) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_THREAD_DEPENDENCIES chrono system date_time) + set(_Boost_TIMER_DEPENDENCIES chrono system) + set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(NOT Boost_VERSION VERSION_LESS 105300 AND Boost_VERSION VERSION_LESS 105400) + set(_Boost_ATOMIC_DEPENDENCIES thread chrono system date_time) + set(_Boost_CHRONO_DEPENDENCIES system) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l regex random) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) + set(_Boost_TIMER_DEPENDENCIES chrono system) + set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(NOT Boost_VERSION VERSION_LESS 105400 AND Boost_VERSION VERSION_LESS 105500) + set(_Boost_ATOMIC_DEPENDENCIES thread chrono system date_time) + set(_Boost_CHRONO_DEPENDENCIES system) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_LOG_DEPENDENCIES log_setup date_time system filesystem thread regex chrono) + set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l regex random) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) + set(_Boost_TIMER_DEPENDENCIES chrono system) + set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(NOT Boost_VERSION VERSION_LESS 105500 AND Boost_VERSION VERSION_LESS 105600) + set(_Boost_CHRONO_DEPENDENCIES system) + set(_Boost_COROUTINE_DEPENDENCIES context system) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_LOG_DEPENDENCIES log_setup date_time system filesystem thread regex chrono) + set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l regex random) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) + set(_Boost_TIMER_DEPENDENCIES chrono system) + set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(NOT Boost_VERSION VERSION_LESS 105600 AND Boost_VERSION VERSION_LESS 105900) + set(_Boost_CHRONO_DEPENDENCIES system) + set(_Boost_COROUTINE_DEPENDENCIES context system) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_LOG_DEPENDENCIES log_setup date_time system filesystem thread regex chrono) + set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_RANDOM_DEPENDENCIES system) + set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) + set(_Boost_TIMER_DEPENDENCIES chrono system) + set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(NOT Boost_VERSION VERSION_LESS 105900 AND Boost_VERSION VERSION_LESS 106000) + set(_Boost_CHRONO_DEPENDENCIES system) + set(_Boost_COROUTINE_DEPENDENCIES context system) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_LOG_DEPENDENCIES log_setup date_time system filesystem thread regex chrono atomic) + set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_RANDOM_DEPENDENCIES system) + set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) + set(_Boost_TIMER_DEPENDENCIES chrono system) + set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + elseif(NOT Boost_VERSION VERSION_LESS 106000 AND Boost_VERSION VERSION_LESS 106200) + set(_Boost_CHRONO_DEPENDENCIES system) + set(_Boost_COROUTINE_DEPENDENCIES context system) + set(_Boost_FILESYSTEM_DEPENDENCIES system) + set(_Boost_IOSTREAMS_DEPENDENCIES regex) + set(_Boost_LOG_DEPENDENCIES date_time log_setup system filesystem thread regex chrono atomic) + set(_Boost_MATH_DEPENDENCIES math_c99 math_c99f math_c99l math_tr1 math_tr1f math_tr1l atomic) + set(_Boost_MPI_DEPENDENCIES serialization) + set(_Boost_MPI_PYTHON_DEPENDENCIES python mpi serialization) + set(_Boost_RANDOM_DEPENDENCIES system) + set(_Boost_THREAD_DEPENDENCIES chrono system date_time atomic) + set(_Boost_TIMER_DEPENDENCIES chrono system) + set(_Boost_WAVE_DEPENDENCIES filesystem system serialization thread chrono date_time atomic) + set(_Boost_WSERIALIZATION_DEPENDENCIES serialization) + else() + message(WARNING "Imported targets not available for Boost version ${Boost_VERSION}") + set(_Boost_IMPORTED_TARGETS FALSE) + endif() + + string(TOUPPER ${component} uppercomponent) + set(${_ret} ${_Boost_${uppercomponent}_DEPENDENCIES} PARENT_SCOPE) + set(_Boost_IMPORTED_TARGETS ${_Boost_IMPORTED_TARGETS} PARENT_SCOPE) + + string(REGEX REPLACE ";" " " _boost_DEPS_STRING "${_Boost_${uppercomponent}_DEPENDENCIES}") + if (NOT _boost_DEPS_STRING) + set(_boost_DEPS_STRING "(none)") + endif() + # message(STATUS "Dependencies for Boost::${component}: ${_boost_DEPS_STRING}") +endfunction() + +# +# Determine if any missing dependencies require adding to the component list. +# +# Sets _Boost_${COMPONENT}_DEPENDENCIES for each required component, +# plus _Boost_IMPORTED_TARGETS (TRUE if imported targets should be +# defined; FALSE if dependency information is unavailable). +# +# componentvar - the component list variable name +# extravar - the indirect dependency list variable name +# +# +function(_Boost_MISSING_DEPENDENCIES componentvar extravar) + # _boost_unprocessed_components - list of components requiring processing + # _boost_processed_components - components already processed (or currently being processed) + # _boost_new_components - new components discovered for future processing + # + list(APPEND _boost_unprocessed_components ${${componentvar}}) + + while(_boost_unprocessed_components) + list(APPEND _boost_processed_components ${_boost_unprocessed_components}) + foreach(component ${_boost_unprocessed_components}) + string(TOUPPER ${component} uppercomponent) + set(${_ret} ${_Boost_${uppercomponent}_DEPENDENCIES} PARENT_SCOPE) + _Boost_COMPONENT_DEPENDENCIES("${component}" _Boost_${uppercomponent}_DEPENDENCIES) + set(_Boost_${uppercomponent}_DEPENDENCIES ${_Boost_${uppercomponent}_DEPENDENCIES} PARENT_SCOPE) + set(_Boost_IMPORTED_TARGETS ${_Boost_IMPORTED_TARGETS} PARENT_SCOPE) + foreach(componentdep ${_Boost_${uppercomponent}_DEPENDENCIES}) + list(FIND _boost_processed_components "${componentdep}" _boost_component_found) + list(FIND _boost_new_components "${componentdep}" _boost_component_new) + if (_boost_component_found EQUAL -1 AND _boost_component_new EQUAL -1) + list(APPEND _boost_new_components ${componentdep}) + endif() + endforeach() + endforeach() + set(_boost_unprocessed_components ${_boost_new_components}) + unset(_boost_new_components) + endwhile() + set(_boost_extra_components ${_boost_processed_components}) + if(_boost_extra_components AND ${componentvar}) + list(REMOVE_ITEM _boost_extra_components ${${componentvar}}) + endif() + set(${componentvar} ${_boost_processed_components} PARENT_SCOPE) + set(${extravar} ${_boost_extra_components} PARENT_SCOPE) +endfunction() + +# +# End functions/macros +# +#------------------------------------------------------------------------------- + +#------------------------------------------------------------------------------- +# main. +#------------------------------------------------------------------------------- + + +# If the user sets Boost_LIBRARY_DIR, use it as the default for both +# configurations. +if(NOT Boost_LIBRARY_DIR_RELEASE AND Boost_LIBRARY_DIR) + set(Boost_LIBRARY_DIR_RELEASE "${Boost_LIBRARY_DIR}") +endif() +if(NOT Boost_LIBRARY_DIR_DEBUG AND Boost_LIBRARY_DIR) + set(Boost_LIBRARY_DIR_DEBUG "${Boost_LIBRARY_DIR}") +endif() + +if(NOT DEFINED Boost_USE_MULTITHREADED) + set(Boost_USE_MULTITHREADED TRUE) +endif() +if(NOT DEFINED Boost_USE_DEBUG_RUNTIME) + set(Boost_USE_DEBUG_RUNTIME TRUE) +endif() + +# Check the version of Boost against the requested version. +if(Boost_FIND_VERSION AND NOT Boost_FIND_VERSION_MINOR) + message(SEND_ERROR "When requesting a specific version of Boost, you must provide at least the major and minor version numbers, e.g., 1.34") +endif() + +if(Boost_FIND_VERSION_EXACT) + # The version may appear in a directory with or without the patch + # level, even when the patch level is non-zero. + set(_boost_TEST_VERSIONS + "${Boost_FIND_VERSION_MAJOR}.${Boost_FIND_VERSION_MINOR}.${Boost_FIND_VERSION_PATCH}" + "${Boost_FIND_VERSION_MAJOR}.${Boost_FIND_VERSION_MINOR}") +else() + # The user has not requested an exact version. Among known + # versions, find those that are acceptable to the user request. + # + # Note: When adding a new Boost release, also update the dependency + # information in _Boost_COMPONENT_DEPENDENCIES. See the + # instructions at the top of _Boost_COMPONENT_DEPENDENCIES. + set(_Boost_KNOWN_VERSIONS ${Boost_ADDITIONAL_VERSIONS} + "1.61.0" "1.61" "1.60.0" "1.60" + "1.59.0" "1.59" "1.58.0" "1.58" "1.57.0" "1.57" "1.56.0" "1.56" "1.55.0" "1.55" + "1.54.0" "1.54" "1.53.0" "1.53" "1.52.0" "1.52" "1.51.0" "1.51" + "1.50.0" "1.50" "1.49.0" "1.49" "1.48.0" "1.48" "1.47.0" "1.47" "1.46.1" + "1.46.0" "1.46" "1.45.0" "1.45" "1.44.0" "1.44" "1.43.0" "1.43" "1.42.0" "1.42" + "1.41.0" "1.41" "1.40.0" "1.40" "1.39.0" "1.39" "1.38.0" "1.38" "1.37.0" "1.37" + "1.36.1" "1.36.0" "1.36" "1.35.1" "1.35.0" "1.35" "1.34.1" "1.34.0" + "1.34" "1.33.1" "1.33.0" "1.33") + + set(_boost_TEST_VERSIONS) + if(Boost_FIND_VERSION) + set(_Boost_FIND_VERSION_SHORT "${Boost_FIND_VERSION_MAJOR}.${Boost_FIND_VERSION_MINOR}") + # Select acceptable versions. + foreach(version ${_Boost_KNOWN_VERSIONS}) + if(NOT "${version}" VERSION_LESS "${Boost_FIND_VERSION}") + # This version is high enough. + list(APPEND _boost_TEST_VERSIONS "${version}") + elseif("${version}.99" VERSION_EQUAL "${_Boost_FIND_VERSION_SHORT}.99") + # This version is a short-form for the requested version with + # the patch level dropped. + list(APPEND _boost_TEST_VERSIONS "${version}") + endif() + endforeach() + else() + # Any version is acceptable. + set(_boost_TEST_VERSIONS "${_Boost_KNOWN_VERSIONS}") + endif() +endif() + +# The reason that we failed to find Boost. This will be set to a +# user-friendly message when we fail to find some necessary piece of +# Boost. +set(Boost_ERROR_REASON) + +if(Boost_DEBUG) + # Output some of their choices + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + "_boost_TEST_VERSIONS = ${_boost_TEST_VERSIONS}") + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + "Boost_USE_MULTITHREADED = ${Boost_USE_MULTITHREADED}") + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + "Boost_USE_STATIC_LIBS = ${Boost_USE_STATIC_LIBS}") + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + "Boost_USE_STATIC_RUNTIME = ${Boost_USE_STATIC_RUNTIME}") + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + "Boost_ADDITIONAL_VERSIONS = ${Boost_ADDITIONAL_VERSIONS}") + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + "Boost_NO_SYSTEM_PATHS = ${Boost_NO_SYSTEM_PATHS}") +endif() + +# Supply Boost_LIB_DIAGNOSTIC_DEFINITIONS as a convenience target. It +# will only contain any interface definitions on WIN32, but is created +# on all platforms to keep end user code free from platform dependent +# code. Also provide convenience targets to disable autolinking and +# enable dynamic linking. +if(NOT TARGET Boost::diagnostic_definitions) + add_library(Boost::diagnostic_definitions INTERFACE IMPORTED) + add_library(Boost::disable_autolinking INTERFACE IMPORTED) + add_library(Boost::dynamic_linking INTERFACE IMPORTED) +endif() +if(WIN32) + # In windows, automatic linking is performed, so you do not have + # to specify the libraries. If you are linking to a dynamic + # runtime, then you can choose to link to either a static or a + # dynamic Boost library, the default is to do a static link. You + # can alter this for a specific library "whatever" by defining + # BOOST_WHATEVER_DYN_LINK to force Boost library "whatever" to be + # linked dynamically. Alternatively you can force all Boost + # libraries to dynamic link by defining BOOST_ALL_DYN_LINK. + + # This feature can be disabled for Boost library "whatever" by + # defining BOOST_WHATEVER_NO_LIB, or for all of Boost by defining + # BOOST_ALL_NO_LIB. + + # If you want to observe which libraries are being linked against + # then defining BOOST_LIB_DIAGNOSTIC will cause the auto-linking + # code to emit a #pragma message each time a library is selected + # for linking. + set(Boost_LIB_DIAGNOSTIC_DEFINITIONS "-DBOOST_LIB_DIAGNOSTIC") + set_target_properties(Boost::diagnostic_definitions PROPERTIES + INTERFACE_COMPILE_DEFINITIONS "BOOST_LIB_DIAGNOSTIC") + set_target_properties(Boost::disable_autolinking PROPERTIES + INTERFACE_COMPILE_DEFINITIONS "BOOST_ALL_NO_LIB") + set_target_properties(Boost::dynamic_linking PROPERTIES + INTERFACE_COMPILE_DEFINITIONS "BOOST_ALL_DYN_LINK") +endif() + +_Boost_CHECK_SPELLING(Boost_ROOT) +_Boost_CHECK_SPELLING(Boost_LIBRARYDIR) +_Boost_CHECK_SPELLING(Boost_INCLUDEDIR) + +# Collect environment variable inputs as hints. Do not consider changes. +foreach(v BOOSTROOT BOOST_ROOT BOOST_INCLUDEDIR BOOST_LIBRARYDIR) + set(_env $ENV{${v}}) + if(_env) + file(TO_CMAKE_PATH "${_env}" _ENV_${v}) + else() + set(_ENV_${v} "") + endif() +endforeach() +if(NOT _ENV_BOOST_ROOT AND _ENV_BOOSTROOT) + set(_ENV_BOOST_ROOT "${_ENV_BOOSTROOT}") +endif() + +# Collect inputs and cached results. Detect changes since the last run. +if(NOT BOOST_ROOT AND BOOSTROOT) + set(BOOST_ROOT "${BOOSTROOT}") +endif() +set(_Boost_VARS_DIR + BOOST_ROOT + Boost_NO_SYSTEM_PATHS + ) + +if(Boost_DEBUG) + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + "Declared as CMake or Environmental Variables:") + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + " BOOST_ROOT = ${BOOST_ROOT}") + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + " BOOST_INCLUDEDIR = ${BOOST_INCLUDEDIR}") + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + " BOOST_LIBRARYDIR = ${BOOST_LIBRARYDIR}") + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + "_boost_TEST_VERSIONS = ${_boost_TEST_VERSIONS}") +endif() + +# ------------------------------------------------------------------------ +# Search for Boost include DIR +# ------------------------------------------------------------------------ + +set(_Boost_VARS_INC BOOST_INCLUDEDIR Boost_INCLUDE_DIR Boost_ADDITIONAL_VERSIONS) +_Boost_CHANGE_DETECT(_Boost_CHANGE_INCDIR ${_Boost_VARS_DIR} ${_Boost_VARS_INC}) +# Clear Boost_INCLUDE_DIR if it did not change but other input affecting the +# location did. We will find a new one based on the new inputs. +if(_Boost_CHANGE_INCDIR AND NOT _Boost_INCLUDE_DIR_CHANGED) + unset(Boost_INCLUDE_DIR CACHE) +endif() + +if(NOT Boost_INCLUDE_DIR) + set(_boost_INCLUDE_SEARCH_DIRS "") + if(BOOST_INCLUDEDIR) + list(APPEND _boost_INCLUDE_SEARCH_DIRS ${BOOST_INCLUDEDIR}) + elseif(_ENV_BOOST_INCLUDEDIR) + list(APPEND _boost_INCLUDE_SEARCH_DIRS ${_ENV_BOOST_INCLUDEDIR}) + endif() + + if( BOOST_ROOT ) + list(APPEND _boost_INCLUDE_SEARCH_DIRS ${BOOST_ROOT}/include ${BOOST_ROOT}) + elseif( _ENV_BOOST_ROOT ) + list(APPEND _boost_INCLUDE_SEARCH_DIRS ${_ENV_BOOST_ROOT}/include ${_ENV_BOOST_ROOT}) + endif() + + if( Boost_NO_SYSTEM_PATHS) + list(APPEND _boost_INCLUDE_SEARCH_DIRS NO_CMAKE_SYSTEM_PATH) + else() + list(APPEND _boost_INCLUDE_SEARCH_DIRS PATHS + C:/boost/include + C:/boost + /sw/local/include + ) + endif() + + # Try to find Boost by stepping backwards through the Boost versions + # we know about. + # Build a list of path suffixes for each version. + set(_boost_PATH_SUFFIXES) + foreach(_boost_VER ${_boost_TEST_VERSIONS}) + # Add in a path suffix, based on the required version, ideally + # we could read this from version.hpp, but for that to work we'd + # need to know the include dir already + set(_boost_BOOSTIFIED_VERSION) + + # Transform 1.35 => 1_35 and 1.36.0 => 1_36_0 + if(_boost_VER MATCHES "([0-9]+)\\.([0-9]+)\\.([0-9]+)") + set(_boost_BOOSTIFIED_VERSION + "${CMAKE_MATCH_1}_${CMAKE_MATCH_2}_${CMAKE_MATCH_3}") + elseif(_boost_VER MATCHES "([0-9]+)\\.([0-9]+)") + set(_boost_BOOSTIFIED_VERSION + "${CMAKE_MATCH_1}_${CMAKE_MATCH_2}") + endif() + + list(APPEND _boost_PATH_SUFFIXES + "boost-${_boost_BOOSTIFIED_VERSION}" + "boost_${_boost_BOOSTIFIED_VERSION}" + "boost/boost-${_boost_BOOSTIFIED_VERSION}" + "boost/boost_${_boost_BOOSTIFIED_VERSION}" + ) + + endforeach() + + if(Boost_DEBUG) + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + "Include debugging info:") + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + " _boost_INCLUDE_SEARCH_DIRS = ${_boost_INCLUDE_SEARCH_DIRS}") + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + " _boost_PATH_SUFFIXES = ${_boost_PATH_SUFFIXES}") + endif() + + # Look for a standard boost header file. + find_path(Boost_INCLUDE_DIR + NAMES boost/config.hpp + HINTS ${_boost_INCLUDE_SEARCH_DIRS} + PATH_SUFFIXES ${_boost_PATH_SUFFIXES} + ) +endif() + +# ------------------------------------------------------------------------ +# Extract version information from version.hpp +# ------------------------------------------------------------------------ + +# Set Boost_FOUND based only on header location and version. +# It will be updated below for component libraries. +if(Boost_INCLUDE_DIR) + if(Boost_DEBUG) + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + "location of version.hpp: ${Boost_INCLUDE_DIR}/boost/version.hpp") + endif() + + # Extract Boost_VERSION and Boost_LIB_VERSION from version.hpp + set(Boost_VERSION 0) + set(Boost_LIB_VERSION "") + file(STRINGS "${Boost_INCLUDE_DIR}/boost/version.hpp" _boost_VERSION_HPP_CONTENTS REGEX "#define BOOST_(LIB_)?VERSION ") + set(_Boost_VERSION_REGEX "([0-9]+)") + set(_Boost_LIB_VERSION_REGEX "\"([0-9_]+)\"") + foreach(v VERSION LIB_VERSION) + if("${_boost_VERSION_HPP_CONTENTS}" MATCHES "#define BOOST_${v} ${_Boost_${v}_REGEX}") + set(Boost_${v} "${CMAKE_MATCH_1}") + endif() + endforeach() + unset(_boost_VERSION_HPP_CONTENTS) + + math(EXPR Boost_MAJOR_VERSION "${Boost_VERSION} / 100000") + math(EXPR Boost_MINOR_VERSION "${Boost_VERSION} / 100 % 1000") + math(EXPR Boost_SUBMINOR_VERSION "${Boost_VERSION} % 100") + + set(Boost_ERROR_REASON + "${Boost_ERROR_REASON}Boost version: ${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}\nBoost include path: ${Boost_INCLUDE_DIR}") + if(Boost_DEBUG) + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + "version.hpp reveals boost " + "${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}") + endif() + + if(Boost_FIND_VERSION) + # Set Boost_FOUND based on requested version. + set(_Boost_VERSION "${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}") + if("${_Boost_VERSION}" VERSION_LESS "${Boost_FIND_VERSION}") + set(Boost_FOUND 0) + set(_Boost_VERSION_AGE "old") + elseif(Boost_FIND_VERSION_EXACT AND + NOT "${_Boost_VERSION}" VERSION_EQUAL "${Boost_FIND_VERSION}") + set(Boost_FOUND 0) + set(_Boost_VERSION_AGE "new") + else() + set(Boost_FOUND 1) + endif() + if(NOT Boost_FOUND) + # State that we found a version of Boost that is too new or too old. + set(Boost_ERROR_REASON + "${Boost_ERROR_REASON}\nDetected version of Boost is too ${_Boost_VERSION_AGE}. Requested version was ${Boost_FIND_VERSION_MAJOR}.${Boost_FIND_VERSION_MINOR}") + if (Boost_FIND_VERSION_PATCH) + set(Boost_ERROR_REASON + "${Boost_ERROR_REASON}.${Boost_FIND_VERSION_PATCH}") + endif () + if (NOT Boost_FIND_VERSION_EXACT) + set(Boost_ERROR_REASON "${Boost_ERROR_REASON} (or newer)") + endif () + set(Boost_ERROR_REASON "${Boost_ERROR_REASON}.") + endif () + else() + # Caller will accept any Boost version. + set(Boost_FOUND 1) + endif() +else() + set(Boost_FOUND 0) + set(Boost_ERROR_REASON + "${Boost_ERROR_REASON}Unable to find the Boost header files. Please set BOOST_ROOT to the root directory containing Boost or BOOST_INCLUDEDIR to the directory containing Boost's headers.") +endif() + +# ------------------------------------------------------------------------ +# Prefix initialization +# ------------------------------------------------------------------------ + +set(Boost_LIB_PREFIX "") +if ( (GHSMULTI AND Boost_USE_STATIC_LIBS) OR + (WIN32 AND Boost_USE_STATIC_LIBS AND NOT CYGWIN) ) + set(Boost_LIB_PREFIX "lib") +endif() + +if ( NOT Boost_NAMESPACE ) + set(Boost_NAMESPACE "boost") +endif() + +# ------------------------------------------------------------------------ +# Suffix initialization and compiler suffix detection. +# ------------------------------------------------------------------------ + +set(_Boost_VARS_NAME + Boost_NAMESPACE + Boost_COMPILER + Boost_THREADAPI + Boost_USE_DEBUG_PYTHON + Boost_USE_MULTITHREADED + Boost_USE_STATIC_LIBS + Boost_USE_STATIC_RUNTIME + Boost_USE_STLPORT + Boost_USE_STLPORT_DEPRECATED_NATIVE_IOSTREAMS + ) +_Boost_CHANGE_DETECT(_Boost_CHANGE_LIBNAME ${_Boost_VARS_NAME}) + +# Setting some more suffixes for the library +if (Boost_COMPILER) + set(_boost_COMPILER ${Boost_COMPILER}) + if(Boost_DEBUG) + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + "using user-specified Boost_COMPILER = ${_boost_COMPILER}") + endif() +else() + # Attempt to guess the compiler suffix + # NOTE: this is not perfect yet, if you experience any issues + # please report them and use the Boost_COMPILER variable + # to work around the problems. + _Boost_GUESS_COMPILER_PREFIX(_boost_COMPILER) + if(Boost_DEBUG) + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + "guessed _boost_COMPILER = ${_boost_COMPILER}") + endif() +endif() + +set (_boost_MULTITHREADED "-mt") +if( NOT Boost_USE_MULTITHREADED ) + set (_boost_MULTITHREADED "") +endif() +if(Boost_DEBUG) + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + "_boost_MULTITHREADED = ${_boost_MULTITHREADED}") +endif() + +#====================== +# Systematically build up the Boost ABI tag +# http://boost.org/doc/libs/1_41_0/more/getting_started/windows.html#library-naming +set( _boost_RELEASE_ABI_TAG "-") +set( _boost_DEBUG_ABI_TAG "-") +# Key Use this library when: +# s linking statically to the C++ standard library and +# compiler runtime support libraries. +if(Boost_USE_STATIC_RUNTIME) + set( _boost_RELEASE_ABI_TAG "${_boost_RELEASE_ABI_TAG}s") + set( _boost_DEBUG_ABI_TAG "${_boost_DEBUG_ABI_TAG}s") +endif() +# g using debug versions of the standard and runtime +# support libraries +if(WIN32 AND Boost_USE_DEBUG_RUNTIME) + if(MSVC OR "${CMAKE_CXX_COMPILER}" MATCHES "icl" + OR "${CMAKE_CXX_COMPILER}" MATCHES "icpc") + set(_boost_DEBUG_ABI_TAG "${_boost_DEBUG_ABI_TAG}g") + endif() +endif() +# y using special debug build of python +if(Boost_USE_DEBUG_PYTHON) + set(_boost_DEBUG_ABI_TAG "${_boost_DEBUG_ABI_TAG}y") +endif() +# d using a debug version of your code +set(_boost_DEBUG_ABI_TAG "${_boost_DEBUG_ABI_TAG}d") +# p using the STLport standard library rather than the +# default one supplied with your compiler +if(Boost_USE_STLPORT) + set( _boost_RELEASE_ABI_TAG "${_boost_RELEASE_ABI_TAG}p") + set( _boost_DEBUG_ABI_TAG "${_boost_DEBUG_ABI_TAG}p") +endif() +# n using the STLport deprecated "native iostreams" feature +if(Boost_USE_STLPORT_DEPRECATED_NATIVE_IOSTREAMS) + set( _boost_RELEASE_ABI_TAG "${_boost_RELEASE_ABI_TAG}n") + set( _boost_DEBUG_ABI_TAG "${_boost_DEBUG_ABI_TAG}n") +endif() + +if(Boost_DEBUG) + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + "_boost_RELEASE_ABI_TAG = ${_boost_RELEASE_ABI_TAG}") + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + "_boost_DEBUG_ABI_TAG = ${_boost_DEBUG_ABI_TAG}") +endif() + +# ------------------------------------------------------------------------ +# Begin finding boost libraries +# ------------------------------------------------------------------------ + +set(_Boost_VARS_LIB "") +foreach(c DEBUG RELEASE) + set(_Boost_VARS_LIB_${c} BOOST_LIBRARYDIR Boost_LIBRARY_DIR_${c}) + list(APPEND _Boost_VARS_LIB ${_Boost_VARS_LIB_${c}}) + _Boost_CHANGE_DETECT(_Boost_CHANGE_LIBDIR_${c} ${_Boost_VARS_DIR} ${_Boost_VARS_LIB_${c}} Boost_INCLUDE_DIR) + # Clear Boost_LIBRARY_DIR_${c} if it did not change but other input affecting the + # location did. We will find a new one based on the new inputs. + if(_Boost_CHANGE_LIBDIR_${c} AND NOT _Boost_LIBRARY_DIR_${c}_CHANGED) + unset(Boost_LIBRARY_DIR_${c} CACHE) + endif() + + # If Boost_LIBRARY_DIR_[RELEASE,DEBUG] is set, prefer its value. + if(Boost_LIBRARY_DIR_${c}) + set(_boost_LIBRARY_SEARCH_DIRS_${c} ${Boost_LIBRARY_DIR_${c}} NO_DEFAULT_PATH NO_CMAKE_FIND_ROOT_PATH) + else() + set(_boost_LIBRARY_SEARCH_DIRS_${c} "") + if(BOOST_LIBRARYDIR) + list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} ${BOOST_LIBRARYDIR}) + elseif(_ENV_BOOST_LIBRARYDIR) + list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} ${_ENV_BOOST_LIBRARYDIR}) + endif() + + if(BOOST_ROOT) + list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} ${BOOST_ROOT}/lib ${BOOST_ROOT}/stage/lib) + elseif(_ENV_BOOST_ROOT) + list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} ${_ENV_BOOST_ROOT}/lib ${_ENV_BOOST_ROOT}/stage/lib) + endif() + + list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} + ${Boost_INCLUDE_DIR}/lib + ${Boost_INCLUDE_DIR}/../lib + ${Boost_INCLUDE_DIR}/stage/lib + ) + if( Boost_NO_SYSTEM_PATHS ) + list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} NO_CMAKE_SYSTEM_PATH) + else() + list(APPEND _boost_LIBRARY_SEARCH_DIRS_${c} PATHS + C:/boost/lib + C:/boost + /sw/local/lib + ) + endif() + endif() +endforeach() + +if(Boost_DEBUG) + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + "_boost_LIBRARY_SEARCH_DIRS_RELEASE = ${_boost_LIBRARY_SEARCH_DIRS_RELEASE}" + "_boost_LIBRARY_SEARCH_DIRS_DEBUG = ${_boost_LIBRARY_SEARCH_DIRS_DEBUG}") +endif() + +# Support preference of static libs by adjusting CMAKE_FIND_LIBRARY_SUFFIXES +if( Boost_USE_STATIC_LIBS ) + set( _boost_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES ${CMAKE_FIND_LIBRARY_SUFFIXES}) + if(WIN32) + set(CMAKE_FIND_LIBRARY_SUFFIXES .lib .a ${CMAKE_FIND_LIBRARY_SUFFIXES}) + else() + set(CMAKE_FIND_LIBRARY_SUFFIXES .a ) + endif() +endif() + +# We want to use the tag inline below without risking double dashes +if(_boost_RELEASE_ABI_TAG) + if(${_boost_RELEASE_ABI_TAG} STREQUAL "-") + set(_boost_RELEASE_ABI_TAG "") + endif() +endif() +if(_boost_DEBUG_ABI_TAG) + if(${_boost_DEBUG_ABI_TAG} STREQUAL "-") + set(_boost_DEBUG_ABI_TAG "") + endif() +endif() + +# The previous behavior of FindBoost when Boost_USE_STATIC_LIBS was enabled +# on WIN32 was to: +# 1. Search for static libs compiled against a SHARED C++ standard runtime library (use if found) +# 2. Search for static libs compiled against a STATIC C++ standard runtime library (use if found) +# We maintain this behavior since changing it could break people's builds. +# To disable the ambiguous behavior, the user need only +# set Boost_USE_STATIC_RUNTIME either ON or OFF. +set(_boost_STATIC_RUNTIME_WORKAROUND false) +if(WIN32 AND Boost_USE_STATIC_LIBS) + if(NOT DEFINED Boost_USE_STATIC_RUNTIME) + set(_boost_STATIC_RUNTIME_WORKAROUND true) + endif() +endif() + +# On versions < 1.35, remove the System library from the considered list +# since it wasn't added until 1.35. +if(Boost_VERSION AND Boost_FIND_COMPONENTS) + if(Boost_VERSION LESS 103500) + list(REMOVE_ITEM Boost_FIND_COMPONENTS system) + endif() +endif() + +# Additional components may be required via component dependencies. +# Add any missing components to the list. +_Boost_MISSING_DEPENDENCIES(Boost_FIND_COMPONENTS _Boost_EXTRA_FIND_COMPONENTS) + +# If thread is required, get the thread libs as a dependency +list(FIND Boost_FIND_COMPONENTS thread _Boost_THREAD_DEPENDENCY_LIBS) +if(NOT _Boost_THREAD_DEPENDENCY_LIBS EQUAL -1) + include(CMakeFindDependencyMacro) + find_dependency(Threads) +endif() + +# If the user changed any of our control inputs flush previous results. +if(_Boost_CHANGE_LIBDIR OR _Boost_CHANGE_LIBNAME) + foreach(COMPONENT ${_Boost_COMPONENTS_SEARCHED}) + string(TOUPPER ${COMPONENT} UPPERCOMPONENT) + foreach(c DEBUG RELEASE) + set(_var Boost_${UPPERCOMPONENT}_LIBRARY_${c}) + unset(${_var} CACHE) + set(${_var} "${_var}-NOTFOUND") + endforeach() + endforeach() + set(_Boost_COMPONENTS_SEARCHED "") +endif() + +foreach(COMPONENT ${Boost_FIND_COMPONENTS}) + string(TOUPPER ${COMPONENT} UPPERCOMPONENT) + + set( _boost_docstring_release "Boost ${COMPONENT} library (release)") + set( _boost_docstring_debug "Boost ${COMPONENT} library (debug)") + + if(${COMPONENT} STREQUAL "python" OR ${COMPONENT} STREQUAL "mpi_python") + # Get version of Python. + if (NOT PYTHON_EXECUTABLE) + #if a certain version of python was detected by cmake before use that one + set(PYTHON_EXECUTABLE "python") + endif (NOT PYTHON_EXECUTABLE) + execute_process(COMMAND "${PYTHON_EXECUTABLE}" -c "import sys; sys.stdout.write('.'.join(str(x) for x in sys.version_info[:2]))" OUTPUT_VARIABLE _python_version) + endif() + + # Compute component-specific hints. + set(_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT "") + if(${COMPONENT} STREQUAL "mpi" OR ${COMPONENT} STREQUAL "mpi_python" OR + ${COMPONENT} STREQUAL "graph_parallel") + foreach(lib ${MPI_CXX_LIBRARIES} ${MPI_C_LIBRARIES}) + if(IS_ABSOLUTE "${lib}") + get_filename_component(libdir "${lib}" PATH) + string(REPLACE "\\" "/" libdir "${libdir}") + list(APPEND _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT ${libdir}) + endif() + endforeach() + endif() + + # Consolidate and report component-specific hints. + if(_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT) + list(REMOVE_DUPLICATES _Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT) + if(Boost_DEBUG) + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + "Component-specific library search paths for ${COMPONENT}: " + "${_Boost_FIND_LIBRARY_HINTS_FOR_COMPONENT}") + endif() + endif() + + # + # Find RELEASE libraries + # + set(_boost_RELEASE_NAMES + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT} ) + if(${COMPONENT} STREQUAL "python" OR ${COMPONENT} STREQUAL "mpi_python") + list(APPEND _boost_RELEASE_NAMES + ${Boost_LIB_PREFIX}boost_${COMPONENT}-${_python_version}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}boost_${COMPONENT}-${_python_version}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG} + ${Boost_LIB_PREFIX}boost_${COMPONENT}-${_python_version}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}boost_${COMPONENT}-${_python_version}${_boost_MULTITHREADED}${_boost_RELEASE_ABI_TAG} + ${Boost_LIB_PREFIX}boost_${COMPONENT}-${_python_version} ) + endif() + + if(_boost_STATIC_RUNTIME_WORKAROUND) + set(_boost_RELEASE_STATIC_ABI_TAG "-s${_boost_RELEASE_ABI_TAG}") + list(APPEND _boost_RELEASE_NAMES + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG} ) + if(${COMPONENT} STREQUAL "python" OR ${COMPONENT} STREQUAL "mpi_python") + list(APPEND _boost_RELEASE_NAMES + ${Boost_LIB_PREFIX}boost_${COMPONENT}-${_python_version}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}boost_${COMPONENT}-${_python_version}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG} + ${Boost_LIB_PREFIX}boost_${COMPONENT}-${_python_version}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}boost_${COMPONENT}-${_python_version}${_boost_MULTITHREADED}${_boost_RELEASE_STATIC_ABI_TAG} ) + endif() + endif() + if(Boost_THREADAPI AND ${COMPONENT} STREQUAL "thread") + _Boost_PREPEND_LIST_WITH_THREADAPI(_boost_RELEASE_NAMES ${_boost_RELEASE_NAMES}) + endif() + if(Boost_DEBUG) + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + "Searching for ${UPPERCOMPONENT}_LIBRARY_RELEASE: ${_boost_RELEASE_NAMES}") + endif() + + # if Boost_LIBRARY_DIR_RELEASE is not defined, + # but Boost_LIBRARY_DIR_DEBUG is, look there first for RELEASE libs + if(NOT Boost_LIBRARY_DIR_RELEASE AND Boost_LIBRARY_DIR_DEBUG) + list(INSERT _boost_LIBRARY_SEARCH_DIRS_RELEASE 0 ${Boost_LIBRARY_DIR_DEBUG}) + endif() + + # Avoid passing backslashes to _Boost_FIND_LIBRARY due to macro re-parsing. + string(REPLACE "\\" "/" _boost_LIBRARY_SEARCH_DIRS_tmp "${_boost_LIBRARY_SEARCH_DIRS_RELEASE}") + + _Boost_FIND_LIBRARY(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE RELEASE + NAMES ${_boost_RELEASE_NAMES} + HINTS ${_boost_LIBRARY_SEARCH_DIRS_tmp} + NAMES_PER_DIR + DOC "${_boost_docstring_release}" + ) + + # + # Find DEBUG libraries + # + set(_boost_DEBUG_NAMES + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT} ) + if(${COMPONENT} STREQUAL "python" OR ${COMPONENT} STREQUAL "mpi_python") + list(APPEND _boost_DEBUG_NAMES + ${Boost_LIB_PREFIX}boost_${COMPONENT}-${_python_version}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}boost_${COMPONENT}-${_python_version}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG} + ${Boost_LIB_PREFIX}boost_${COMPONENT}-${_python_version}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}boost_${COMPONENT}-${_python_version}${_boost_MULTITHREADED}${_boost_DEBUG_ABI_TAG} + ${Boost_LIB_PREFIX}boost_${COMPONENT}-${_python_version}${_boost_MULTITHREADED} + ${Boost_LIB_PREFIX}boost_${COMPONENT}-${_python_version} ) + endif() + if(_boost_STATIC_RUNTIME_WORKAROUND) + set(_boost_DEBUG_STATIC_ABI_TAG "-s${_boost_DEBUG_ABI_TAG}") + list(APPEND _boost_DEBUG_NAMES + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}${Boost_NAMESPACE}_${COMPONENT}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG} ) + if(${COMPONENT} STREQUAL "python" OR ${COMPONENT} STREQUAL "mpi_python") + list(APPEND _boost_DEBUG_NAMES + ${Boost_LIB_PREFIX}boost_${COMPONENT}-${_python_version}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}boost_${COMPONENT}-${_python_version}${_boost_COMPILER}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG} + ${Boost_LIB_PREFIX}boost_${COMPONENT}-${_python_version}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG}-${Boost_LIB_VERSION} + ${Boost_LIB_PREFIX}boost_${COMPONENT}-${_python_version}${_boost_MULTITHREADED}${_boost_DEBUG_STATIC_ABI_TAG} ) + endif() + endif() + if(Boost_THREADAPI AND ${COMPONENT} STREQUAL "thread") + _Boost_PREPEND_LIST_WITH_THREADAPI(_boost_DEBUG_NAMES ${_boost_DEBUG_NAMES}) + endif() + if(Boost_DEBUG) + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] " + "Searching for ${UPPERCOMPONENT}_LIBRARY_DEBUG: ${_boost_DEBUG_NAMES}") + endif() + + # if Boost_LIBRARY_DIR_DEBUG is not defined, + # but Boost_LIBRARY_DIR_RELEASE is, look there first for DEBUG libs + if(NOT Boost_LIBRARY_DIR_DEBUG AND Boost_LIBRARY_DIR_RELEASE) + list(INSERT _boost_LIBRARY_SEARCH_DIRS_DEBUG 0 ${Boost_LIBRARY_DIR_RELEASE}) + endif() + + # Avoid passing backslashes to _Boost_FIND_LIBRARY due to macro re-parsing. + string(REPLACE "\\" "/" _boost_LIBRARY_SEARCH_DIRS_tmp "${_boost_LIBRARY_SEARCH_DIRS_DEBUG}") + + _Boost_FIND_LIBRARY(Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG DEBUG + NAMES ${_boost_DEBUG_NAMES} + HINTS ${_boost_LIBRARY_SEARCH_DIRS_tmp} + NAMES_PER_DIR + DOC "${_boost_docstring_debug}" + ) + + if(Boost_REALPATH) + _Boost_SWAP_WITH_REALPATH(Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE "${_boost_docstring_release}") + _Boost_SWAP_WITH_REALPATH(Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG "${_boost_docstring_debug}" ) + endif() + + _Boost_ADJUST_LIB_VARS(${UPPERCOMPONENT}) + +endforeach() + +# Restore the original find library ordering +if( Boost_USE_STATIC_LIBS ) + set(CMAKE_FIND_LIBRARY_SUFFIXES ${_boost_ORIG_CMAKE_FIND_LIBRARY_SUFFIXES}) +endif() + +# ------------------------------------------------------------------------ +# End finding boost libraries +# ------------------------------------------------------------------------ + +set(Boost_INCLUDE_DIRS ${Boost_INCLUDE_DIR}) +set(Boost_LIBRARY_DIRS) +if(Boost_LIBRARY_DIR_RELEASE) + list(APPEND Boost_LIBRARY_DIRS ${Boost_LIBRARY_DIR_RELEASE}) +endif() +if(Boost_LIBRARY_DIR_DEBUG) + list(APPEND Boost_LIBRARY_DIRS ${Boost_LIBRARY_DIR_DEBUG}) +endif() +if(Boost_LIBRARY_DIRS) + list(REMOVE_DUPLICATES Boost_LIBRARY_DIRS) +endif() + +# The above setting of Boost_FOUND was based only on the header files. +# Update it for the requested component libraries. +if(Boost_FOUND) + # The headers were found. Check for requested component libs. + set(_boost_CHECKED_COMPONENT FALSE) + set(_Boost_MISSING_COMPONENTS "") + foreach(COMPONENT ${Boost_FIND_COMPONENTS}) + string(TOUPPER ${COMPONENT} COMPONENT) + set(_boost_CHECKED_COMPONENT TRUE) + if(NOT Boost_${COMPONENT}_FOUND) + string(TOLOWER ${COMPONENT} COMPONENT) + list(APPEND _Boost_MISSING_COMPONENTS ${COMPONENT}) + endif() + endforeach() + if(_Boost_MISSING_COMPONENTS AND _Boost_EXTRA_FIND_COMPONENTS) + # Optional indirect dependencies are not counted as missing. + list(REMOVE_ITEM _Boost_MISSING_COMPONENTS ${_Boost_EXTRA_FIND_COMPONENTS}) + endif() + + if(Boost_DEBUG) + message(STATUS "[ ${CMAKE_CURRENT_LIST_FILE}:${CMAKE_CURRENT_LIST_LINE} ] Boost_FOUND = ${Boost_FOUND}") + endif() + + if (_Boost_MISSING_COMPONENTS) + set(Boost_FOUND 0) + # We were unable to find some libraries, so generate a sensible + # error message that lists the libraries we were unable to find. + set(Boost_ERROR_REASON + "${Boost_ERROR_REASON}\nCould not find the following") + if(Boost_USE_STATIC_LIBS) + set(Boost_ERROR_REASON "${Boost_ERROR_REASON} static") + endif() + set(Boost_ERROR_REASON + "${Boost_ERROR_REASON} Boost libraries:\n") + foreach(COMPONENT ${_Boost_MISSING_COMPONENTS}) + set(Boost_ERROR_REASON + "${Boost_ERROR_REASON} ${Boost_NAMESPACE}_${COMPONENT}\n") + endforeach() + + list(LENGTH Boost_FIND_COMPONENTS Boost_NUM_COMPONENTS_WANTED) + list(LENGTH _Boost_MISSING_COMPONENTS Boost_NUM_MISSING_COMPONENTS) + if (${Boost_NUM_COMPONENTS_WANTED} EQUAL ${Boost_NUM_MISSING_COMPONENTS}) + set(Boost_ERROR_REASON + "${Boost_ERROR_REASON}No Boost libraries were found. You may need to set BOOST_LIBRARYDIR to the directory containing Boost libraries or BOOST_ROOT to the location of Boost.") + else () + set(Boost_ERROR_REASON + "${Boost_ERROR_REASON}Some (but not all) of the required Boost libraries were found. You may need to install these additional Boost libraries. Alternatively, set BOOST_LIBRARYDIR to the directory containing Boost libraries or BOOST_ROOT to the location of Boost.") + endif () + endif () + + if( NOT Boost_LIBRARY_DIRS AND NOT _boost_CHECKED_COMPONENT ) + # Compatibility Code for backwards compatibility with CMake + # 2.4's FindBoost module. + + # Look for the boost library path. + # Note that the user may not have installed any libraries + # so it is quite possible the Boost_LIBRARY_DIRS may not exist. + set(_boost_LIB_DIR ${Boost_INCLUDE_DIR}) + + if("${_boost_LIB_DIR}" MATCHES "boost-[0-9]+") + get_filename_component(_boost_LIB_DIR ${_boost_LIB_DIR} PATH) + endif() + + if("${_boost_LIB_DIR}" MATCHES "/include$") + # Strip off the trailing "/include" in the path. + get_filename_component(_boost_LIB_DIR ${_boost_LIB_DIR} PATH) + endif() + + if(EXISTS "${_boost_LIB_DIR}/lib") + set(_boost_LIB_DIR ${_boost_LIB_DIR}/lib) + else() + if(EXISTS "${_boost_LIB_DIR}/stage/lib") + set(_boost_LIB_DIR ${_boost_LIB_DIR}/stage/lib) + else() + set(_boost_LIB_DIR "") + endif() + endif() + + if(_boost_LIB_DIR AND EXISTS "${_boost_LIB_DIR}") + set(Boost_LIBRARY_DIRS ${_boost_LIB_DIR}) + endif() + + endif() +else() + # Boost headers were not found so no components were found. + foreach(COMPONENT ${Boost_FIND_COMPONENTS}) + string(TOUPPER ${COMPONENT} UPPERCOMPONENT) + set(Boost_${UPPERCOMPONENT}_FOUND 0) + endforeach() +endif() + +# ------------------------------------------------------------------------ +# Add imported targets +# ------------------------------------------------------------------------ + +if(Boost_FOUND AND _Boost_IMPORTED_TARGETS) + # For header-only libraries + if(NOT TARGET Boost::boost) + add_library(Boost::boost INTERFACE IMPORTED) + if(Boost_INCLUDE_DIRS) + set_target_properties(Boost::boost PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}") + endif() + endif() + + foreach(COMPONENT ${Boost_FIND_COMPONENTS}) + if(NOT TARGET Boost::${COMPONENT}) + string(TOUPPER ${COMPONENT} UPPERCOMPONENT) + if(Boost_${UPPERCOMPONENT}_FOUND) + if(Boost_USE_STATIC_LIBS) + add_library(Boost::${COMPONENT} STATIC IMPORTED) + else() + # Even if Boost_USE_STATIC_LIBS is OFF, we might have static + # libraries as a result. + add_library(Boost::${COMPONENT} UNKNOWN IMPORTED) + endif() + if(Boost_INCLUDE_DIRS) + set_target_properties(Boost::${COMPONENT} PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES "${Boost_INCLUDE_DIRS}") + endif() + if(EXISTS "${Boost_${UPPERCOMPONENT}_LIBRARY}") + set_target_properties(Boost::${COMPONENT} PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES "CXX" + IMPORTED_LOCATION "${Boost_${UPPERCOMPONENT}_LIBRARY}") + endif() + if(EXISTS "${Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG}") + set_property(TARGET Boost::${COMPONENT} APPEND PROPERTY + IMPORTED_CONFIGURATIONS DEBUG) + set_target_properties(Boost::${COMPONENT} PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES_DEBUG "CXX" + IMPORTED_LOCATION_DEBUG "${Boost_${UPPERCOMPONENT}_LIBRARY_DEBUG}") + endif() + if(EXISTS "${Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE}") + set_property(TARGET Boost::${COMPONENT} APPEND PROPERTY + IMPORTED_CONFIGURATIONS RELEASE) + set_target_properties(Boost::${COMPONENT} PROPERTIES + IMPORTED_LINK_INTERFACE_LANGUAGES_RELEASE "CXX" + IMPORTED_LOCATION_RELEASE "${Boost_${UPPERCOMPONENT}_LIBRARY_RELEASE}") + endif() + if(_Boost_${UPPERCOMPONENT}_DEPENDENCIES) + unset(_Boost_${UPPERCOMPONENT}_TARGET_DEPENDENCIES) + foreach(dep ${_Boost_${UPPERCOMPONENT}_DEPENDENCIES}) + list(APPEND _Boost_${UPPERCOMPONENT}_TARGET_DEPENDENCIES Boost::${dep}) + endforeach() + if(COMPONENT STREQUAL "thread") + list(APPEND _Boost_${UPPERCOMPONENT}_TARGET_DEPENDENCIES Threads::Threads) + endif() + set_target_properties(Boost::${COMPONENT} PROPERTIES + INTERFACE_LINK_LIBRARIES "${_Boost_${UPPERCOMPONENT}_TARGET_DEPENDENCIES}") + endif() + endif() + endif() + endforeach() +endif() + +# ------------------------------------------------------------------------ +# Notification to end user about what was found +# ------------------------------------------------------------------------ + +set(Boost_LIBRARIES "") +if(Boost_FOUND) + if(NOT Boost_FIND_QUIETLY) + message(STATUS "Boost version: ${Boost_MAJOR_VERSION}.${Boost_MINOR_VERSION}.${Boost_SUBMINOR_VERSION}") + if(Boost_FIND_COMPONENTS) + message(STATUS "Found the following Boost libraries:") + endif() + endif() + foreach( COMPONENT ${Boost_FIND_COMPONENTS} ) + string( TOUPPER ${COMPONENT} UPPERCOMPONENT ) + if( Boost_${UPPERCOMPONENT}_FOUND ) + if(NOT Boost_FIND_QUIETLY) + message (STATUS " ${COMPONENT}") + endif() + list(APPEND Boost_LIBRARIES ${Boost_${UPPERCOMPONENT}_LIBRARY}) + endif() + endforeach() +else() + if(Boost_FIND_REQUIRED) + message(SEND_ERROR "Unable to find the requested Boost libraries.\n${Boost_ERROR_REASON}") + else() + if(NOT Boost_FIND_QUIETLY) + # we opt not to automatically output Boost_ERROR_REASON here as + # it could be quite lengthy and somewhat imposing in its requests + # Since Boost is not always a required dependency we'll leave this + # up to the end-user. + if(Boost_DEBUG OR Boost_DETAILED_FAILURE_MSG) + message(STATUS "Could NOT find Boost\n${Boost_ERROR_REASON}") + else() + message(STATUS "Could NOT find Boost") + endif() + endif() + endif() +endif() + +# Configure display of cache entries in GUI. +foreach(v BOOSTROOT BOOST_ROOT ${_Boost_VARS_INC} ${_Boost_VARS_LIB}) + get_property(_type CACHE ${v} PROPERTY TYPE) + if(_type) + set_property(CACHE ${v} PROPERTY ADVANCED 1) + if("x${_type}" STREQUAL "xUNINITIALIZED") + if("x${v}" STREQUAL "xBoost_ADDITIONAL_VERSIONS") + set_property(CACHE ${v} PROPERTY TYPE STRING) + else() + set_property(CACHE ${v} PROPERTY TYPE PATH) + endif() + endif() + endif() +endforeach() + +# Record last used values of input variables so we can +# detect on the next run if the user changed them. +foreach(v + ${_Boost_VARS_INC} ${_Boost_VARS_LIB} + ${_Boost_VARS_DIR} ${_Boost_VARS_NAME} + ) + if(DEFINED ${v}) + set(_${v}_LAST "${${v}}" CACHE INTERNAL "Last used ${v} value.") + else() + unset(_${v}_LAST CACHE) + endif() +endforeach() + +# Maintain a persistent list of components requested anywhere since +# the last flush. +set(_Boost_COMPONENTS_SEARCHED "${_Boost_COMPONENTS_SEARCHED}") +list(APPEND _Boost_COMPONENTS_SEARCHED ${Boost_FIND_COMPONENTS}) +list(REMOVE_DUPLICATES _Boost_COMPONENTS_SEARCHED) +list(SORT _Boost_COMPONENTS_SEARCHED) +set(_Boost_COMPONENTS_SEARCHED "${_Boost_COMPONENTS_SEARCHED}" + CACHE INTERNAL "Components requested for this build tree.") From af9a8d9c91a1a195da51ec3b1adc3ec6516d41cf Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Thu, 2 Jun 2016 21:38:36 +0200 Subject: [PATCH 39/92] dummy fix --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e399523..adae75f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ target_compile_features(dplayer++ PUBLIC cxx_range_for cxx_auto_type cxx_lambdas list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") #Check if boost exists -find_package(Boost 1.60.0 COMPONENTS filesystem program_options) +find_package(Boost COMPONENTS filesystem program_options) if(NOT Boost_FOUND) message( FATAL_ERROR "Boost libraries not found." ) From 20302e970fcd6b195cfaba5f60455670c76f690d Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Thu, 2 Jun 2016 22:09:52 +0200 Subject: [PATCH 40/92] string literals are not compatible with gcc 4.9 --- src/main.cpp | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main.cpp b/src/main.cpp index facbb88..a5f921b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,8 +5,6 @@ #include #include -using namespace std::string_literals; - //Copied from the net. void daemonize() { pid_t pid, sid; @@ -55,7 +53,7 @@ void daemonize() { int main(int argc, char* argv[]) { - if(argc == 2 && argv[1] == "-d"s) { + if(argc == 2 && argv[1] == string("-d")) { daemonize(); } else { std::cout << "If you want to run it as a daemon restart it with \"-d\" flag" << std::endl; @@ -67,4 +65,4 @@ int main(int argc, char* argv[]) { } catch(std::exception& e) { std::cerr << e.what() << std::endl; } -} \ No newline at end of file +} From d80b2240f4ea1886b75a15f9d54366b91c51ff11 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Thu, 2 Jun 2016 22:12:20 +0200 Subject: [PATCH 41/92] idiotic fix --- src/main.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index a5f921b..8b1d68f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -4,6 +4,7 @@ #include #include +#include //Copied from the net. void daemonize() { @@ -53,7 +54,7 @@ void daemonize() { int main(int argc, char* argv[]) { - if(argc == 2 && argv[1] == string("-d")) { + if(argc == 2 && argv[1] == std::string("-d")) { daemonize(); } else { std::cout << "If you want to run it as a daemon restart it with \"-d\" flag" << std::endl; From 90a8c0e7cf91c7ad0b82ef9405331c1c7204d758 Mon Sep 17 00:00:00 2001 From: David Date: Thu, 2 Jun 2016 23:40:25 +0200 Subject: [PATCH 42/92] Update README.md --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 5347305..13d9cda 100644 --- a/README.md +++ b/README.md @@ -33,3 +33,7 @@ El programa al iniciar lee la configuración de ~/.config/player++/daemon.conf - Soporte para plugins - Ecualizador - Cache de canciones recientes (para agilizar la búsqueda) + +#### Colaboradores +Lista de gente que ha colaborado de alguna forma con el proyecto +[@masapastosa](https://github.com/masapastosa) [@javorcd](https://github.com/javorcd) From 459d8d8d0f80e2063a25af0e038c8a6ed9296100 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Fri, 3 Jun 2016 00:53:34 +0200 Subject: [PATCH 43/92] create unlicense --- UNLICENSE | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 UNLICENSE diff --git a/UNLICENSE b/UNLICENSE new file mode 100644 index 0000000..68a49da --- /dev/null +++ b/UNLICENSE @@ -0,0 +1,24 @@ +This is free and unencumbered software released into the public domain. + +Anyone is free to copy, modify, publish, use, compile, sell, or +distribute this software, either in source code form or as a compiled +binary, for any purpose, commercial or non-commercial, and by any +means. + +In jurisdictions that recognize copyright laws, the author or authors +of this software dedicate any and all copyright interest in the +software to the public domain. We make this dedication for the benefit +of the public at large and to the detriment of our heirs and +successors. We intend this dedication to be an overt act of +relinquishment in perpetuity of all present and future rights to this +software under copyright law. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. +IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR +OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, +ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR +OTHER DEALINGS IN THE SOFTWARE. + +For more information, please refer to From 3c3a31dac8d5e813c5303147bc2846095b9166ef Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Fri, 3 Jun 2016 11:33:33 +0200 Subject: [PATCH 44/92] travis --- .travis.yml | 46 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 46 insertions(+) create mode 100644 .travis.yml diff --git a/.travis.yml b/.travis.yml new file mode 100644 index 0000000..9631ca1 --- /dev/null +++ b/.travis.yml @@ -0,0 +1,46 @@ +language: cpp +sudo: required +dist: trusty + +matrix: + include: + - compiler: gcc + addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: + - g++-4.9 + env: COMPILER=g++-4.9 + - compiler: gcc + addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: + - g++-5 + env: COMPILER=g++-5 + - compiler: clang + addons: + apt: + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-precise-3.6 + packages: + - clang-3.6 + env: COMPILER=clang++-3.6 + - compiler: clang + addons: + apt: + sources: + - ubuntu-toolchain-r-test + - llvm-toolchain-precise-3.7 + packages: + - clang-3.7 + env: COMPILER=clang++-3.7 + + +script: + - mkdir build + - cd build + - cmake -DCMAKE_CXX_COMPILER=$COMPILER .. && make From 12541838b4140785e81ee48475ea81c2032700a4 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Fri, 3 Jun 2016 11:37:29 +0200 Subject: [PATCH 45/92] add dependencies to travis --- .travis.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.travis.yml b/.travis.yml index 9631ca1..6d7c54d 100644 --- a/.travis.yml +++ b/.travis.yml @@ -40,6 +40,10 @@ matrix: env: COMPILER=clang++-3.7 +before_install: + - sudo apt-get update -qq + - sudo apt-get install -y libmpg123-dev libsfml-dev libboost-filesystem-dev libboost-program-options-dev libtag1-dev + script: - mkdir build - cd build From 6880333d88771af0f334a417587d289069a96e45 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Fri, 3 Jun 2016 11:55:46 +0200 Subject: [PATCH 46/92] fucking travis --- .travis.yml | 14 ++------------ 1 file changed, 2 insertions(+), 12 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6d7c54d..0defd3b 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,40 +1,30 @@ language: cpp sudo: required -dist: trusty +dist: wily matrix: include: - compiler: gcc addons: apt: - sources: - - ubuntu-toolchain-r-test packages: - g++-4.9 env: COMPILER=g++-4.9 - compiler: gcc addons: apt: - sources: - - ubuntu-toolchain-r-test packages: - g++-5 env: COMPILER=g++-5 - compiler: clang addons: apt: - sources: - - ubuntu-toolchain-r-test - - llvm-toolchain-precise-3.6 packages: - clang-3.6 env: COMPILER=clang++-3.6 - compiler: clang addons: apt: - sources: - - ubuntu-toolchain-r-test - - llvm-toolchain-precise-3.7 packages: - clang-3.7 env: COMPILER=clang++-3.7 @@ -47,4 +37,4 @@ before_install: script: - mkdir build - cd build - - cmake -DCMAKE_CXX_COMPILER=$COMPILER .. && make + - cmake -DCMAKE_CXX_COMPILER=$COMPILER .. && make VERBOSE=1 From d5ac17c1ea899433bb56dfd37ac811fa05d5e559 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Sun, 5 Jun 2016 18:21:02 +0200 Subject: [PATCH 47/92] fix travis --- .travis.yml | 19 +++++-------------- CMakeLists.txt | 3 ++- 2 files changed, 7 insertions(+), 15 deletions(-) diff --git a/.travis.yml b/.travis.yml index 0defd3b..c81d1bc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,34 +1,25 @@ language: cpp sudo: required -dist: wily +dist: trusty matrix: include: - compiler: gcc addons: apt: + sources: + - ubuntu-toolchain-r-test packages: - g++-4.9 env: COMPILER=g++-4.9 - compiler: gcc addons: apt: + sources: + - ubuntu-toolchain-r-test packages: - g++-5 env: COMPILER=g++-5 - - compiler: clang - addons: - apt: - packages: - - clang-3.6 - env: COMPILER=clang++-3.6 - - compiler: clang - addons: - apt: - packages: - - clang-3.7 - env: COMPILER=clang++-3.7 - before_install: - sudo apt-get update -qq diff --git a/CMakeLists.txt b/CMakeLists.txt index adae75f..946c9c0 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -28,8 +28,9 @@ endif() target_link_libraries(dplayer++ ${CMAKE_THREAD_LIBS_INIT}) +target_link_libraries(dplayer++ sfml-system sfml-audio mpg123 tag sqlite3) + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic") -set(CMAKE_EXE_LINKER_FLAGS "-lsfml-system -lsfml-audio -lmpg123 -ltag -lsqlite3" ) #RELEASE set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -flto") From 2856033f283851c538723b28b5c1ab1e136ce72a Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Sun, 5 Jun 2016 18:24:02 +0200 Subject: [PATCH 48/92] add build status --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 13d9cda..22fa1ef 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,7 @@ # cppplayer +[![Build Status](https://travis-ci.org/stakewinner00/cppplayer.svg?branch=master)](https://travis-ci.org/stakewinner00/cppplayer) + Reproductor de música sencillo que busca la simplicidad y facilidad de configuración (se podría ver como alternativa a mpd) El programa usa las librerías mpg123, sfml, TagLib boost-program-options y boost-filesystem. From 997cb3b45156da7180895aeed00b163a836c88fc Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Tue, 14 Jun 2016 01:55:12 +0200 Subject: [PATCH 49/92] add volume commands --- include/commands.h | 15 +++++++++++++++ include/music.h | 3 +++ src/manager.cpp | 15 +++++++++++++++ src/music.cpp | 13 ++++++++++++- 4 files changed, 45 insertions(+), 1 deletion(-) diff --git a/include/commands.h b/include/commands.h index aac4c43..ee5d576 100644 --- a/include/commands.h +++ b/include/commands.h @@ -8,10 +8,25 @@ enum class Command : char { PAUSE, STOP, SORT_RANDOM, + + //Return the requested metadata GET_ARTIST, GET_TITLE, GET_FILE, + + //Create a playlist with songs that match an artist. FILTER_ARTIST, + + //Add songs to the current playlist and the full list of songs. ADD_FOLDER, ADD_FILE, + + //Operates with playlists + //Saves the current songs3 to a playlist + SAVE_FILE, + //Saves the current list to a playlist + SAVE_PLAYLIST, + + VOLUME_SET, + VOLUME_GET, }; \ No newline at end of file diff --git a/include/music.h b/include/music.h index 76e3c21..8b5a898 100644 --- a/include/music.h +++ b/include/music.h @@ -61,6 +61,9 @@ class Music { Status GetStatus() const; void SetStatus(Status s); + void SetVolume(float v); + float GetVolume(); + MusicList& GetList(); Song& GetCurrent(); private: diff --git a/src/manager.cpp b/src/manager.cpp index 7c5aa61..1a9a48c 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -160,6 +160,21 @@ void Manager::ExecuteCommand(Command c) { music.GetList().LoadFile(s); } break; + case Command::VOLUME_SET: + { + std::string s; + std::fstream file(conf.GetDaemonPipe()); + getline(file, s); + file.close(); + music.SetVolume(std::atof(s.c_str())); + } + break; + case Command::VOLUME_GET: + { + std::fstream file(conf.GetClientPipe()); + file << std::to_string(music.GetVolume()) << std::endl; + } + break; //case Command::SAVE_FILE: // break; } diff --git a/src/music.cpp b/src/music.cpp index 8d3e155..c0fb338 100644 --- a/src/music.cpp +++ b/src/music.cpp @@ -35,7 +35,7 @@ void Music::PlayList() { void Music::Play() { if(song.GetExtension() == ".mp3") Reproduce(mp3music, song.GetFile().c_str()); - else Reproduce(music, song.GetFile().c_str()); + else Reproduce(music, song.GetFile().c_str()); } Status Music::GetStatus() const { @@ -51,6 +51,17 @@ void Music::SetStatus(Status s) { cv.notify_one(); } +void Music::SetVolume(float v) { + music.setVolume(v); + mp3music.setVolume(v); +} + +float Music::GetVolume() { + //XXX: mp3music and music have the same value, doesn't + //matter if we return mp3music.getVolume() or music.getVolume() + return music.getVolume(); +} + bool Music::IsStatus(Status s) { bool tmp = GetStatus()==s; if(tmp) mymutex.notify(); From 01410e34fa2bea3def2db89ea083c468e7e6a083 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Fri, 17 Jun 2016 12:05:54 +0200 Subject: [PATCH 50/92] write default config file if it doesn't exists --- src/config.cpp | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/config.cpp b/src/config.cpp index 6a98c4a..d8014bc 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -15,6 +15,7 @@ Config::Config() { } void Config::Load() { + //TODO: Maybe we should use boost propertytree library #ifdef DEBUG std::cout << "Using config file " << MakeAbsolute(CONFIG_FOLDER+"daemon.conf") << std::endl; #endif @@ -31,6 +32,15 @@ void Config::Load() { std::ifstream config(MakeAbsolute(CONFIG_FOLDER+"daemon.conf")); if(!config.is_open()) { std::cerr << "Config file could not be open, using default values" << std::endl; + //Write a dumb config file + std::ofstream config(MakeAbsolute(CONFIG_FOLDER+"daemon.conf")); + config.setf(std::ios::boolalpha); + config << "daemon_pipe = " << GetDaemonPipe() << std::endl + << "client_pipe = " << GetClientPipe() << std::endl + << "music_folder = " << GetDir() << std::endl + << "auto_start = " << GetAutostart() << std::endl + << "pid_file = " << GetPidFile() << std::endl + << "db_file = " << GetDbFile() << std::endl; } else { options_description desc("Options"); desc.add_options() From f0e7aecd3f3269d258c0e46819233556c9ccc1b1 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Sat, 18 Jun 2016 00:55:03 +0200 Subject: [PATCH 51/92] . --- include/config.h | 2 +- include/manager.h | 6 +++-- src/config.cpp | 22 +++++++++--------- src/manager.cpp | 57 ++++++++++++++++++++++++----------------------- 4 files changed, 45 insertions(+), 42 deletions(-) diff --git a/include/config.h b/include/config.h index 7744c57..4af26bc 100644 --- a/include/config.h +++ b/include/config.h @@ -21,7 +21,7 @@ class Config { path GetDir() const; bool GetAutostart() const; private: - std::string MakeAbsolute(const std::string file); + std::string Expand(const std::string file); std::string GetHome(); struct Options { //Pipe used by the daemon to write to client diff --git a/include/manager.h b/include/manager.h index 540daad..f597b65 100644 --- a/include/manager.h +++ b/include/manager.h @@ -5,6 +5,8 @@ #include "database.h" #include "commands.h" +#include + //The main work is done in this class //It process the commands from the client @@ -19,8 +21,8 @@ class Manager { //Start the main loop void StartServer(); private: - Command ReadCommand(); - void ExecuteCommand(Command c); + Command ReadCommand(std::ifstream&); + void ExecuteCommand(Command c, std::ifstream&); Music music; Database db; Config conf; diff --git a/src/config.cpp b/src/config.cpp index d8014bc..56433f4 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -8,7 +8,7 @@ using namespace boost::program_options; Config::Config() { - path dir(MakeAbsolute(CONFIG_FOLDER)); + path dir(Expand(CONFIG_FOLDER)); if(!exists(dir) && !create_directory(dir)) throw std::runtime_error("Could not create config directory"); @@ -17,23 +17,23 @@ Config::Config() { void Config::Load() { //TODO: Maybe we should use boost propertytree library #ifdef DEBUG - std::cout << "Using config file " << MakeAbsolute(CONFIG_FOLDER+"daemon.conf") << std::endl; + std::cout << "Using config file " << Expand(CONFIG_FOLDER+"daemon.conf") << std::endl; #endif //Try to autodetect music dir //Here we should use libxdg to parse ~/.config/user-dirs.dirs (if exists) //and get the default music dir. - path default_music(MakeAbsolute("~/Music/")); + path default_music(Expand("~/Music/")); if(exists(default_music)) opt.dir = default_music.c_str(); - std::ifstream config(MakeAbsolute(CONFIG_FOLDER+"daemon.conf")); + std::ifstream config(Expand(CONFIG_FOLDER+"daemon.conf")); if(!config.is_open()) { std::cerr << "Config file could not be open, using default values" << std::endl; //Write a dumb config file - std::ofstream config(MakeAbsolute(CONFIG_FOLDER+"daemon.conf")); + std::ofstream config(Expand(CONFIG_FOLDER+"daemon.conf")); config.setf(std::ios::boolalpha); config << "daemon_pipe = " << GetDaemonPipe() << std::endl << "client_pipe = " << GetClientPipe() << std::endl @@ -58,11 +58,11 @@ void Config::Load() { notify(vm); } - opt.daemonpipe =MakeAbsolute(opt.daemonpipe); - opt.clientpipe =MakeAbsolute(opt.clientpipe); - opt.pidfile =MakeAbsolute(opt.pidfile); - opt.dbfile =MakeAbsolute(opt.dbfile); - opt.dir =MakeAbsolute(opt.dir.c_str()); + opt.daemonpipe =Expand(opt.daemonpipe); + opt.clientpipe =Expand(opt.clientpipe); + opt.pidfile =Expand(opt.pidfile); + opt.dbfile =Expand(opt.dbfile); + opt.dir =Expand(opt.dir.c_str()); } std::string Config::GetDaemonPipe() const { @@ -91,7 +91,7 @@ bool Config::GetAutostart() const { //Private functions -std::string Config::MakeAbsolute(std::string file) { +std::string Config::Expand(std::string file) { auto pos = file.find('~'); if(pos != std::string::npos) { file.erase(pos,1); diff --git a/src/manager.cpp b/src/manager.cpp index 1a9a48c..e404969 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -4,8 +4,8 @@ #include #include #include -#include #include +#include //Public functions @@ -65,8 +65,9 @@ void Manager::StartServer() { music.SetStatus(Status::Playing); } + std::ifstream f; while(music.GetStatus() != Status::Exit) { - ExecuteCommand(ReadCommand()); + ExecuteCommand(ReadCommand(f), f); } mplayer.join(); } @@ -74,17 +75,19 @@ void Manager::StartServer() { //Private Functions -Command Manager::ReadCommand() { - std::ifstream f(conf.GetDaemonPipe()); +Command Manager::ReadCommand(std::ifstream& f) { + f.open(conf.GetDaemonPipe()); if(!f.is_open()) { throw std::runtime_error("Daemon pipe could not be opened"); } - auto tmp = static_cast(f.get()); return tmp; } -void Manager::ExecuteCommand(Command c) { +void Manager::ExecuteCommand(Command c, std::ifstream& dfile) { + #ifdef DEBUG + std::cout << "Command:" <<(int)c << std::endl; + #endif switch (c) { case Command::QUIT: music.SetStatus(Status::Exit); @@ -112,28 +115,26 @@ void Manager::ExecuteCommand(Command c) { break; case Command::GET_ARTIST: { - std::fstream file(conf.GetClientPipe()); - file << music.GetCurrent().GetArtist() << std::endl; + std::ofstream cfile(conf.GetClientPipe()); + cfile << music.GetCurrent().GetArtist() << std::endl; } break; case Command::GET_TITLE: { - std::fstream file(conf.GetClientPipe()); - file << music.GetCurrent().GetTitle() << std::endl; + std::ofstream cfile(conf.GetClientPipe()); + cfile << music.GetCurrent().GetTitle() << std::endl; } break; case Command::GET_FILE: { - std::fstream file(conf.GetClientPipe()); - file << music.GetCurrent().GetFile() << std::endl; + std::ofstream cfile(conf.GetClientPipe()); + cfile << music.GetCurrent().GetFile() << std::endl; } break; case Command::FILTER_ARTIST: { std::string s; - std::fstream file(conf.GetDaemonPipe()); - getline(file, s); - file.close(); + getline(dfile, s); //Stop reproduction while we are filtering the list auto tmp = music.GetStatus(); @@ -145,37 +146,37 @@ void Manager::ExecuteCommand(Command c) { case Command::ADD_FOLDER: { std::string s; - std::fstream file(conf.GetDaemonPipe()); - getline(file, s); - file.close(); + getline(dfile, s); music.GetList().LoadDir(s); } break; case Command::ADD_FILE: { std::string s; - std::fstream file(conf.GetDaemonPipe()); - getline(file, s); - file.close(); + getline(dfile, s); music.GetList().LoadFile(s); } break; case Command::VOLUME_SET: { - std::string s; - std::fstream file(conf.GetDaemonPipe()); - getline(file, s); - file.close(); - music.SetVolume(std::atof(s.c_str())); + std::string volum; + dfile >> volum; + #ifdef DEBUG + std::cout << volum << std::endl; + #endif + music.SetVolume(std::atof(volum.c_str())); } break; case Command::VOLUME_GET: { - std::fstream file(conf.GetClientPipe()); - file << std::to_string(music.GetVolume()) << std::endl; + std::ofstream cfile(conf.GetClientPipe()); + cfile << std::to_string(music.GetVolume()) << std::endl; } break; //case Command::SAVE_FILE: // break; } + + dfile.get(); + dfile.close(); } From 787dc25cf6aa4b91167337878ba3ac5248a26800 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Sat, 18 Jun 2016 10:08:54 +0200 Subject: [PATCH 52/92] delete config example --- README.md | 3 ++- player++.config.example | 5 ----- 2 files changed, 2 insertions(+), 6 deletions(-) delete mode 100644 player++.config.example diff --git a/README.md b/README.md index 22fa1ef..5e4bcfe 100644 --- a/README.md +++ b/README.md @@ -17,7 +17,8 @@ Nota: En debian stable (jessie) no hay la versión necesaria de cmake, para arre #### Configuración -El programa al iniciar lee la configuración de ~/.config/player++/daemon.conf +El programa al iniciar lee la configuración de ~/.config/player++/daemon.conf +Si no existe ninguna configuración se crea una por defecto #### Features diff --git a/player++.config.example b/player++.config.example deleted file mode 100644 index 7584ae1..0000000 --- a/player++.config.example +++ /dev/null @@ -1,5 +0,0 @@ -#daemon_pipe = /tmp/dplayer++ -#client_pipe = /tmp/cplayer++ -music_folder = ~/Music -auto_start = false -pid_file = /tmp/player++.pid From 9d378aa8c777bf86d22e2e467deca99ffb60802c Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Sat, 18 Jun 2016 10:24:56 +0200 Subject: [PATCH 53/92] minor changes --- src/manager.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/manager.cpp b/src/manager.cpp index e404969..7f9289f 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -65,9 +65,11 @@ void Manager::StartServer() { music.SetStatus(Status::Playing); } - std::ifstream f; while(music.GetStatus() != Status::Exit) { + std::ifstream f(conf.GetDaemonPipe()); ExecuteCommand(ReadCommand(f), f); + + f.get(); } mplayer.join(); } @@ -76,7 +78,6 @@ void Manager::StartServer() { //Private Functions Command Manager::ReadCommand(std::ifstream& f) { - f.open(conf.GetDaemonPipe()); if(!f.is_open()) { throw std::runtime_error("Daemon pipe could not be opened"); } @@ -176,7 +177,4 @@ void Manager::ExecuteCommand(Command c, std::ifstream& dfile) { //case Command::SAVE_FILE: // break; } - - dfile.get(); - dfile.close(); } From f1db00df755deaeb6a8c16a850f0d295819801ac Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Sat, 18 Jun 2016 16:29:37 +0200 Subject: [PATCH 54/92] update readme --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 5e4bcfe..9c2f075 100644 --- a/README.md +++ b/README.md @@ -37,6 +37,11 @@ Si no existe ninguna configuración se crea una por defecto - Ecualizador - Cache de canciones recientes (para agilizar la búsqueda) +#### Clientes + +- https://github.com/stakewinner00/web_cppplayer (cliente web) +- https://github.com/stakewinner00/cl_cppplayer (cliente por terminal) + #### Colaboradores Lista de gente que ha colaborado de alguna forma con el proyecto -[@masapastosa](https://github.com/masapastosa) [@javorcd](https://github.com/javorcd) +[@masapastosa](https://github.com/masapastosa) [@javorcd](https://github.com/javorcd) [@kid_goth](https://github.com/bssanchez) From 4ba8650dc28e99ae53fcd16eaac9cf205a7f19f5 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Sat, 18 Jun 2016 20:21:52 +0200 Subject: [PATCH 55/92] undo filter when artist = "" --- src/musiclist.cpp | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/src/musiclist.cpp b/src/musiclist.cpp index e883b2b..c6b373e 100644 --- a/src/musiclist.cpp +++ b/src/musiclist.cpp @@ -38,13 +38,17 @@ void MusicList::Sort(Order s) { } void MusicList::FilterArtist(const std::string artist) { - song_list.clear(); - for(auto s : full_list ) { - #ifdef DEBUG - std::cout << "Analyzing " << s->GetFile() << std::endl; - #endif - if(s->GetArtist() == artist) - song_list.emplace_back(s); + if(artist != "") { + song_list.clear(); + for(auto s : full_list ) { + #ifdef DEBUG + std::cout << "Analyzing " << s->GetFile() << std::endl; + #endif + if(s->GetArtist() == artist) + song_list.emplace_back(s); + } + } else { + song_list = full_list; } } From e7b0d8c6cb9417ce7f3f13c78cca95ebb536a2b5 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Mon, 20 Jun 2016 20:39:26 +0200 Subject: [PATCH 56/92] use property_tree to parse the ini file --- CMakeLists.txt | 2 +- src/config.cpp | 65 +++++++++++++++++++++++++------------------------- 2 files changed, 34 insertions(+), 33 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 946c9c0..e7d5809 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,7 +10,7 @@ target_compile_features(dplayer++ PUBLIC cxx_range_for cxx_auto_type cxx_lambdas list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}/cmake") #Check if boost exists -find_package(Boost COMPONENTS filesystem program_options) +find_package(Boost COMPONENTS filesystem) if(NOT Boost_FOUND) message( FATAL_ERROR "Boost libraries not found." ) diff --git a/src/config.cpp b/src/config.cpp index 56433f4..6d09a90 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -2,10 +2,11 @@ #include #include -#include +#include +#include -using namespace boost::program_options; +namespace pt = boost::property_tree; Config::Config() { path dir(Expand(CONFIG_FOLDER)); @@ -21,6 +22,8 @@ void Config::Load() { #endif + + //Try to autodetect music dir //Here we should use libxdg to parse ~/.config/user-dirs.dirs (if exists) //and get the default music dir. @@ -31,38 +34,36 @@ void Config::Load() { std::ifstream config(Expand(CONFIG_FOLDER+"daemon.conf")); if(!config.is_open()) { - std::cerr << "Config file could not be open, using default values" << std::endl; - //Write a dumb config file - std::ofstream config(Expand(CONFIG_FOLDER+"daemon.conf")); - config.setf(std::ios::boolalpha); - config << "daemon_pipe = " << GetDaemonPipe() << std::endl - << "client_pipe = " << GetClientPipe() << std::endl - << "music_folder = " << GetDir() << std::endl - << "auto_start = " << GetAutostart() << std::endl - << "pid_file = " << GetPidFile() << std::endl - << "db_file = " << GetDbFile() << std::endl; + std::cerr << "Config file could not be open, using default values" << std::endl; + //Write a dumb config file + std::ofstream config(Expand(CONFIG_FOLDER+"daemon.conf")); + config.setf(std::ios::boolalpha); + config << "daemon_pipe = " << GetDaemonPipe() << std::endl + << "client_pipe = " << GetClientPipe() << std::endl + << "music_folder = " << GetDir() << std::endl + << "auto_start = " << GetAutostart() << std::endl + << "pid_file = " << GetPidFile() << std::endl + << "db_file = " << GetDbFile() << std::endl; + + opt.daemonpipe =Expand(opt.daemonpipe); + opt.clientpipe =Expand(opt.clientpipe); + opt.pidfile =Expand(opt.pidfile); + opt.dbfile =Expand(opt.dbfile); + opt.dir =Expand(opt.dir.c_str()); + } else { - options_description desc("Options"); - desc.add_options() - ("daemon_pipe", value(&opt.daemonpipe)) - ("client_pipe", value(&opt.clientpipe)) - ("pid_file", value(&opt.pidfile)) - ("db_file", value(&opt.dbfile)) - ("music_folder", value(&opt.dir)) - ("auto_start", value(&opt.autostart)) - - ; - - variables_map vm = variables_map(); - store(parse_config_file(config , desc, true), vm); - notify(vm); - } + pt::ptree tree; + pt::read_ini(config, tree); + + //The second argument of tree.get is the default value - opt.daemonpipe =Expand(opt.daemonpipe); - opt.clientpipe =Expand(opt.clientpipe); - opt.pidfile =Expand(opt.pidfile); - opt.dbfile =Expand(opt.dbfile); - opt.dir =Expand(opt.dir.c_str()); + opt.daemonpipe = Expand(tree.get("daemon_pipe", opt.daemonpipe)); + opt.clientpipe = Expand(tree.get("client_pipe", opt.clientpipe)); + opt.pidfile = Expand(tree.get("pid_file", opt.pidfile)); + opt.dbfile = Expand(tree.get("db_file", opt.dbfile)); + opt.dir = Expand(tree.get("music_folder", opt.dir).c_str()); + opt.autostart = tree.get("auto_start", opt.autostart); + } } std::string Config::GetDaemonPipe() const { From 3a60c1c7236fe7680588d914a14791da7635a8ed Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Tue, 21 Jun 2016 11:28:17 +0200 Subject: [PATCH 57/92] make the public header compatible with C --- CMakeLists.txt | 2 ++ README.md | 4 ++-- include/commands.h | 11 ++++++++++- 3 files changed, 14 insertions(+), 3 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e7d5809..996d195 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -5,6 +5,8 @@ include_directories(include) file(GLOB_RECURSE SRC_FILES src/*.cpp) add_executable(dplayer++ ${SRC_FILES}) install(PROGRAMS build/dplayer++ DESTINATION /usr/local/bin) +install(DIRECTORY DESTINATION /usr/include/cppplayer) +install(FILES include/commands.h DESTINATION /usr/include/cppplayer) target_compile_features(dplayer++ PUBLIC cxx_range_for cxx_auto_type cxx_lambdas) diff --git a/README.md b/README.md index 9c2f075..1fec2c3 100644 --- a/README.md +++ b/README.md @@ -10,8 +10,8 @@ El programa usa las librerías mpg123, sfml, TagLib boost-program-options y boos **# apt-get install libmpg123-dev libsfml-dev libboost-filesystem-dev libboost-program-options-dev libtag1-dev** -Para compilarlo -> mkdir -p build; cd build; cmake ..; make +Para compilarlo y instalarlo +> mkdir -p build; cd build; cmake ..; make; sudo make install Nota: En debian stable (jessie) no hay la versión necesaria de cmake, para arreglarlo se puede pasar a debian testing, que si tiene la versión necesaria. diff --git a/include/commands.h b/include/commands.h index ee5d576..0766eee 100644 --- a/include/commands.h +++ b/include/commands.h @@ -1,6 +1,10 @@ #pragma once +#ifdef __cplusplus enum class Command : char { +#else +typedef enum { +#endif QUIT, PLAY, NEXT, @@ -29,4 +33,9 @@ enum class Command : char { VOLUME_SET, VOLUME_GET, -}; \ No newline at end of file +#ifdef __cplusplus +}; +#else +} Command; +#endif + From a78fe103e3e58fce18759dfd1ada4f252d1c8480 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Tue, 21 Jun 2016 11:28:33 +0200 Subject: [PATCH 58/92] use ptree library --- src/config.cpp | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/src/config.cpp b/src/config.cpp index 6d09a90..2e2e7c4 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -37,13 +37,14 @@ void Config::Load() { std::cerr << "Config file could not be open, using default values" << std::endl; //Write a dumb config file std::ofstream config(Expand(CONFIG_FOLDER+"daemon.conf")); - config.setf(std::ios::boolalpha); - config << "daemon_pipe = " << GetDaemonPipe() << std::endl - << "client_pipe = " << GetClientPipe() << std::endl - << "music_folder = " << GetDir() << std::endl - << "auto_start = " << GetAutostart() << std::endl - << "pid_file = " << GetPidFile() << std::endl - << "db_file = " << GetDbFile() << std::endl; + pt::ptree tree; + tree.put("daemon_pipe", opt.daemonpipe); + tree.put("client_pipe", opt.clientpipe); + tree.put("pid_file", opt.pidfile); + tree.put("db_file", opt.dbfile); + tree.put("music_folder", opt.dir); + tree.put("auto_start", opt.autostart); + pt::write_ini(config, tree); opt.daemonpipe =Expand(opt.daemonpipe); opt.clientpipe =Expand(opt.clientpipe); From 2db802d65b0beba92fe4955830e336c599940eb1 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Wed, 22 Jun 2016 19:30:20 +0200 Subject: [PATCH 59/92] silly fix to support unicode --- include/song.h | 8 ++++---- src/config.cpp | 4 ---- src/song.cpp | 12 ++++++------ 3 files changed, 10 insertions(+), 14 deletions(-) diff --git a/include/song.h b/include/song.h index dbe1f61..859bbc5 100644 --- a/include/song.h +++ b/include/song.h @@ -9,13 +9,13 @@ class Song { public: Song(path p); Song() =default; - std::string GetTitle(); - std::string GetArtist(); + std::wstring GetTitle(); + std::wstring GetArtist(); std::string GetFile(); std::string GetExtension(); private: std::string extension; - std::string artist; - std::string title; + std::wstring artist; + std::wstring title; std::string file; }; \ No newline at end of file diff --git a/src/config.cpp b/src/config.cpp index 2e2e7c4..1e9c931 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -16,14 +16,10 @@ Config::Config() { } void Config::Load() { - //TODO: Maybe we should use boost propertytree library #ifdef DEBUG std::cout << "Using config file " << Expand(CONFIG_FOLDER+"daemon.conf") << std::endl; #endif - - - //Try to autodetect music dir //Here we should use libxdg to parse ~/.config/user-dirs.dirs (if exists) //and get the default music dir. diff --git a/src/song.cpp b/src/song.cpp index f3a8987..475602c 100644 --- a/src/song.cpp +++ b/src/song.cpp @@ -14,35 +14,35 @@ Song::Song(path p) { file = p.c_str(); } -std::string Song::GetTitle() { +std::wstring Song::GetTitle() { std::lock_guard song_guard(song_mutex); if(title == "") { TagLib::FileRef f(file.c_str()); if(f.isNull()) { - artist = title = "Unknown"; + artist = title = L"Unknown"; } else { auto tmp = f.tag()->title(); if( tmp == TagLib::String::null) { tmp = TagLib::String("Unknown"); } - title = tmp.to8Bit(); + title = tmp.toWString(); } } return title; } -std::string Song::GetArtist() { +std::wstring Song::GetArtist() { std::lock_guard song_guard(song_mutex); if(artist == "") { TagLib::FileRef f(file.c_str()); if(f.isNull()) { - artist = title = "Unknown"; + artist = title = L"Unknown"; } else { auto tmp = f.tag()->artist(); if( tmp == TagLib::String::null) { tmp = TagLib::String("Unknown"); } - artist = tmp.to8Bit(); + artist = tmp.toWString(); } } return artist; From 5cd0f69c6897ba8543f08df4482450f63096004b Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Wed, 22 Jun 2016 20:28:32 +0200 Subject: [PATCH 60/92] revert last commit --- include/song.h | 8 ++++---- src/song.cpp | 13 +++++++------ 2 files changed, 11 insertions(+), 10 deletions(-) diff --git a/include/song.h b/include/song.h index 859bbc5..dbe1f61 100644 --- a/include/song.h +++ b/include/song.h @@ -9,13 +9,13 @@ class Song { public: Song(path p); Song() =default; - std::wstring GetTitle(); - std::wstring GetArtist(); + std::string GetTitle(); + std::string GetArtist(); std::string GetFile(); std::string GetExtension(); private: std::string extension; - std::wstring artist; - std::wstring title; + std::string artist; + std::string title; std::string file; }; \ No newline at end of file diff --git a/src/song.cpp b/src/song.cpp index 475602c..54ed3f1 100644 --- a/src/song.cpp +++ b/src/song.cpp @@ -14,35 +14,36 @@ Song::Song(path p) { file = p.c_str(); } -std::wstring Song::GetTitle() { +std::string Song::GetTitle() { std::lock_guard song_guard(song_mutex); if(title == "") { TagLib::FileRef f(file.c_str()); if(f.isNull()) { - artist = title = L"Unknown"; + artist = title = "Unknown"; } else { auto tmp = f.tag()->title(); if( tmp == TagLib::String::null) { tmp = TagLib::String("Unknown"); } - title = tmp.toWString(); + title = tmp.to8Bit(); } } return title; } -std::wstring Song::GetArtist() { +std::string Song::GetArtist() { std::lock_guard song_guard(song_mutex); if(artist == "") { TagLib::FileRef f(file.c_str()); if(f.isNull()) { - artist = title = L"Unknown"; + artist = title = "Unknown"; } else { auto tmp = f.tag()->artist(); if( tmp == TagLib::String::null) { tmp = TagLib::String("Unknown"); } - artist = tmp.toWString(); + artist = tmp.to8Bit(); + //artist = tmp.toWString(); } } return artist; From ef51d342f279ac79ece30e814b82172354f221e2 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Wed, 22 Jun 2016 21:31:28 +0200 Subject: [PATCH 61/92] add TIME_GET_REMAINING --- include/commands.h | 24 ++++++++++++++++++++++++ include/music.h | 2 ++ src/manager.cpp | 5 +++++ src/music.cpp | 5 +++++ 4 files changed, 36 insertions(+) diff --git a/include/commands.h b/include/commands.h index 0766eee..9797ba3 100644 --- a/include/commands.h +++ b/include/commands.h @@ -1,3 +1,25 @@ +#if 0 +#This way i can source this file and debug with bash +export CPPPLAYER_QUIT="\x00" +export CPPPLAYER_PLAY="\x01" +export CPPPLAYER_NEXT="\x02" +export CPPPLAYER_BACK="\x03" +export CPPPLAYER_PAUSE="\x04" +export CPPPLAYER_STOP="\x05" +export CPPPLAYER_SORT_RANDOM="\x06" +export CPPPLAYER_GET_ARTIST="\x07" +export CPPPLAYER_GET_TITLE="\x08" +export CPPPLAYER_GET_FILE="\x09" +export CPPPLAYER_FILTER_ARTIST="\x0a" +export CPPPLAYER_ADD_FOLDER="\x0b" +export CPPPLAYER_ADD_FILE="\x0c" +export CPPPLAYER_SAVE_FILE="\x0d" +export CPPPLAYER_VOLUME_SET="\x0e" +export CPPPLAYER_VOLUME_GET="\x0f" +export CPPPLAYER_TIME_GET_REMAINING="\x10" +return +#endif + #pragma once #ifdef __cplusplus @@ -33,6 +55,8 @@ typedef enum { VOLUME_SET, VOLUME_GET, + + TIME_GET_REMAINING, #ifdef __cplusplus }; #else diff --git a/include/music.h b/include/music.h index 8b5a898..cc972c1 100644 --- a/include/music.h +++ b/include/music.h @@ -64,6 +64,8 @@ class Music { void SetVolume(float v); float GetVolume(); + int GetRemainingMilliseconds(); + MusicList& GetList(); Song& GetCurrent(); private: diff --git a/src/manager.cpp b/src/manager.cpp index 7f9289f..e9d82d8 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -174,6 +174,11 @@ void Manager::ExecuteCommand(Command c, std::ifstream& dfile) { cfile << std::to_string(music.GetVolume()) << std::endl; } break; + case Command::TIME_GET_REMAINING: + { + std::ofstream cfile(conf.GetClientPipe()); + cfile << music.GetRemainingMilliseconds() << std::endl; + } //case Command::SAVE_FILE: // break; } diff --git a/src/music.cpp b/src/music.cpp index c0fb338..506af48 100644 --- a/src/music.cpp +++ b/src/music.cpp @@ -62,6 +62,11 @@ float Music::GetVolume() { return music.getVolume(); } +int Music::GetRemainingMilliseconds() { + return (music.getDuration().asMilliseconds() - music.getPlayingOffset().asMilliseconds()) + + (mp3music.getDuration().asMilliseconds() - mp3music.getPlayingOffset().asMilliseconds()); +} + bool Music::IsStatus(Status s) { bool tmp = GetStatus()==s; if(tmp) mymutex.notify(); From 86ec7216258e74cba240a3c3305f73e70ca330a9 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Thu, 23 Jun 2016 19:15:56 +0200 Subject: [PATCH 62/92] update dependencies --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 1fec2c3..7b3bf57 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,11 @@ Reproductor de música sencillo que busca la simplicidad y facilidad de configuración (se podría ver como alternativa a mpd) -El programa usa las librerías mpg123, sfml, TagLib boost-program-options y boost-filesystem. +El programa usa las librerías mpg123, sfml, TagLib, boost-filesystem y sqlite. #### Instalación en Debian/Ubuntu -**# apt-get install libmpg123-dev libsfml-dev libboost-filesystem-dev libboost-program-options-dev libtag1-dev** +**# apt-get install libmpg123-dev libsfml-dev libboost-filesystem-dev libsqlite3-dev libtag1-dev** Para compilarlo y instalarlo > mkdir -p build; cd build; cmake ..; make; sudo make install From d6c8815acc8563ebe227147bdbc01fdf4f4ee727 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Sat, 25 Jun 2016 01:52:39 +0200 Subject: [PATCH 63/92] silly fix --- include/commands.h | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/include/commands.h b/include/commands.h index 9797ba3..69a6e80 100644 --- a/include/commands.h +++ b/include/commands.h @@ -14,8 +14,9 @@ export CPPPLAYER_FILTER_ARTIST="\x0a" export CPPPLAYER_ADD_FOLDER="\x0b" export CPPPLAYER_ADD_FILE="\x0c" export CPPPLAYER_SAVE_FILE="\x0d" -export CPPPLAYER_VOLUME_SET="\x0e" -export CPPPLAYER_VOLUME_GET="\x0f" +export CPPPLAYER_SAVE_PLAYLIST="\x0e" +export CPPPLAYER_VOLUME_SET="\x0f" +export CPPPLAYER_VOLUME_GET="\x10" export CPPPLAYER_TIME_GET_REMAINING="\x10" return #endif From c75b6c455f34fb8faad8a530ab625275bf94282a Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Sat, 25 Jun 2016 01:55:12 +0200 Subject: [PATCH 64/92] generalize commands processing and execution generalize commands processing and execution so it will be easier to implemente other protocols in a future --- CMakeLists.txt | 7 +++++ include/manager.h | 11 +++++--- include/protocol.h | 70 ++++++++++++++++++++++++++++++++++++++++++++++ src/manager.cpp | 69 +++++++++++++++------------------------------ 4 files changed, 107 insertions(+), 50 deletions(-) create mode 100644 include/protocol.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 996d195..780877e 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,8 +1,15 @@ cmake_minimum_required(VERSION 3.1.0 FATAL_ERROR) project (cppplayer) +#Compiler define +option(_NAMED_PIPE "Use named pipes as a comunnication protocol" ON) +IF (_NAMED_PIPE) + ADD_DEFINITIONS(-D_NAMED_PIPE) +ENDIF() + include_directories(include) file(GLOB_RECURSE SRC_FILES src/*.cpp) + add_executable(dplayer++ ${SRC_FILES}) install(PROGRAMS build/dplayer++ DESTINATION /usr/local/bin) install(DIRECTORY DESTINATION /usr/include/cppplayer) diff --git a/include/manager.h b/include/manager.h index f597b65..fc11052 100644 --- a/include/manager.h +++ b/include/manager.h @@ -4,8 +4,7 @@ #include "music.h" #include "database.h" #include "commands.h" - -#include +#include "protocol.h" //The main work is done in this class @@ -21,8 +20,12 @@ class Manager { //Start the main loop void StartServer(); private: - Command ReadCommand(std::ifstream&); - void ExecuteCommand(Command c, std::ifstream&); + template + void ProcessCommand(T& proto); + + template + void ExecuteCommand(Command c, T& proto); + Music music; Database db; Config conf; diff --git a/include/protocol.h b/include/protocol.h new file mode 100644 index 0000000..0507a03 --- /dev/null +++ b/include/protocol.h @@ -0,0 +1,70 @@ +#pragma once + +#include +#include +#include +#include "commands.h" + + +//This should only be used for debugging/scripting pourpose +// or if only one client are in use. +class NamedPipe { +public: + NamedPipe(std::string d, std::string c) + : daemon(d), client(c) + {} + + Command ReadCommand() { + CheckDaemon(); + return static_cast(fdaemon.get()); + } + + std::string GetLine() { + CheckDaemon(); + std::string s; + getline(fdaemon, s); + return s; + } + + template + std::ostream& operator<<(const T& obj) { + CheckClient(); + fclient << obj; + return fclient; + } + + template + std::istream& operator>>(T& obj) { + CheckDaemon(); + fdaemon >> obj; + return fdaemon; + } +private: + + void CheckClient() { + if(!fclient.is_open()) { + fclient.open(client); + if(!fclient.is_open()) { + throw std::runtime_error("Client pipe could not be opened"); + } + } + } + + void CheckDaemon() { + //XXX: Workaround + if(fdaemon.peek() == -1) fdaemon.ignore(); + + if(!fdaemon.good() || !fdaemon.is_open()) { + fdaemon.close(); + fdaemon.open(daemon); + if(!fdaemon.is_open()) { + throw std::runtime_error("Daemon pipe could not be opened"); + } + } + } + + std::string daemon; + std::string client; + std::ofstream fclient; + std::ifstream fdaemon; +}; \ No newline at end of file diff --git a/src/manager.cpp b/src/manager.cpp index e9d82d8..6ec1521 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -66,10 +66,14 @@ void Manager::StartServer() { } while(music.GetStatus() != Status::Exit) { - std::ifstream f(conf.GetDaemonPipe()); - ExecuteCommand(ReadCommand(f), f); - - f.get(); + //TODO: Allow to use more than one protocol simultaneously + + #ifdef _NAMED_PIPE + static NamedPipe pipe(conf.GetDaemonPipe(), conf.GetClientPipe()); + ProcessCommand(pipe); + #else + #error At least we need one protocol to use + #endif } mplayer.join(); } @@ -77,15 +81,13 @@ void Manager::StartServer() { //Private Functions -Command Manager::ReadCommand(std::ifstream& f) { - if(!f.is_open()) { - throw std::runtime_error("Daemon pipe could not be opened"); - } - auto tmp = static_cast(f.get()); - return tmp; +template +void Manager::ProcessCommand(T& proto) { + ExecuteCommand(proto.ReadCommand(), proto); } -void Manager::ExecuteCommand(Command c, std::ifstream& dfile) { +template +void Manager::ExecuteCommand(Command c, T& proto) { #ifdef DEBUG std::cout << "Command:" <<(int)c << std::endl; #endif @@ -115,53 +117,33 @@ void Manager::ExecuteCommand(Command c, std::ifstream& dfile) { music.GetList().Sort(Order::RANDOM); break; case Command::GET_ARTIST: - { - std::ofstream cfile(conf.GetClientPipe()); - cfile << music.GetCurrent().GetArtist() << std::endl; - } + proto << music.GetCurrent().GetArtist() << std::endl; break; case Command::GET_TITLE: - { - std::ofstream cfile(conf.GetClientPipe()); - cfile << music.GetCurrent().GetTitle() << std::endl; - } + proto << music.GetCurrent().GetTitle() << std::endl; break; case Command::GET_FILE: - { - std::ofstream cfile(conf.GetClientPipe()); - cfile << music.GetCurrent().GetFile() << std::endl; - } + proto << music.GetCurrent().GetFile() << std::endl; break; case Command::FILTER_ARTIST: { - std::string s; - getline(dfile, s); - //Stop reproduction while we are filtering the list auto tmp = music.GetStatus(); music.SetStatus(Status::Stoped); - music.GetList().FilterArtist(s); + music.GetList().FilterArtist(proto.GetLine()); music.SetStatus(tmp); } break; case Command::ADD_FOLDER: - { - std::string s; - getline(dfile, s); - music.GetList().LoadDir(s); - } + music.GetList().LoadDir(proto.GetLine()); break; case Command::ADD_FILE: - { - std::string s; - getline(dfile, s); - music.GetList().LoadFile(s); - } + music.GetList().LoadFile(proto.GetLine()); break; case Command::VOLUME_SET: { std::string volum; - dfile >> volum; + proto >> volum; #ifdef DEBUG std::cout << volum << std::endl; #endif @@ -169,16 +151,11 @@ void Manager::ExecuteCommand(Command c, std::ifstream& dfile) { } break; case Command::VOLUME_GET: - { - std::ofstream cfile(conf.GetClientPipe()); - cfile << std::to_string(music.GetVolume()) << std::endl; - } + proto << std::to_string(music.GetVolume()) << std::endl; break; case Command::TIME_GET_REMAINING: - { - std::ofstream cfile(conf.GetClientPipe()); - cfile << music.GetRemainingMilliseconds() << std::endl; - } + proto << music.GetRemainingMilliseconds() << std::endl; + //case Command::SAVE_FILE: // break; } From 60f226d217a5a70dba7acc3ec624928cd5969cee Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Sat, 25 Jun 2016 11:45:07 +0200 Subject: [PATCH 65/92] small fixes --- include/config.h | 4 +++- include/protocol.h | 15 ++++++++------- src/config.cpp | 7 ++++++- src/manager.cpp | 2 +- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/include/config.h b/include/config.h index 4af26bc..20f4933 100644 --- a/include/config.h +++ b/include/config.h @@ -24,12 +24,14 @@ class Config { std::string Expand(const std::string file); std::string GetHome(); struct Options { + #ifdef _NAMED_PIPE //Pipe used by the daemon to write to client std::string daemonpipe = CONFIG_FOLDER+"dplayer++"; //Pipe used by the client to write to daemon std::string clientpipe = CONFIG_FOLDER+"cplayer++"; - + #endif + //File to store the pid number so we can check if the daemon is really running std::string pidfile = CONFIG_FOLDER+"player++.pid"; diff --git a/include/protocol.h b/include/protocol.h index 0507a03..b1e9152 100644 --- a/include/protocol.h +++ b/include/protocol.h @@ -1,17 +1,19 @@ #pragma once +#include "commands.h" +#include "config.h" + #include #include #include -#include "commands.h" //This should only be used for debugging/scripting pourpose // or if only one client are in use. class NamedPipe { public: - NamedPipe(std::string d, std::string c) - : daemon(d), client(c) + NamedPipe(Config& c) + : conf(c) {} Command ReadCommand() { @@ -43,7 +45,7 @@ class NamedPipe { void CheckClient() { if(!fclient.is_open()) { - fclient.open(client); + fclient.open(conf.GetClientPipe()); if(!fclient.is_open()) { throw std::runtime_error("Client pipe could not be opened"); } @@ -56,15 +58,14 @@ class NamedPipe { if(!fdaemon.good() || !fdaemon.is_open()) { fdaemon.close(); - fdaemon.open(daemon); + fdaemon.open(conf.GetDaemonPipe()); if(!fdaemon.is_open()) { throw std::runtime_error("Daemon pipe could not be opened"); } } } - std::string daemon; - std::string client; + Config& conf; std::ofstream fclient; std::ifstream fdaemon; }; \ No newline at end of file diff --git a/src/config.cpp b/src/config.cpp index 1e9c931..71f3466 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -34,16 +34,20 @@ void Config::Load() { //Write a dumb config file std::ofstream config(Expand(CONFIG_FOLDER+"daemon.conf")); pt::ptree tree; + #ifdef _NAMED_PIPE tree.put("daemon_pipe", opt.daemonpipe); tree.put("client_pipe", opt.clientpipe); + #endif tree.put("pid_file", opt.pidfile); tree.put("db_file", opt.dbfile); tree.put("music_folder", opt.dir); tree.put("auto_start", opt.autostart); pt::write_ini(config, tree); + #ifdef _NAMED_PIPE opt.daemonpipe =Expand(opt.daemonpipe); opt.clientpipe =Expand(opt.clientpipe); + #endif opt.pidfile =Expand(opt.pidfile); opt.dbfile =Expand(opt.dbfile); opt.dir =Expand(opt.dir.c_str()); @@ -53,9 +57,10 @@ void Config::Load() { pt::read_ini(config, tree); //The second argument of tree.get is the default value - + #ifdef _NAMED_PIPE opt.daemonpipe = Expand(tree.get("daemon_pipe", opt.daemonpipe)); opt.clientpipe = Expand(tree.get("client_pipe", opt.clientpipe)); + #endif opt.pidfile = Expand(tree.get("pid_file", opt.pidfile)); opt.dbfile = Expand(tree.get("db_file", opt.dbfile)); opt.dir = Expand(tree.get("music_folder", opt.dir).c_str()); diff --git a/src/manager.cpp b/src/manager.cpp index 6ec1521..f120b33 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -69,7 +69,7 @@ void Manager::StartServer() { //TODO: Allow to use more than one protocol simultaneously #ifdef _NAMED_PIPE - static NamedPipe pipe(conf.GetDaemonPipe(), conf.GetClientPipe()); + static NamedPipe pipe(conf); ProcessCommand(pipe); #else #error At least we need one protocol to use From 31281e3f868760f8bfccb5fec4328272b1f372e4 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Sun, 26 Jun 2016 17:52:44 +0200 Subject: [PATCH 66/92] first implementation of tcp for comunnication --- CMakeLists.txt | 5 +++ include/config.h | 16 +++++++- include/protocol.h | 99 +++++++++++++++++++++++++++++++++++++++++++--- src/config.cpp | 54 +++++++++++++++++++------ src/manager.cpp | 26 ++++-------- 5 files changed, 164 insertions(+), 36 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 780877e..bfbf803 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -7,6 +7,11 @@ IF (_NAMED_PIPE) ADD_DEFINITIONS(-D_NAMED_PIPE) ENDIF() +option(_TCP_SOCKET "Use a tcp socket for the comunnication" ON) +IF (_TCP_SOCKET) + ADD_DEFINITIONS(-D_TCP_SOCKET) +ENDIF() + include_directories(include) file(GLOB_RECURSE SRC_FILES src/*.cpp) diff --git a/include/config.h b/include/config.h index 20f4933..1aa2485 100644 --- a/include/config.h +++ b/include/config.h @@ -14,8 +14,16 @@ class Config { public: Config(); void Load(); + + #ifdef _NAMED_PIPE std::string GetDaemonPipe() const; std::string GetClientPipe() const; + #elif _TCP_SOCKET + unsigned GetPortNumber() const; + std::string GetBindAddress() const; + #else + #error At least we need one protocol to use + #endif std::string GetPidFile() const; std::string GetDbFile() const; path GetDir() const; @@ -30,8 +38,14 @@ class Config { //Pipe used by the client to write to daemon std::string clientpipe = CONFIG_FOLDER+"cplayer++"; + #elif _TCP_SOCKET + //TODO: ipv6 + unsigned portnumber = 6600; + std::string bindaddress = "0.0.0.0"; + #else + #error At least we need one protocol to use #endif - + //File to store the pid number so we can check if the daemon is really running std::string pidfile = CONFIG_FOLDER+"player++.pid"; diff --git a/include/protocol.h b/include/protocol.h index b1e9152..304a862 100644 --- a/include/protocol.h +++ b/include/protocol.h @@ -3,18 +3,41 @@ #include "commands.h" #include "config.h" -#include -#include #include +#include +#include +#ifdef _NAMED_PIPE +#include +#include +#include +#elif _TCP_SOCKET +#include +#else +#error At least we need one protocol to use +#endif +#ifdef _NAMED_PIPE //This should only be used for debugging/scripting pourpose // or if only one client are in use. class NamedPipe { public: NamedPipe(Config& c) : conf(c) - {} + { + //Delete pipes, if exist (the program exit abnormaly) + unlink(conf.GetDaemonPipe().c_str()); + unlink(conf.GetClientPipe().c_str()); + + mkfifo(conf.GetDaemonPipe().c_str(), 0666); + mkfifo(conf.GetClientPipe().c_str(), 0666); + } + + ~NamedPipe() { + //Delete pipes + unlink(conf.GetDaemonPipe().c_str()); + unlink(conf.GetClientPipe().c_str()); + } Command ReadCommand() { CheckDaemon(); @@ -31,7 +54,7 @@ class NamedPipe { template std::ostream& operator<<(const T& obj) { CheckClient(); - fclient << obj; + fclient << obj << std::endl; return fclient; } @@ -68,4 +91,70 @@ class NamedPipe { Config& conf; std::ofstream fclient; std::ifstream fdaemon; -}; \ No newline at end of file +}; + +#elif _TCP_SOCKET + +using boost::asio::ip::tcp; + +class Tcp { +public: + Tcp(Config& c) + : conf(c) + { + //TODO: Setear la bindadddress + acceptor = new tcp::acceptor(io_service, tcp::endpoint(tcp::v4(), 6600)); + } + + ~Tcp() { + delete acceptor; + } + + Command ReadCommand() { + delete socket; + + socket = new tcp::socket(io_service); + acceptor->accept(*socket); + + char buffer[1]; + boost::asio::read(*socket, boost::asio::buffer(buffer, 1)); + return static_cast(buffer[0]); + } + + std::string GetLine() { + auto bytes = boost::asio::read_until(*socket, buffer, '\n'); + buffer.commit(bytes); + std::string line; + std::getline(is, line); + return line; + } + + template + std::ostream& operator<<(const T& obj) { + os << obj << std::endl; + auto bytes = boost::asio::write(*socket, buffer); + buffer.consume(bytes); + return os; + } + + template + std::istream& operator>>(T& obj) { + auto bytes = boost::asio::read_until(*socket, buffer, '\n'); + buffer.commit(bytes); + is >> obj; + return is; + } +private: + Config& conf; + boost::asio::io_service io_service; + tcp::acceptor* acceptor; + tcp::socket* socket; + + boost::asio::streambuf buffer; + std::istream is{&buffer}; + std::ostream os{&buffer}; +}; + +#else +#error At least we need one protocol to use +#endif \ No newline at end of file diff --git a/src/config.cpp b/src/config.cpp index 71f3466..523cfde 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -34,14 +34,23 @@ void Config::Load() { //Write a dumb config file std::ofstream config(Expand(CONFIG_FOLDER+"daemon.conf")); pt::ptree tree; - #ifdef _NAMED_PIPE - tree.put("daemon_pipe", opt.daemonpipe); - tree.put("client_pipe", opt.clientpipe); - #endif + tree.put("pid_file", opt.pidfile); tree.put("db_file", opt.dbfile); tree.put("music_folder", opt.dir); tree.put("auto_start", opt.autostart); + + #ifdef _NAMED_PIPE + tree.put("fifo.daemon_pipe", opt.daemonpipe); + tree.put("fifo.client_pipe", opt.clientpipe); + #elif _TCP_SOCKET + //TODO: ipv6 + tree.put("tcp.port_number", opt.portnumber); + tree.put("tcp.bind_address", opt.bindaddress); + #else + #error At least we need one protocol to use + #endif + pt::write_ini(config, tree); #ifdef _NAMED_PIPE @@ -58,8 +67,13 @@ void Config::Load() { //The second argument of tree.get is the default value #ifdef _NAMED_PIPE - opt.daemonpipe = Expand(tree.get("daemon_pipe", opt.daemonpipe)); - opt.clientpipe = Expand(tree.get("client_pipe", opt.clientpipe)); + opt.daemonpipe = Expand(tree.get("fifo.daemon_pipe", opt.daemonpipe)); + opt.clientpipe = Expand(tree.get("fifo.client_pipe", opt.clientpipe)); + #elif _TCP_SOCKET + opt.portnumber = tree.get("tcp.port_number", opt.portnumber); + opt.bindaddress = tree.get("tcp.bind_address", opt.bindaddress); + #else + #error At least we need one protocol to use #endif opt.pidfile = Expand(tree.get("pid_file", opt.pidfile)); opt.dbfile = Expand(tree.get("db_file", opt.dbfile)); @@ -68,13 +82,29 @@ void Config::Load() { } } -std::string Config::GetDaemonPipe() const { - return opt.daemonpipe; -} +#ifdef _NAMED_PIPE -std::string Config::GetClientPipe() const { - return opt.clientpipe; -} + std::string Config::GetDaemonPipe() const { + return opt.daemonpipe; + } + + std::string Config::GetClientPipe() const { + return opt.clientpipe; + } + +#elif _TCP_SOCKET + + unsigned Config::GetPortNumber() const { + return opt.portnumber; + } + + std::string Config::GetBindAddress() const { + return opt.bindaddress; + } + +#else +#error At least we need one protocol to use +#endif std::string Config::GetPidFile() const { return opt.pidfile; diff --git a/src/manager.cpp b/src/manager.cpp index f120b33..877a3fd 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -1,8 +1,6 @@ #include "manager.h" #include "musiclist.h" -#include -#include #include #include #include @@ -36,20 +34,9 @@ Manager::Manager() { } opid_file << getpid(); opid_file.close(); - - //Delete pipes, if exist (the program exit abnormaly) - unlink(conf.GetDaemonPipe().c_str()); - unlink(conf.GetClientPipe().c_str()); - - mkfifo(conf.GetDaemonPipe().c_str(), 0666); - mkfifo(conf.GetClientPipe().c_str(), 0666); } Manager::~Manager() { - //Delete pipes - unlink(conf.GetDaemonPipe().c_str()); - unlink(conf.GetClientPipe().c_str()); - //Remove pid file std::remove(conf.GetPidFile().c_str()); } @@ -71,6 +58,9 @@ void Manager::StartServer() { #ifdef _NAMED_PIPE static NamedPipe pipe(conf); ProcessCommand(pipe); + #elif _TCP_SOCKET + static Tcp tcp(conf); + ProcessCommand(tcp); #else #error At least we need one protocol to use #endif @@ -117,13 +107,13 @@ void Manager::ExecuteCommand(Command c, T& proto) { music.GetList().Sort(Order::RANDOM); break; case Command::GET_ARTIST: - proto << music.GetCurrent().GetArtist() << std::endl; + proto << music.GetCurrent().GetArtist(); break; case Command::GET_TITLE: - proto << music.GetCurrent().GetTitle() << std::endl; + proto << music.GetCurrent().GetTitle(); break; case Command::GET_FILE: - proto << music.GetCurrent().GetFile() << std::endl; + proto << music.GetCurrent().GetFile(); break; case Command::FILTER_ARTIST: { @@ -151,10 +141,10 @@ void Manager::ExecuteCommand(Command c, T& proto) { } break; case Command::VOLUME_GET: - proto << std::to_string(music.GetVolume()) << std::endl; + proto << std::to_string(music.GetVolume()); break; case Command::TIME_GET_REMAINING: - proto << music.GetRemainingMilliseconds() << std::endl; + proto << music.GetRemainingMilliseconds(); //case Command::SAVE_FILE: // break; From 7ca2f9b5c9a2ee014eb921c7b2b38de0bfe20593 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Sun, 26 Jun 2016 18:14:58 +0200 Subject: [PATCH 67/92] set bindaddress & misc --- include/protocol.h | 15 +++++++++------ src/config.cpp | 2 +- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/include/protocol.h b/include/protocol.h index 304a862..1c37231 100644 --- a/include/protocol.h +++ b/include/protocol.h @@ -95,15 +95,18 @@ class NamedPipe { #elif _TCP_SOCKET +//TODO: Accept multiple connections simultaneously + using boost::asio::ip::tcp; +using namespace boost::asio; class Tcp { public: Tcp(Config& c) : conf(c) { - //TODO: Setear la bindadddress - acceptor = new tcp::acceptor(io_service, tcp::endpoint(tcp::v4(), 6600)); + auto ip = ip::address_v4().from_string(conf.GetBindAddress()); + acceptor = new tcp::acceptor(io_service, tcp::endpoint(ip, 6600)); } ~Tcp() { @@ -117,12 +120,12 @@ class Tcp { acceptor->accept(*socket); char buffer[1]; - boost::asio::read(*socket, boost::asio::buffer(buffer, 1)); + read(*socket, boost::asio::buffer(buffer, 1)); return static_cast(buffer[0]); } std::string GetLine() { - auto bytes = boost::asio::read_until(*socket, buffer, '\n'); + auto bytes = read_until(*socket, buffer, '\n'); buffer.commit(bytes); std::string line; std::getline(is, line); @@ -132,7 +135,7 @@ class Tcp { template std::ostream& operator<<(const T& obj) { os << obj << std::endl; - auto bytes = boost::asio::write(*socket, buffer); + auto bytes = write(*socket, buffer); buffer.consume(bytes); return os; } @@ -150,7 +153,7 @@ class Tcp { tcp::acceptor* acceptor; tcp::socket* socket; - boost::asio::streambuf buffer; + streambuf buffer; std::istream is{&buffer}; std::ostream os{&buffer}; }; diff --git a/src/config.cpp b/src/config.cpp index 523cfde..46d5aff 100644 --- a/src/config.cpp +++ b/src/config.cpp @@ -21,7 +21,7 @@ void Config::Load() { #endif //Try to autodetect music dir - //Here we should use libxdg to parse ~/.config/user-dirs.dirs (if exists) + //TODO: We should use libxdg to parse ~/.config/user-dirs.dirs (if exists) //and get the default music dir. path default_music(Expand("~/Music/")); if(exists(default_music)) From 2519dffcb9569f243979463eae993eafc06af010 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Sun, 26 Jun 2016 21:14:37 +0200 Subject: [PATCH 68/92] fix problem with bash scripting (SIGPIPE) --- include/protocol.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/include/protocol.h b/include/protocol.h index 1c37231..4325109 100644 --- a/include/protocol.h +++ b/include/protocol.h @@ -67,11 +67,10 @@ class NamedPipe { private: void CheckClient() { + fclient.close(); + fclient.open(conf.GetClientPipe()); if(!fclient.is_open()) { - fclient.open(conf.GetClientPipe()); - if(!fclient.is_open()) { - throw std::runtime_error("Client pipe could not be opened"); - } + throw std::runtime_error("Client pipe could not be opened"); } } From afd49d23f98c2da30bb8722e06c9956d6edfa2ba Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Sun, 26 Jun 2016 21:14:57 +0200 Subject: [PATCH 69/92] misc --- README.md | 1 + src/manager.cpp | 1 + 2 files changed, 2 insertions(+) diff --git a/README.md b/README.md index 7b3bf57..2e76e0a 100644 --- a/README.md +++ b/README.md @@ -36,6 +36,7 @@ Si no existe ninguna configuración se crea una por defecto - Soporte para plugins - Ecualizador - Cache de canciones recientes (para agilizar la búsqueda) +- Soporte para carácteres raros/extranjeros. #### Clientes diff --git a/src/manager.cpp b/src/manager.cpp index 877a3fd..7ece916 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -21,6 +21,7 @@ Manager::Manager() { //Check if that pid is a real process std::ifstream f("/proc/"+pid+"/comm"); if(f.is_open()) { + //TODO: ensure that this process is our daemon and not other type of processs f.close(); throw std::runtime_error("Server is already running"); } From 3cf818d8bbac098caa7052733074c9a608bcd13e Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Sun, 26 Jun 2016 21:31:29 +0200 Subject: [PATCH 70/92] basic user documentation --- doc/USER.txt | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 99 insertions(+) create mode 100644 doc/USER.txt diff --git a/doc/USER.txt b/doc/USER.txt new file mode 100644 index 0000000..7a7a2fd --- /dev/null +++ b/doc/USER.txt @@ -0,0 +1,99 @@ +=== Compiling & Installing === + +Obviously, we need to clone and create the build directory + + git clone https://github.com/stakewinner00/cppplayer + cd cppplayer + mkdir build; cd build + +Then we have some flags we can change at compile time. +First, we have the build type, currently there are 4 build types, RELEASE, DEBUG, THREAD and ADDRESS. + +The RELEASE type enables -O3 and -flto compiler flags. +The DEBUG type enables -ggdb -Og and -DDEBUG compiler flags and enables a verbose output for debugging purpose. +The THREAD type enables the same of DEBUG type plus -fsanitize=thread for detecting data races. +The ADDRESS type enables the same of DEBUG type plus -fsanitize=address for detecting data leaks. + +Then we can define the protocols we want to use, for now there are _NAMED_PIPE and _TCP_SOCKET. + +If we wanted to compile with DEBUG build type and with _TCP_SOCKET enable and _NAMED_PIPE disabled, but with _TCP_SOCKET enabled we can execute + + cmake -DCMAKE_BUILD_TYPE=debug -D_NAMED_PIPE=Off -D_TCP_SOCKET=On .. + +Once this is done we can compile with + + make + +or if we want verbose output + + make VERBOSE=1 + +For installing we can execute + + sudo make install + +It will copy the commands.h header to /usr/include/cppplayer/commands.h and the executable to /usr/local/bin/dplayer++ + +NOTES / LIMITATIONS: Currently only of the two protocols can be used (this will change soon). + + +=== Configuration === + +All the information and related files will be located in ~/.config/player++/. The configuration file used by the daemon is called daemon.conf. +For default if the file doesn't exist, it will be created with the default values. If some value is not especified, it will use default values. + +We can write these configuration for our own, or if our music folder is located in ~/Music, let the daemon to use the default values (for default the daemon search if the ~/Music directory exists, and in that case play the music inside of the directory recursively). + +Currently the configuration file have the next options. +pid_file: Is the location of the pid file used for detecting daemons already running. Default is ~/.config/player++/player++.pid + +db_file:Is the location of the sql database, currently unused + +music_folder: Is the directory where the music is searched. Default is . or ~/Music if exists + +auto_start: A boolean that says if the status of the daemon should change from Stop to Playing automatically. Default is false + +Inside section [tcp]. + +port_number: Port number used for receiving orders and sending information to clients. Default is 6600 + +bind_address: Address used for listening connections. Default is 0.0.0.0 + +Inside section [fifo] + +daemon_pipe: Location of the pipe that the daemon uses for reading from clients. Default is: ~/.config/player++/dplayer++ + +client_pipe: Location of the pipe that the client uses for reading from daemon. Default is ~/.config/player++/cplayer++ + + +=== Running & Scripting === + +For default the player will not fork so if some error happens, it will be printed on the console. +If we want to run it as a daemon, we could add the "-d" flag. + +Once we have the daemon running, we can use some more usable clients like https://github.com/stakewinner00/cl_cppplayer for a client console or https://github.com/stakewinner00/web_cppplayer for a web client, but we can use bash too. + +If we want to use bash first we should + + source /usr/include/cppplayer/commands.h + +so we don't need to remember or search for the hexadecimal number for each command. +Supposing we are using named pipes, and the pipes are in the default location. We can: + cd ~/.config/player++ + + #pause/play the reproduction, if status=pause it will change to play, if status=play it will change to pause + echo -n $CPPPLAYER_PAUSE > ./dplayer++ + + #forward to the next song + echo -n $CPPPLAYER_NEXT > ./dplayer++ + + #get the current artist name + echo -n $CPPPLAYER_GET_ARTIST > ./dplayer++; sed q cplayer++ + + #get current volume + echo -n $CPPPLAYER_VOLUME_GET > ./dplayer++; sed q cplayer++ + + #set volume to 50 + echo -n $CPPPLAYER_VOLUME_SET"50" > ./dplayer++ + +etc, to see all supported commands you can read the /usr/include/cppplayer/commands.h header file \ No newline at end of file From 18d9a78c38a51b6e342f90a93c6419337d2a9025 Mon Sep 17 00:00:00 2001 From: David Date: Sun, 26 Jun 2016 21:36:16 +0200 Subject: [PATCH 71/92] Update README.md --- README.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/README.md b/README.md index 2e76e0a..96cb939 100644 --- a/README.md +++ b/README.md @@ -42,6 +42,9 @@ Si no existe ninguna configuración se crea una por defecto - https://github.com/stakewinner00/web_cppplayer (cliente web) - https://github.com/stakewinner00/cl_cppplayer (cliente por terminal) + +#### Documentation +- [user tutorial](doc/USER.txt) #### Colaboradores Lista de gente que ha colaborado de alguna forma con el proyecto From b25cabb32fa5578605f0ceca0edfa595e96aea18 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Tue, 28 Jun 2016 23:39:36 +0200 Subject: [PATCH 72/92] move dependencies information to doc/USER.txt --- README.md | 19 ++----------------- doc/USER.txt | 13 ++++++++++++- 2 files changed, 14 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 96cb939..f7738ec 100644 --- a/README.md +++ b/README.md @@ -4,21 +4,8 @@ Reproductor de música sencillo que busca la simplicidad y facilidad de configuración (se podría ver como alternativa a mpd) -El programa usa las librerías mpg123, sfml, TagLib, boost-filesystem y sqlite. - -#### Instalación en Debian/Ubuntu - -**# apt-get install libmpg123-dev libsfml-dev libboost-filesystem-dev libsqlite3-dev libtag1-dev** - -Para compilarlo y instalarlo -> mkdir -p build; cd build; cmake ..; make; sudo make install - -Nota: En debian stable (jessie) no hay la versión necesaria de cmake, para arreglarlo se puede pasar a debian testing, que si tiene la versión necesaria. - -#### Configuración - -El programa al iniciar lee la configuración de ~/.config/player++/daemon.conf -Si no existe ninguna configuración se crea una por defecto +#### Documentation +- [USER tutorial (compiling, installing, configuring and scripting)](doc/USER.txt) #### Features @@ -43,8 +30,6 @@ Si no existe ninguna configuración se crea una por defecto - https://github.com/stakewinner00/web_cppplayer (cliente web) - https://github.com/stakewinner00/cl_cppplayer (cliente por terminal) -#### Documentation -- [user tutorial](doc/USER.txt) #### Colaboradores Lista de gente que ha colaborado de alguna forma con el proyecto diff --git a/doc/USER.txt b/doc/USER.txt index 7a7a2fd..381c458 100644 --- a/doc/USER.txt +++ b/doc/USER.txt @@ -1,3 +1,14 @@ +=== Dependencies === + +For be able to download and compile the code we need *git* and *cmake* tools plus the next libraries: mpg123, sfml, TagLib, boost-filesystem and sqlite. +In a debian/ubuntu distro we can install it executing the next two commands + + sudo apt install git cmake + sudo apt install libmpg123-dev libsfml-dev libboost-filesystem-dev libsqlite3-dev libtag1-dev + +Important note: In stable debian (jessie) the provided cmake version is not compatible, for be able to compile the project we can use debian testing or compile the version ourselves. The minimum version is 3.1.0 + + === Compiling & Installing === Obviously, we need to clone and create the build directory @@ -96,4 +107,4 @@ Supposing we are using named pipes, and the pipes are in the default location. W #set volume to 50 echo -n $CPPPLAYER_VOLUME_SET"50" > ./dplayer++ -etc, to see all supported commands you can read the /usr/include/cppplayer/commands.h header file \ No newline at end of file +etc, to see all supported commands you can read the /usr/include/cppplayer/commands.h header file From 161915b1780165d320eea3eb61d1a145373dbbf0 Mon Sep 17 00:00:00 2001 From: isaky Date: Wed, 29 Jun 2016 03:31:14 +0200 Subject: [PATCH 73/92] Added Playlist support --- include/commands.h | 3 +++ include/musiclist.h | 2 ++ src/manager.cpp | 17 ++++++++++++++++- src/musiclist.cpp | 12 ++++++++++++ 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/include/commands.h b/include/commands.h index 69a6e80..e8896a2 100644 --- a/include/commands.h +++ b/include/commands.h @@ -58,6 +58,9 @@ typedef enum { VOLUME_GET, TIME_GET_REMAINING, + + // Placed here for keeping consistency in existing clients. Future replacement for proper code reading... + LOAD_PLAYLIST, #ifdef __cplusplus }; #else diff --git a/include/musiclist.h b/include/musiclist.h index b90dda5..ce32b9a 100644 --- a/include/musiclist.h +++ b/include/musiclist.h @@ -21,6 +21,8 @@ class MusicList { void LoadFile(const path pathSong); + void LoadPlaylist(path pathPl); + void Sort(Order s); diff --git a/src/manager.cpp b/src/manager.cpp index 7ece916..48cfb86 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -55,7 +55,6 @@ void Manager::StartServer() { while(music.GetStatus() != Status::Exit) { //TODO: Allow to use more than one protocol simultaneously - #ifdef _NAMED_PIPE static NamedPipe pipe(conf); ProcessCommand(pipe); @@ -131,6 +130,22 @@ void Manager::ExecuteCommand(Command c, T& proto) { case Command::ADD_FILE: music.GetList().LoadFile(proto.GetLine()); break; + case Command::LOAD_PLAYLIST: + { + auto tmp = music.GetStatus(); + // TODO: These checks are because the player breaks when setting to the same status + if(tmp != Status::Stoped) { + music.SetStatus(Status::Stoped); + } + + // For the moment works passing the full path of the PlayList + music.GetList().LoadPlaylist(proto.GetLine()); + + if(tmp != music.GetStatus()) { + music.SetStatus(tmp); + } + } + break; case Command::VOLUME_SET: { std::string volum; diff --git a/src/musiclist.cpp b/src/musiclist.cpp index c6b373e..4e2979b 100644 --- a/src/musiclist.cpp +++ b/src/musiclist.cpp @@ -28,6 +28,18 @@ void MusicList::LoadFile(const path pathSong) { } } +void MusicList::LoadPlaylist(path pathPl) { + std::ifstream pl(pathPl.string()); + if(pl.is_open()) { + song_list.clear(); + + for(std::string l; std::getline(pl, l);) { + LoadFile(*(new path(l))); // This is clean safe code ??? + } + } + pl.close(); +} + void MusicList::Sort(Order s) { switch(s) { case Order::RANDOM: From 337a49dfcd8e6061dd462a06efddc8398c11449a Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Wed, 29 Jun 2016 20:03:51 +0200 Subject: [PATCH 74/92] minor fix --- include/musiclist.h | 2 +- src/musiclist.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/include/musiclist.h b/include/musiclist.h index ce32b9a..f52cd8b 100644 --- a/include/musiclist.h +++ b/include/musiclist.h @@ -21,7 +21,7 @@ class MusicList { void LoadFile(const path pathSong); - void LoadPlaylist(path pathPl); + void LoadPlaylist(std::string pathPl); void Sort(Order s); diff --git a/src/musiclist.cpp b/src/musiclist.cpp index 4e2979b..807546a 100644 --- a/src/musiclist.cpp +++ b/src/musiclist.cpp @@ -28,8 +28,8 @@ void MusicList::LoadFile(const path pathSong) { } } -void MusicList::LoadPlaylist(path pathPl) { - std::ifstream pl(pathPl.string()); +void MusicList::LoadPlaylist(std::string pathPl) { + std::ifstream pl(pathPl); if(pl.is_open()) { song_list.clear(); From 0b7c698f5c25512dd4c5191227f076517d7f88b0 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Wed, 29 Jun 2016 20:12:38 +0200 Subject: [PATCH 75/92] fix. --- src/musiclist.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/musiclist.cpp b/src/musiclist.cpp index 807546a..f3d7f34 100644 --- a/src/musiclist.cpp +++ b/src/musiclist.cpp @@ -4,6 +4,7 @@ #include #include #include +#include //Public functions From f58f487ec56eba7ed45d6e37c93542c60d69d3bf Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Wed, 29 Jun 2016 23:32:09 +0200 Subject: [PATCH 76/92] fix bug --- src/manager.cpp | 10 ++-------- src/music.cpp | 3 +++ 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/src/manager.cpp b/src/manager.cpp index 48cfb86..da0b01c 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -133,17 +133,11 @@ void Manager::ExecuteCommand(Command c, T& proto) { case Command::LOAD_PLAYLIST: { auto tmp = music.GetStatus(); - // TODO: These checks are because the player breaks when setting to the same status - if(tmp != Status::Stoped) { - music.SetStatus(Status::Stoped); - } + music.SetStatus(Status::Stoped); // For the moment works passing the full path of the PlayList music.GetList().LoadPlaylist(proto.GetLine()); - - if(tmp != music.GetStatus()) { - music.SetStatus(tmp); - } + music.SetStatus(tmp); } break; case Command::VOLUME_SET: diff --git a/src/music.cpp b/src/music.cpp index 506af48..32cf866 100644 --- a/src/music.cpp +++ b/src/music.cpp @@ -43,6 +43,9 @@ Status Music::GetStatus() const { } void Music::SetStatus(Status s) { + //Fix bug: when setting two times the same status it stops reading + if(status == s) return; + //Wait the previous status to be processed mymutex.wait(); From 7303b0d6caecd89d7e6293cbc35ba3e4a25c6c49 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Fri, 1 Jul 2016 12:49:56 +0200 Subject: [PATCH 77/92] fix cmake bug --- CMakeLists.txt | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index bfbf803..22f46a7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -48,7 +48,7 @@ set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -pedantic") #RELEASE set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3 -flto") -set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -flto") +set(CMAKE_EXE_LINKER_FLAGS_RELEASE "${CMAKE_EXE_LINKER_FLAGS} -flto") #DEBUG set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -ggdb -Og -DDEBUG") @@ -59,5 +59,5 @@ set(CMAKE_EXE_LINKER_FLAGS_THREAD "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=thread") #ADDRESS SANITIZER set(CMAKE_CXX_FLAGS_ADDRESS "${CMAKE_CXX_FLAGS_ADDRESS} -fsanitize=address -DDEBUG -Og -ggdb") -set(CMAKE_EXE_LINKER_FLAGS_THREAD "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address") +set(CMAKE_EXE_LINKER_FLAGS_ADDRESS "${CMAKE_EXE_LINKER_FLAGS} -fsanitize=address") From 3f541ec1e0b09d33a816bc813742525768f35fd3 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Sat, 2 Jul 2016 00:53:25 +0200 Subject: [PATCH 78/92] . --- src/manager.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/manager.cpp b/src/manager.cpp index da0b01c..861d7bb 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -4,6 +4,7 @@ #include #include #include +#include //Public functions From 719e4a77c964fb7d492c1380fc750f90fad5c508 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Sat, 2 Jul 2016 01:44:32 +0200 Subject: [PATCH 79/92] fix data race when getting current song --- include/music.h | 14 ++++++++++++++ src/manager.cpp | 11 +++++++++-- src/music.cpp | 14 +++++++++++--- 3 files changed, 34 insertions(+), 5 deletions(-) diff --git a/include/music.h b/include/music.h index cc972c1..6f096ab 100644 --- a/include/music.h +++ b/include/music.h @@ -61,6 +61,20 @@ class Music { Status GetStatus() const; void SetStatus(Status s); + /* XXX: Probably there are better ways to avoid this data race + * + * When changing the status, there are a lapse. + * Some commands like GET_ARTIST can return the + * content of the previous song, so we must provide + * some mecanism to wait while the status are in this lapse. + * + * This function waits the status "s" to be done. + * + * This function should be called after SetStatus in case that + * we want to ensure that the status is changed. + */ + void WaitStatus(Status s); + void SetVolume(float v); float GetVolume(); diff --git a/src/manager.cpp b/src/manager.cpp index 861d7bb..8cc7e00 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -88,21 +88,28 @@ void Manager::ExecuteCommand(Command c, T& proto) { break; case Command::PLAY: music.SetStatus(Status::Playing); + music.WaitStatus(Status::Playing); break; case Command::PAUSE: - if(music.GetStatus() != Status::Playing) + if(music.GetStatus() != Status::Playing) { music.SetStatus(Status::Playing); - else + music.WaitStatus(Status::Playing); + } else { music.SetStatus(Status::Paused); + music.WaitStatus(Status::Paused); + } break; case Command::STOP: music.SetStatus(Status::Stoped); + music.WaitStatus(Status::Stoped); break; case Command::NEXT: music.SetStatus(Status::Forwarding); + music.WaitStatus(Status::Forwarding); break; case Command::BACK: music.SetStatus(Status::Backing); + music.WaitStatus(Status::Backing); break; case Command::SORT_RANDOM: music.GetList().Sort(Order::RANDOM); diff --git a/src/music.cpp b/src/music.cpp index 32cf866..79175c0 100644 --- a/src/music.cpp +++ b/src/music.cpp @@ -1,9 +1,11 @@ #include #include #include +#include #include "music.h" + //Public functions void Music::PlayList() { @@ -43,11 +45,11 @@ Status Music::GetStatus() const { } void Music::SetStatus(Status s) { - //Fix bug: when setting two times the same status it stops reading - if(status == s) return; - //Wait the previous status to be processed mymutex.wait(); + + //Fix bug: when setting two times the same status it stops reading + if(status == s) return; status = s; @@ -86,6 +88,12 @@ MusicList& Music::GetList() { return list; } +void Music::WaitStatus(Status s) { + std::mutex cv_m; + std::unique_lock lk{cv_m}; + cv.wait(lk, [this, s]{return IsNotStatus(s);}); +} + Song& Music::GetCurrent() { return song; } From 14768a889e502d6190ca2796aad0ddbf71836968 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Sat, 2 Jul 2016 02:01:36 +0200 Subject: [PATCH 80/92] fix bug --- src/manager.cpp | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/manager.cpp b/src/manager.cpp index 8cc7e00..002a40c 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -93,10 +93,8 @@ void Manager::ExecuteCommand(Command c, T& proto) { case Command::PAUSE: if(music.GetStatus() != Status::Playing) { music.SetStatus(Status::Playing); - music.WaitStatus(Status::Playing); } else { music.SetStatus(Status::Paused); - music.WaitStatus(Status::Paused); } break; case Command::STOP: From d040a4671181f34e2ad8af1c2cf3d35d7aa1043e Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Sat, 2 Jul 2016 10:47:54 +0200 Subject: [PATCH 81/92] . --- include/protocol.h | 20 +++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/include/protocol.h b/include/protocol.h index 4325109..17d68f8 100644 --- a/include/protocol.h +++ b/include/protocol.h @@ -53,7 +53,17 @@ class NamedPipe { template std::ostream& operator<<(const T& obj) { - CheckClient(); + if(!fclient.is_open()) { + fclient.open(conf.GetClientPipe()); + if(!fclient.is_open()) { + throw std::runtime_error("Client pipe could not be opened"); + } + } + + if(!fclient.good()) { + throw std::runtime_error("Client is bad state"); + } + fclient << obj << std::endl; return fclient; } @@ -66,14 +76,6 @@ class NamedPipe { } private: - void CheckClient() { - fclient.close(); - fclient.open(conf.GetClientPipe()); - if(!fclient.is_open()) { - throw std::runtime_error("Client pipe could not be opened"); - } - } - void CheckDaemon() { //XXX: Workaround if(fdaemon.peek() == -1) fdaemon.ignore(); From f9a579da0c7f70e66c4b46092e40fd25b0cd96fe Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Sat, 2 Jul 2016 10:59:20 +0200 Subject: [PATCH 82/92] . --- include/protocol.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/protocol.h b/include/protocol.h index 17d68f8..fca2478 100644 --- a/include/protocol.h +++ b/include/protocol.h @@ -80,13 +80,13 @@ class NamedPipe { //XXX: Workaround if(fdaemon.peek() == -1) fdaemon.ignore(); - if(!fdaemon.good() || !fdaemon.is_open()) { + //if(!fdaemon.good() || !fdaemon.is_open()) { fdaemon.close(); fdaemon.open(conf.GetDaemonPipe()); if(!fdaemon.is_open()) { throw std::runtime_error("Daemon pipe could not be opened"); } - } + //} } Config& conf; From 2807aad3b677e8a263a20d889bf34556aec646cb Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Sat, 2 Jul 2016 11:13:24 +0200 Subject: [PATCH 83/92] reopen before writing. --- include/protocol.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/include/protocol.h b/include/protocol.h index fca2478..af94107 100644 --- a/include/protocol.h +++ b/include/protocol.h @@ -80,13 +80,13 @@ class NamedPipe { //XXX: Workaround if(fdaemon.peek() == -1) fdaemon.ignore(); - //if(!fdaemon.good() || !fdaemon.is_open()) { + if(!fdaemon.good() || fdaemon.is_open()) fdaemon.close(); - fdaemon.open(conf.GetDaemonPipe()); - if(!fdaemon.is_open()) { - throw std::runtime_error("Daemon pipe could not be opened"); - } - //} + + fdaemon.open(conf.GetDaemonPipe()); + if(!fdaemon.is_open()) { + throw std::runtime_error("Daemon pipe could not be opened"); + } } Config& conf; From ba04d9835f63aeffb61375c267a8fa8f0fbb414b Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Sat, 2 Jul 2016 11:18:07 +0200 Subject: [PATCH 84/92] check errors --- include/protocol.h | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/include/protocol.h b/include/protocol.h index af94107..9d8e350 100644 --- a/include/protocol.h +++ b/include/protocol.h @@ -3,6 +3,7 @@ #include "commands.h" #include "config.h" +#include #include #include #include @@ -26,17 +27,23 @@ class NamedPipe { : conf(c) { //Delete pipes, if exist (the program exit abnormaly) - unlink(conf.GetDaemonPipe().c_str()); - unlink(conf.GetClientPipe().c_str()); - - mkfifo(conf.GetDaemonPipe().c_str(), 0666); - mkfifo(conf.GetClientPipe().c_str(), 0666); + if(unlink(conf.GetDaemonPipe().c_str()) == -1) + throw std::runtime_error(strerror(errno)); + if(unlink(conf.GetClientPipe().c_str()) == -1) + throw std::runtime_error(strerror(errno)); + + if(mkfifo(conf.GetDaemonPipe().c_str(), 0666) == -1) + throw std::runtime_error(strerror(errno)); + if(mkfifo(conf.GetClientPipe().c_str(), 0666) == -1) + throw std::runtime_error(strerror(errno)); } ~NamedPipe() { //Delete pipes - unlink(conf.GetDaemonPipe().c_str()); - unlink(conf.GetClientPipe().c_str()); + if(unlink(conf.GetDaemonPipe().c_str()) == -1) + throw std::runtime_error(strerror(errno)); + if(unlink(conf.GetClientPipe().c_str()) == -1) + throw std::runtime_error(strerror(errno)); } Command ReadCommand() { From ae6a1d229e394139c89e92aba9b47ab0bfe74246 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Sat, 2 Jul 2016 15:53:31 +0200 Subject: [PATCH 85/92] test travis notifications --- .travis.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.travis.yml b/.travis.yml index c81d1bc..ab75d81 100644 --- a/.travis.yml +++ b/.travis.yml @@ -29,3 +29,8 @@ script: - mkdir build - cd build - cmake -DCMAKE_CXX_COMPILER=$COMPILER .. && make VERBOSE=1 + +notifications: + irc: "mumei.space#entry-point" + on_success: always + on_failure: always From 00b94a3f93af5866854b0af616e55178eda5825d Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Sat, 2 Jul 2016 17:22:56 +0200 Subject: [PATCH 86/92] revert 719e4a77c964fb7d492c1380fc750f90fad5c508 --- include/music.h | 14 -------------- src/manager.cpp | 4 ---- src/music.cpp | 6 ------ 3 files changed, 24 deletions(-) diff --git a/include/music.h b/include/music.h index 6f096ab..cc972c1 100644 --- a/include/music.h +++ b/include/music.h @@ -61,20 +61,6 @@ class Music { Status GetStatus() const; void SetStatus(Status s); - /* XXX: Probably there are better ways to avoid this data race - * - * When changing the status, there are a lapse. - * Some commands like GET_ARTIST can return the - * content of the previous song, so we must provide - * some mecanism to wait while the status are in this lapse. - * - * This function waits the status "s" to be done. - * - * This function should be called after SetStatus in case that - * we want to ensure that the status is changed. - */ - void WaitStatus(Status s); - void SetVolume(float v); float GetVolume(); diff --git a/src/manager.cpp b/src/manager.cpp index 002a40c..79c99f9 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -88,7 +88,6 @@ void Manager::ExecuteCommand(Command c, T& proto) { break; case Command::PLAY: music.SetStatus(Status::Playing); - music.WaitStatus(Status::Playing); break; case Command::PAUSE: if(music.GetStatus() != Status::Playing) { @@ -99,15 +98,12 @@ void Manager::ExecuteCommand(Command c, T& proto) { break; case Command::STOP: music.SetStatus(Status::Stoped); - music.WaitStatus(Status::Stoped); break; case Command::NEXT: music.SetStatus(Status::Forwarding); - music.WaitStatus(Status::Forwarding); break; case Command::BACK: music.SetStatus(Status::Backing); - music.WaitStatus(Status::Backing); break; case Command::SORT_RANDOM: music.GetList().Sort(Order::RANDOM); diff --git a/src/music.cpp b/src/music.cpp index 79175c0..add34f6 100644 --- a/src/music.cpp +++ b/src/music.cpp @@ -88,12 +88,6 @@ MusicList& Music::GetList() { return list; } -void Music::WaitStatus(Status s) { - std::mutex cv_m; - std::unique_lock lk{cv_m}; - cv.wait(lk, [this, s]{return IsNotStatus(s);}); -} - Song& Music::GetCurrent() { return song; } From 4caf2d47593817aca817c13acbb4f6645cda5c45 Mon Sep 17 00:00:00 2001 From: stakewinner00 Date: Sun, 3 Jul 2016 02:09:31 +0200 Subject: [PATCH 87/92] fix data races --- include/music.h | 27 ++------------------------- include/protocol.h | 31 ++++++++++++++----------------- src/music.cpp | 20 +++++++++++++++----- 3 files changed, 31 insertions(+), 47 deletions(-) diff --git a/include/music.h b/include/music.h index cc972c1..9228692 100644 --- a/include/music.h +++ b/include/music.h @@ -26,30 +26,6 @@ enum class Status { }; -class MyMutex { -public: - inline void notify() - { - std::unique_lock lock(mtx); - count = 1; - cv.notify_one(); - } - - inline void wait() - { - std::unique_lock lock(mtx); - - cv.wait(lock, [this]{return count>0;}); - - count--; - } - -private: - std::mutex mtx; - std::condition_variable cv; - int count {1}; -}; - class Music { public: void PlayList(); @@ -84,7 +60,8 @@ class Music { sf::Music music; sfe::mp3 mp3music; - MyMutex mymutex; + std::atomic status_processed {true}; std::condition_variable cv; + std::condition_variable status_cv; }; \ No newline at end of file diff --git a/include/protocol.h b/include/protocol.h index 9d8e350..83fdc0d 100644 --- a/include/protocol.h +++ b/include/protocol.h @@ -60,17 +60,7 @@ class NamedPipe { template std::ostream& operator<<(const T& obj) { - if(!fclient.is_open()) { - fclient.open(conf.GetClientPipe()); - if(!fclient.is_open()) { - throw std::runtime_error("Client pipe could not be opened"); - } - } - - if(!fclient.good()) { - throw std::runtime_error("Client is bad state"); - } - + CheckClient(); fclient << obj << std::endl; return fclient; } @@ -83,16 +73,24 @@ class NamedPipe { } private: + void CheckClient() { + fclient.close(); + fclient.open(conf.GetClientPipe()); + if(!fclient.is_open()) { + throw std::runtime_error("Client pipe could not be opened"); + } + } + void CheckDaemon() { //XXX: Workaround if(fdaemon.peek() == -1) fdaemon.ignore(); - if(!fdaemon.good() || fdaemon.is_open()) + if(!fdaemon.good() || !fdaemon.is_open()) { fdaemon.close(); - - fdaemon.open(conf.GetDaemonPipe()); - if(!fdaemon.is_open()) { - throw std::runtime_error("Daemon pipe could not be opened"); + fdaemon.open(conf.GetDaemonPipe()); + if(!fdaemon.is_open()) { + throw std::runtime_error("Daemon pipe could not be opened"); + } } } @@ -100,7 +98,6 @@ class NamedPipe { std::ofstream fclient; std::ifstream fdaemon; }; - #elif _TCP_SOCKET //TODO: Accept multiple connections simultaneously diff --git a/src/music.cpp b/src/music.cpp index add34f6..89297f3 100644 --- a/src/music.cpp +++ b/src/music.cpp @@ -45,12 +45,16 @@ Status Music::GetStatus() const { } void Music::SetStatus(Status s) { - //Wait the previous status to be processed - mymutex.wait(); - + //Wait previous status to be processed + std::mutex cv_m; + std::unique_lock lk{cv_m}; + status_cv.wait(lk, [this]{return status_processed.load();}); + //Fix bug: when setting two times the same status it stops reading if(status == s) return; + status_processed = false; + status = s; cv.notify_one(); @@ -74,13 +78,19 @@ int Music::GetRemainingMilliseconds() { bool Music::IsStatus(Status s) { bool tmp = GetStatus()==s; - if(tmp) mymutex.notify(); + if(tmp) { + status_processed = true; + status_cv.notify_one(); + } return tmp; } bool Music::IsNotStatus(Status s) { bool tmp = GetStatus()!=s; - if(tmp) mymutex.notify(); + if(tmp) { + status_processed = true; + status_cv.notify_one(); + } return tmp; } From 5aeded99f2156c7d4d63654950b188023b56b112 Mon Sep 17 00:00:00 2001 From: tryger Date: Mon, 4 Jul 2016 01:06:13 +0200 Subject: [PATCH 88/92] Set Offset (not working on mp3) --- include/commands.h | 2 ++ include/music.h | 2 ++ src/manager.cpp | 4 ++++ src/music.cpp | 7 +++++++ 4 files changed, 15 insertions(+) diff --git a/include/commands.h b/include/commands.h index e8896a2..2ddb793 100644 --- a/include/commands.h +++ b/include/commands.h @@ -61,6 +61,8 @@ typedef enum { // Placed here for keeping consistency in existing clients. Future replacement for proper code reading... LOAD_PLAYLIST, + + SET_OFFSET, #ifdef __cplusplus }; #else diff --git a/include/music.h b/include/music.h index 9228692..d6e0d74 100644 --- a/include/music.h +++ b/include/music.h @@ -42,6 +42,8 @@ class Music { int GetRemainingMilliseconds(); + void SetPlayingOffset(int ms); + MusicList& GetList(); Song& GetCurrent(); private: diff --git a/src/manager.cpp b/src/manager.cpp index 79c99f9..892d85a 100644 --- a/src/manager.cpp +++ b/src/manager.cpp @@ -157,6 +157,10 @@ void Manager::ExecuteCommand(Command c, T& proto) { break; case Command::TIME_GET_REMAINING: proto << music.GetRemainingMilliseconds(); + break; + case Command::SET_OFFSET: + music.SetPlayingOffset(std::stoi(proto.GetLine())); + break; //case Command::SAVE_FILE: // break; diff --git a/src/music.cpp b/src/music.cpp index 89297f3..fb46667 100644 --- a/src/music.cpp +++ b/src/music.cpp @@ -76,6 +76,13 @@ int Music::GetRemainingMilliseconds() { + (mp3music.getDuration().asMilliseconds() - mp3music.getPlayingOffset().asMilliseconds()); } +void Music::SetPlayingOffset(int ms) { + // ms: Millisecond in the song to move the current offset + std::cout << ms << std::endl; + music.setPlayingOffset(sf::milliseconds(ms)); + mp3music.setPlayingOffset(sf::milliseconds(ms)); +} + bool Music::IsStatus(Status s) { bool tmp = GetStatus()==s; if(tmp) { From 96e3d5638781b9507a5d99037818af4f977c29b2 Mon Sep 17 00:00:00 2001 From: tryger Date: Tue, 5 Jul 2016 02:02:04 +0200 Subject: [PATCH 89/92] Change offset --- include/mp3.h | 4 ++++ src/mp3.cpp | 14 +++++++++++++- src/music.cpp | 14 ++++++++++++-- 3 files changed, 29 insertions(+), 3 deletions(-) diff --git a/include/mp3.h b/include/mp3.h index 18dd3f0..c89b0ce 100644 --- a/include/mp3.h +++ b/include/mp3.h @@ -12,6 +12,10 @@ public : ~mp3(); sf::Time getDuration() const; + + void setPlayingOffset(sf::Time timeOffset); + sf::Time getPlayingOffset(); + bool openFromFile(const std::string& filename); protected : diff --git a/src/mp3.cpp b/src/mp3.cpp index b25d229..eb7dabe 100644 --- a/src/mp3.cpp +++ b/src/mp3.cpp @@ -43,6 +43,18 @@ sf::Time mp3::getDuration() const{ return myDuration; } +sf::Time mp3::getPlayingOffset() +{ + return sf::seconds(mpg123_tellframe(myHandle) * mpg123_tpf(myHandle)); +} + +void mp3::setPlayingOffset(sf::Time timeOffset) +{ + + onSeek(timeOffset); + //m_samplesProcessed = static_cast(timeOffset.asSeconds() * getSampleRate() * getChannelCount()); +} + bool mp3::openFromFile(const std::string& filename) { stop(); @@ -119,7 +131,7 @@ void mp3::onSeek(sf::Time timeOffset) sf::Lock lock(myMutex); if (myHandle) - mpg123_seek(myHandle, timeOffset.asSeconds(), 0); + mpg123_seek_frame(myHandle, mpg123_timeframe(myHandle, timeOffset.asSeconds()), SEEK_SET); } } // namespace sfe diff --git a/src/music.cpp b/src/music.cpp index fb46667..28d4bac 100644 --- a/src/music.cpp +++ b/src/music.cpp @@ -78,9 +78,18 @@ int Music::GetRemainingMilliseconds() { void Music::SetPlayingOffset(int ms) { // ms: Millisecond in the song to move the current offset - std::cout << ms << std::endl; + + auto duration = music.getDuration().asMilliseconds() + mp3music.getDuration().asMilliseconds(); + + if(ms > duration) + ms = duration; + + SetStatus(Status::Paused); + music.setPlayingOffset(sf::milliseconds(ms)); mp3music.setPlayingOffset(sf::milliseconds(ms)); + + SetStatus(Status::Playing); } bool Music::IsStatus(Status s) { @@ -139,7 +148,7 @@ void Music::Reproduce(T& music, const char* song) { loop = false; //Calculate how many milliseconds we have to sleep for finish the song - auto offset = music.getPlayingOffset().asMilliseconds(); + auto offset = mp3music.getPlayingOffset().asMilliseconds(); auto sleep_time = duration - offset; if(sleep_time < 0) { @@ -161,6 +170,7 @@ void Music::Reproduce(T& music, const char* song) { loop = true; } else if(IsStatus(Status::Restart)) { music.setPlayingOffset(sf::seconds(0)); + mp3music.setPlayingOffset(sf::seconds(0)); status = Status::Playing; } } From e47b3b61ed5b4787d29cbf232efe36a8e55b67e4 Mon Sep 17 00:00:00 2001 From: tryger Date: Wed, 6 Jul 2016 01:10:32 +0200 Subject: [PATCH 90/92] Simplify setting offset --- include/mp3.h | 4 ++-- src/mp3.cpp | 4 ++-- src/music.cpp | 3 ++- 3 files changed, 6 insertions(+), 5 deletions(-) diff --git a/include/mp3.h b/include/mp3.h index c89b0ce..82aaf65 100644 --- a/include/mp3.h +++ b/include/mp3.h @@ -13,8 +13,8 @@ public : sf::Time getDuration() const; - void setPlayingOffset(sf::Time timeOffset); - sf::Time getPlayingOffset(); + //void setPlayingOffset(sf::Time timeOffset); + //sf::Time getPlayingOffset(); bool openFromFile(const std::string& filename); diff --git a/src/mp3.cpp b/src/mp3.cpp index eb7dabe..140903a 100644 --- a/src/mp3.cpp +++ b/src/mp3.cpp @@ -43,7 +43,7 @@ sf::Time mp3::getDuration() const{ return myDuration; } -sf::Time mp3::getPlayingOffset() +/*sf::Time mp3::getPlayingOffset() { return sf::seconds(mpg123_tellframe(myHandle) * mpg123_tpf(myHandle)); } @@ -53,7 +53,7 @@ void mp3::setPlayingOffset(sf::Time timeOffset) onSeek(timeOffset); //m_samplesProcessed = static_cast(timeOffset.asSeconds() * getSampleRate() * getChannelCount()); -} +}*/ bool mp3::openFromFile(const std::string& filename) { diff --git a/src/music.cpp b/src/music.cpp index 28d4bac..5d9c01a 100644 --- a/src/music.cpp +++ b/src/music.cpp @@ -84,11 +84,12 @@ void Music::SetPlayingOffset(int ms) { if(ms > duration) ms = duration; - SetStatus(Status::Paused); + music.setPlayingOffset(sf::milliseconds(ms)); mp3music.setPlayingOffset(sf::milliseconds(ms)); + SetStatus(Status::Paused); SetStatus(Status::Playing); } From 3ceefe32c2a73f4ac1640f651f9387298afa8ac5 Mon Sep 17 00:00:00 2001 From: tryger Date: Wed, 6 Jul 2016 01:23:50 +0200 Subject: [PATCH 91/92] mp3music not correct --- src/music.cpp | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/music.cpp b/src/music.cpp index 5d9c01a..6acb390 100644 --- a/src/music.cpp +++ b/src/music.cpp @@ -72,7 +72,7 @@ float Music::GetVolume() { } int Music::GetRemainingMilliseconds() { - return (music.getDuration().asMilliseconds() - music.getPlayingOffset().asMilliseconds()) + return (music.getDuration().asMilliseconds() - music.getPlayingOffset().asMilliseconds()) + (mp3music.getDuration().asMilliseconds() - mp3music.getPlayingOffset().asMilliseconds()); } @@ -84,11 +84,10 @@ void Music::SetPlayingOffset(int ms) { if(ms > duration) ms = duration; - - music.setPlayingOffset(sf::milliseconds(ms)); mp3music.setPlayingOffset(sf::milliseconds(ms)); + // This is to update the sleep_time SetStatus(Status::Paused); SetStatus(Status::Playing); } @@ -149,7 +148,7 @@ void Music::Reproduce(T& music, const char* song) { loop = false; //Calculate how many milliseconds we have to sleep for finish the song - auto offset = mp3music.getPlayingOffset().asMilliseconds(); + auto offset = music.getPlayingOffset().asMilliseconds(); auto sleep_time = duration - offset; if(sleep_time < 0) { @@ -171,7 +170,6 @@ void Music::Reproduce(T& music, const char* song) { loop = true; } else if(IsStatus(Status::Restart)) { music.setPlayingOffset(sf::seconds(0)); - mp3music.setPlayingOffset(sf::seconds(0)); status = Status::Playing; } } From 541355b20bfc10f3b049877ba268cdc0d2548929 Mon Sep 17 00:00:00 2001 From: tryger Date: Wed, 6 Jul 2016 01:31:18 +0200 Subject: [PATCH 92/92] . --- include/mp3.h | 3 --- src/mp3.cpp | 12 ------------ 2 files changed, 15 deletions(-) diff --git a/include/mp3.h b/include/mp3.h index 82aaf65..2d4ea0a 100644 --- a/include/mp3.h +++ b/include/mp3.h @@ -12,9 +12,6 @@ public : ~mp3(); sf::Time getDuration() const; - - //void setPlayingOffset(sf::Time timeOffset); - //sf::Time getPlayingOffset(); bool openFromFile(const std::string& filename); diff --git a/src/mp3.cpp b/src/mp3.cpp index 140903a..7705e07 100644 --- a/src/mp3.cpp +++ b/src/mp3.cpp @@ -43,18 +43,6 @@ sf::Time mp3::getDuration() const{ return myDuration; } -/*sf::Time mp3::getPlayingOffset() -{ - return sf::seconds(mpg123_tellframe(myHandle) * mpg123_tpf(myHandle)); -} - -void mp3::setPlayingOffset(sf::Time timeOffset) -{ - - onSeek(timeOffset); - //m_samplesProcessed = static_cast(timeOffset.asSeconds() * getSampleRate() * getChannelCount()); -}*/ - bool mp3::openFromFile(const std::string& filename) { stop();