New Sleep implementation, and some minor fixes.

This commit is contained in:
Martín Lucas Golini
2013-11-01 23:31:12 -03:00
parent 7eeea19d75
commit 87cec40bf7
11 changed files with 123 additions and 103 deletions

View File

@@ -431,7 +431,7 @@ else
ifeq ($(BUILD_OS), mingw32)
LIBS = -lOpenAL32 -lopengl32 -lmingw32 -lglu32 -lgdi32 -lws2_32 -static-libgcc -static-libstdc++ -mwindows $(LIBSNDFILE) $(SDL_BACKEND_LINK) $(SDL2_BACKEND_LINK) $(SFML_BACKEND_LINK) $(LIBFREETYPE2)
LIBS = -lOpenAL32 -lopengl32 -lmingw32 -lglu32 -lgdi32 -lws2_32 -lwinmm -static-libgcc -static-libstdc++ -mwindows $(LIBSNDFILE) $(SDL_BACKEND_LINK) $(SDL2_BACKEND_LINK) $(SFML_BACKEND_LINK) $(LIBFREETYPE2)
OTHERINC += $(INCFREETYPE2)
PLATFORMSRC = $(wildcard ./src/eepp/window/platform/win/*.cpp) $(wildcard ./src/eepp/system/platform/win/*.cpp) $(wildcard ./src/eepp/network/platform/win/*.cpp)
@@ -440,7 +440,7 @@ else
#if it is cygwin
ifneq (,$(findstring cygwin,$(BUILD_OS)))
LIBS = -lOpenAL32 -lmingw32 -lopengl32 -lglu32 -lgdi32 -lws2_32 -static-libgcc -mwindows $(LIBSNDFILE) $(SDL_BACKEND_LINK) $(SDL2_BACKEND_LINK) $(SFML_BACKEND_LINK) $(LIBFREETYPE2)
LIBS = -lOpenAL32 -lmingw32 -lopengl32 -lglu32 -lgdi32 -lws2_32 -lwinmm -static-libgcc -mwindows $(LIBSNDFILE) $(SDL_BACKEND_LINK) $(SDL2_BACKEND_LINK) $(SFML_BACKEND_LINK) $(LIBFREETYPE2)
OTHERINC += -I./src/eepp/helper/zlib $(INCFREETYPE2)
PLATFORMSRC = $(wildcard ./src/eepp/window/platform/win/*.cpp) $(wildcard ./src/eepp/system/platform/win/*.cpp) $(wildcard ./src/eepp/network/platform/win/*.cpp)

View File

@@ -55,7 +55,7 @@ class EE_API cSoundBuffer {
unsigned int mBuffer; ///< OpenAL buffer identifier
std::vector<Int16> mSamples; ///< Samples buffer
float mDuration; ///< Sound duration, in seconds
cTime mDuration; ///< Sound duration, in seconds
typedef std::set<cSound*> SoundList;
mutable SoundList mSounds;

View File

@@ -31,6 +31,7 @@
#define EE_STRING_HPP
#include <eepp/declares.hpp>
#include <eepp/base/utf.hpp>
#include <locale>
#include <string>
#include <cstring>
@@ -249,6 +250,42 @@ class EE_API String {
**/
String( const String& str );
/** @brief Create a new String from a UTF-8 encoded string
** @param begin Forward iterator to the begining of the UTF-8 sequence
** @param end Forward iterator to the end of the UTF-8 sequence
** @return A String containing the source string
** @see FromUtf16, FromUtf32 */
template <typename T>
static String FromUtf8(T begin, T end) {
String string;
Utf8::ToUtf32(begin, end, std::back_inserter(string.mString));
return string;
}
/** @brief Create a new String from a UTF-16 encoded string
** @param begin Forward iterator to the begining of the UTF-16 sequence
** @param end Forward iterator to the end of the UTF-16 sequence
** @return A String containing the source string
** @see FromUtf8, FromUtf32 */
template <typename T>
static String FromUtf16(T begin, T end) {
String string;
Utf16::ToUtf32(begin, end, std::back_inserter(string.mString));
return string;
}
/** @brief Create a new String from a UTF-32 encoded string
** @param begin Forward iterator to the begining of the UTF-32 sequence
** @param end Forward iterator to the end of the UTF-32 sequence
** @return A String containing the source string
** @see FromUtf8, FromUtf32 */
template <typename T>
static String FromUtf32(T begin, T end) {
String string;
Utf32::ToUtf32(begin, end, std::back_inserter(string.mString));
return string;
}
/** @brief Implicit cast operator to std::string (ANSI string)
** The current global locale is used for conversion. If you
** want to explicitely specify a locale, see ToAnsiString.

View File

@@ -196,6 +196,12 @@ class EE_API cHttp : NonCopyable {
** @param data Content of the response to parse */
void Parse(const std::string& data);
/** @brief Read values passed in the answer header
** This function is used by Http to extract values passed
** in the response.
** @param in String stream containing the header values */
void ParseFields(std::istream &in);
// Types
typedef std::map<std::string, std::string> FieldTable;

View File

@@ -301,9 +301,9 @@ function generate_os_links()
table.insert( os_links, "dl" )
end
elseif os.is_real("windows") then
multiple_insert( os_links, { "OpenAL32", "opengl32", "glu32", "gdi32", "ws2_32" } )
multiple_insert( os_links, { "OpenAL32", "opengl32", "glu32", "gdi32", "ws2_32", "winmm" } )
elseif os.is_real("mingw32") then
multiple_insert( os_links, { "OpenAL32", "opengl32", "glu32", "gdi32", "ws2_32" } )
multiple_insert( os_links, { "OpenAL32", "opengl32", "glu32", "gdi32", "ws2_32", "winmm" } )
elseif os.is_real("macosx") then
multiple_insert( os_links, { "OpenGL.framework", "OpenAL.framework", "CoreFoundation.framework", "AGL.framework" } )
elseif os.is_real("freebsd") then

View File

@@ -10,7 +10,7 @@ namespace EE { namespace Audio {
cSoundBuffer::cSoundBuffer() :
mBuffer(0),
mDuration(0.f)
mDuration()
{
EnsureALInit();
@@ -183,7 +183,7 @@ unsigned int cSoundBuffer::GetChannelCount() const {
}
cTime cSoundBuffer::GetDuration() const {
return Seconds( mDuration );
return mDuration;
}
cSoundBuffer& cSoundBuffer::operator =( const cSoundBuffer& Other ) {
@@ -216,7 +216,7 @@ bool cSoundBuffer::Update( unsigned int ChannelCount, unsigned int SampleRate )
ALCheck( alBufferData( mBuffer, Format, &mSamples[0], Size, SampleRate ) );
// Compute the duration
mDuration = (float)mSamples.size() / (float)SampleRate / (float)ChannelCount;
mDuration = Seconds(static_cast<float>(mSamples.size()) / SampleRate / ChannelCount);
return true;
}

View File

@@ -12,11 +12,6 @@ namespace {
*i = static_cast<char>(std::tolower(*i));
return str;
}
template<class InputIterator, class Size, class OutputIterator> OutputIterator copy_n(InputIterator in, Size n, OutputIterator out) {
for (Size i = 0; i < n; *out = *in, i++, ++out, ++in);
return out;
}
}
namespace EE { namespace Network {
@@ -158,9 +153,42 @@ void cHttp::Response::Parse(const std::string& data) {
}
// Ignore the end of the first line
in.ignore(10000, '\n');
in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// Parse the other lines, which contain fields, one by one
ParseFields(in);
// Finally extract the body
mBody.clear();
// Determine whether the transfer is chunked
if (toLower(GetField("transfer-encoding")) != "chunked") {
// Not chunked - everything at once
std::copy(std::istreambuf_iterator<char>(in), std::istreambuf_iterator<char>(), std::back_inserter(mBody));
} else {
// Chunked - have to read chunk by chunk
std::size_t length;
// Read all chunks, identified by a chunk-size not being 0
while (in >> std::hex >> length) {
// Drop the rest of the line (chunk-extension)
in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// Copy the actual content data
std::istreambuf_iterator<char> it(in);
for (std::size_t i = 0; i < length; i++)
mBody.push_back(*it++);
}
// Drop the rest of the line (chunk-extension)
in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// Read all trailers (if present)
ParseFields(in);
}
}
void cHttp::Response::ParseFields(std::istream &in) {
std::string line;
while (std::getline(in, line) && (line.size() > 2)) {
std::string::size_type pos = line.find(": ");
@@ -178,48 +206,6 @@ void cHttp::Response::Parse(const std::string& data) {
mFields[toLower(field)] = value;
}
}
// Finally extract the body
mBody.clear();
// Determine whether the transfer is chunked
if (toLower(GetField("transfer-encoding")).compare("chunked")) {
// Not chunked - everything at once
std::copy(std::istreambuf_iterator<char>(in), std::istreambuf_iterator<char>(), std::back_inserter(mBody));
} else {
// Chunked - have to read chunk by chunk
unsigned long length;
// Read all chunks, identified by a chunk-size not being 0
while (in >> std::hex >> length) {
// Drop the rest of the line (chunk-extension)
in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// Copy the actual content data
::copy_n(std::istreambuf_iterator<char>(in), length, std::back_inserter(mBody));
}
// Drop the rest of the line (chunk-extension)
in.ignore(std::numeric_limits<std::streamsize>::max(), '\n');
// Read all trailers (if present)
while (std::getline(in, line) && (line.size() > 2)) {
std::string::size_type pos = line.find(": ");
if (pos != std::string::npos) {
// Extract the field name and its value
std::string field = line.substr(0, pos);
std::string value = line.substr(pos + 2);
// Remove any trailing \r
if (!value.empty() && (*value.rbegin() == '\r'))
value.erase(value.size() - 1);
// Add the field
mFields[toLower(field)] = value;
}
}
}
}
cHttp::cHttp() :

View File

@@ -94,7 +94,7 @@ cIpAddress cIpAddress::GetLocalAddress() {
return localAddress;
// Connect the socket to localhost on any port
sockaddr_in address = Private::cSocketImpl::CreateAddress(ntohl(INADDR_LOOPBACK), 0);
sockaddr_in address = Private::cSocketImpl::CreateAddress(ntohl(INADDR_LOOPBACK), 9);
if (connect(sock, reinterpret_cast<sockaddr*>(&address), sizeof(address)) == -1) {
Private::cSocketImpl::Close(sock);
return localAddress;

View File

@@ -10,11 +10,15 @@ namespace EE { namespace Network { namespace Private {
sockaddr_in cSocketImpl::CreateAddress(Uint32 address, unsigned short port) {
sockaddr_in addr;
std::memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
std::memset(&addr, 0, sizeof(addr));
addr.sin_addr.s_addr = htonl(address);
addr.sin_family = AF_INET;
addr.sin_family = AF_INET;
addr.sin_port = htons(port);
#if EE_PLATFORM == EE_PLATFORM_MACOSX || EE_PLATFORM == EE_PLATFORM_IOS
addr.sin_len = sizeof(addr);
#endif
return addr;
}

View File

@@ -7,7 +7,7 @@ namespace EE { namespace Network { namespace Private {
sockaddr_in cSocketImpl::CreateAddress(Uint32 address, unsigned short port) {
sockaddr_in addr;
std::memset(addr.sin_zero, 0, sizeof(addr.sin_zero));
std::memset(&addr, 0, sizeof(addr));
addr.sin_addr.s_addr = htonl(address);
addr.sin_family = AF_INET;
addr.sin_port = htons(port);

View File

@@ -4,6 +4,7 @@
#include <cstdlib>
#include <climits>
#include <ctype.h>
#include <cerrno>
// This taints the System module!
#if EE_PLATFORM == EE_PLATFORM_ANDROID
@@ -311,52 +312,38 @@ Uint32 Sys::GetTicks() {
}
void Sys::Sleep( const Uint32& ms ) {
#if EE_PLATFORM == EE_PLATFORM_WIN
::Sleep( ms );
#elif defined( EE_PLATFORM_POSIX )
// usleep( static_cast<unsigned long>( ms * 1000 ) );
// usleep is not reliable enough (it might block the
// whole process instead of just the current thread)
// so we must use pthread_cond_timedwait instead
// this implementation is inspired from Qt
// and taken from SFML
Uint64 usecs = ms * 1000;
// get the current time
timeval tv;
gettimeofday(&tv, NULL);
// construct the time limit (current time + time to wait)
timespec ti;
ti.tv_nsec = (tv.tv_usec + (usecs % 1000000)) * 1000;
ti.tv_sec = tv.tv_sec + (usecs / 1000000) + (ti.tv_nsec / 1000000000);
ti.tv_nsec %= 1000000000;
// create a mutex and thread condition
pthread_mutex_t mutex;
pthread_mutex_init(&mutex, 0);
pthread_cond_t condition;
pthread_cond_init(&condition, 0);
// wait...
pthread_mutex_lock(&mutex);
pthread_cond_timedwait(&condition, &mutex, &ti);
pthread_mutex_unlock(&mutex);
// destroy the mutex and condition
pthread_cond_destroy(&condition);
pthread_mutex_destroy(&mutex);
#else
#warning Sys::Sleep not implemented in this platform.
#endif
Sleep( Milliseconds( ms ) );
}
void Sys::Sleep( const cTime& time ) {
Sleep( (Uint32)time.AsMilliseconds() );
#if EE_PLATFORM == EE_PLATFORM_WIN
TIMECAPS tc;
timeGetDevCaps(&tc, sizeof(TIMECAPS));
timeBeginPeriod(tc.wPeriodMin);
::Sleep( time.AsMilliseconds() );
timeEndPeriod(tc.wPeriodMin);
#elif defined( EE_PLATFORM_POSIX )
Uint64 usecs = time.AsMicroseconds();
// Construct the time to wait
timespec ti;
ti.tv_nsec = (usecs % 1000000) * 1000;
ti.tv_sec = usecs / 1000000;
// Wait...
// If nanosleep returns -1, we check errno. If it is EINTR
// nanosleep was interrupted and has set ti to the remaining
// duration. We continue sleeping until the complete duration
// has passed. We stop sleeping if it was due to an error.
while ((nanosleep(&ti, &ti) == -1) && (errno == EINTR))
{
}
#else
#warning Sys::Sleep not implemented in this platform.
#endif
}
static std::string sGetProcessPath() {