Welcome, Guest. Please login or register. Did you miss your activation email?

Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.


Messages - Thrusty

Pages: [1] 2
1
Audio / Re: How to make main thread wait for SoundRecorder to finish
« on: January 22, 2018, 04:18:45 pm »
My current version of MinGW doesn't support futures or promises, so I am using atomic temporarily. I tried a new way of waiting for the audio thread to finish, and I found that returning false from onProccessSamples() somehow causes onStop() not to be called. Am I missing something? By always returning true from onProccessSamples(), I can manually call stop() from the main thread and have onStop() get called.

#include <atomic>
#include <iostream>
#include <SFML/Audio.hpp>

struct CustomRecorder : sf::SoundRecorder
{
    CustomRecorder() { }

    ~CustomRecorder() { stop(); }

    void waitJoin() const
    {
        while (signalJoin() == false) wait();
    }

    void waitStop() const
    {
        while (signalStop() == false) wait();
    }

private:
    bool onProcessSamples(const int16_t* samples,
                          const size_t sampleCount)
    {
        if (signalStop() == false)
        {
            std::cout << "CustomRecorder::onProcessSamples() [samples:" << sampleCount << "]" << std::endl;
            count += sampleCount;

            if (count >= 22050) atomicStop.store(1, std::memory_order_relaxed);
        }
        else
        {
            std::cout << "CustomRecorder::onProcessSamples() [in flight before stop()]" << std::endl;
        }

        return true;
    }

    bool onStart()
    {
        std::cout << "CustomRecorder::onStart();" << std::endl;
        atomicJoin.store(0, std::memory_order_relaxed);
        atomicStop.store(0, std::memory_order_relaxed);
        return true;
    }

    void onStop()
    {
        std::cout << "CustomRecorder::onStop();" << std::endl;
        atomicJoin.store(1, std::memory_order_relaxed);
    }

    bool signalJoin() const
    {
        return atomicJoin.load(std::memory_order_relaxed);
    }

    bool signalStop() const
    {
        return atomicStop.load(std::memory_order_relaxed);
    }

    void wait() const
    {
        sf::sleep(sf::milliseconds(15));
    }

    size_t               count    = 0;
    std::atomic<int32_t> atomicJoin;
    std::atomic<int32_t> atomicStop;
};

int main()
{
    std::cout << "starting audio capture" << std::endl;
    CustomRecorder r;
    r.start();
    r.waitStop();
    r.stop();
    r.waitJoin();
    return 0;
}

2
Audio / How to make main thread wait for SoundRecorder to finish
« on: January 21, 2018, 12:53:21 pm »
What would be a good way to make the main thread wait for the audio thread to finish?

In the following code I use sf::sleep to wait to make sure that the audio thread has actually finished its work, but I'm not really happy with this solution because it precludes me from instantiating a temporary CRecorder in a function.

#include <atomic>
#include <iostream>
#include <SFML/Audio.hpp>

struct CRecorder : sf::SoundRecorder
{
    CRecorder() { }

    ~CRecorder() { stop(); }

    bool onProcessSamples(const int16_t* samples, const size_t sampleCount)
    {
        std::cout << "CustomRecorder::onProcessSamples() [samples:" << sampleCount << ", done: ";
        std::cout << finished.load(std::memory_order_relaxed) << "]" << std::endl;
 
        if (finished.load(std::memory_order_relaxed) == 1) { return false; }

        // collect samples
        count += sampleCount;

        // return false when 22050 or more have been collected, otherwise return true
        if (count >= 22050)
        {
            // tell the main thread to stop waiting
            finished.store(1, std::memory_order_relaxed);

            // note that onProcessSamples may be called again (sometimes) even though we return false
            return false;
        }

        return true;
    }

    bool onStart()
    {
        std::cout << "CustomRecorder::onStart();" << std::endl;
        finished.store(0, std::memory_order_relaxed);
        setProcessingInterval(sf::milliseconds(25));
        return true;
    }

    void onStop()
    {
        std::cout << "CustomRecorder::onStop();" << std::endl;
    }

    size_t count = 0;
    std::atomic<int32_t> finished;
};

int main()
{
    CRecorder r;
    std::cout << "starting audio capture" << std::endl;
    r.start();

    while (r.finished.load(std::memory_order_relaxed) == 0)
    {
        sf::sleep(sf::milliseconds(25));
    }

    // guard against the "pure virtual method called" exception (might not be totally foolproof)
    //sf::sleep(sf::milliseconds(1000));

    return 0;
}

3
General / Re: Using SFML with a memory pool
« on: November 05, 2017, 10:15:47 am »
Sure thing...I noticed a deque being used there. What's the rationale behind this choice of container?


4
General / Re: Using SFML with a memory pool
« on: November 04, 2017, 05:15:17 pm »
I've noticed that when moving the mouse inside the Window (main Window from RenderWindow), SFML is calling new and delete repeatedly. Is it keeping a log of the events, or are they just happening so quick that it needs a bigger structure to hold them all? Or is this allocation not related to an array, but a series of individual dynamically allocated objects that are needed whenever an event is generated?

Max block size in my app is 2 mib; nothing larger can be allocated, as I don't need anything that big.

5
General / Re: Using SFML with a memory pool
« on: November 02, 2017, 09:45:32 am »
eXpl0it3r, I'll answer your question about why I want to use my own pool shortly. For now, could you answer another question for me?

I think my question number 3 was a bit pointless because obviously I would put checks in my Editor to make sure the user doesn't load in 2000x2000 sized Images.

So, what happens when Image requests too much memory and the request fails? On my side (in the pool), it just returns null, or throws an exception (for the placement version of new). But how does sf::Image, for example, deal with this? I've heard SFML doesn't use exceptions. LoadFromFile returns false, but what happens internally if new returns null (for a request bigger than 2 mib)?

This is what the overloaded new and delete looks like:

#include <new>
#include "../Pool/Pool.hpp"

void* operator new(std::size_t s)
{
    return memory::pool::allocate_b_4096(s, 0, 0);
}

void* operator new[](std::size_t s)
{
    return memory::pool::allocate_b_4096(s, 0, 0);
}

void* operator new(std::size_t s, const std::nothrow_t&)
{
    return memory::pool::allocate_b_4096_noexcept(s, 0, 0);
}

void* operator new[](std::size_t s, const std::nothrow_t&)
{
    return memory::pool::allocate_b_4096_noexcept(s, 0, 0);
}

void operator delete(void* p) noexcept
{
    if (p) { memory::pool::free(p); }
}

void operator delete[](void* p) noexcept
{
    if (p) { memory::pool::free(p); }
}

6
General / Using SFML with a memory pool
« on: November 02, 2017, 08:15:04 am »
I'm using a custom memory pool and allocators in my app, and I would like to get SFML to work with this system if possible.

There are a few things I need to check before I proceed with the attempt:

1. Using SFML's Dynamic  Link Libraries will not be possible, but will there be legal problems when using a statically compiled SFML in my commercial app?

2. Does SFML use new and delete in any of its types that dynamically allocate memory (types such as sf::Text, sf::String, sf::Texture, sf::RenderWindow, etc), or does it use malloc directly anywhere?

3. What is the largest chunk of memory that would realistically be allocated (I don't mean in cases where the user stupidly allocates memory for, say, a million characters in a sf::String, but just in the normal cases)? (the max block size, in my pool, is 2 megabytes)

7
Very well. I'm now sending the re-size event after recreating the window. I don't seem to need a view change either. Though I'll test that out on linux, at some point.

void Sys::menuDisplaySettings(System& rS)
{
    sf::Event event;
    Sys::SubWindow w(350, 500, rS);
    w.setPositionAuto();
    w.setTitle("Display Settings");
    w.enableVertDiv();
    menuDisplaySettingsResetElements(w.yBegin+30, w.xBegin+6, rS);
    int counter = 0;

    for (;;)
    {
        int resize = 0;
        int width = 0;
        int height = 0;

        while (rS.win->pollEvent(event))
        {
            if (event.type == sf::Event::MouseMoved ||
                event.type == sf::Event::MouseButtonPressed ||
                event.type == sf::Event::MouseButtonReleased)
            {
                rS.win->handleEvent(event);
            }

            else if (event.type == sf::Event::Closed) return;

            else if (event.type == sf::Event::Resized)
            {
                if (event.size.width != width || event.size.height != height)
                {
                    resize = 1;
                    width = event.size.width;
                    height = event.size.height;
                }
            }
        }

        if (resize)
        {
            rS.win->removeAllObjects();
            rS.win->create(sf::VideoMode(width, height, 32), "SFML Window");
            //rS.win->setView(sf::View(sf::FloatRect(0, 0, width, height)));

            rS.win->handleEvent(event);

            rS.winPixelWidth = width;
            rS.winPixelHeight = height;
            w.setPositionAuto();
            menuDisplaySettingsResetElements(w.yBegin+30, w.xBegin+6, rS);
        }

        rS.win->clear();
        rS.displayTiles();
        rS.displayUI();
        w.displayWindow();
        rS.win->drawGUI();
        rS.win->display();
    }
}

For the linux release, I'll have to disallow manual window resizing, and let the user specify a window size in the window settings menu.

8
Re-size events are only generated while the user is holding down the mouse button and dragging the window to re-size it. Once he releases the button, cout no longer generates any re-size messages.

            else if (event.type == sf::Event::Resized)
            {
                ++counter;
                std::cout << "Resizes: " << counter << "\n";
                if (event.size.width != width && event.size.height != height)
                {
                    resize = 1;
                    width = event.size.width;
                    height = event.size.height;

                    // rS.win->handleEvent(event);
                }
            }

Does the resize event really need to be given to tgui *after* the view has been changed?

9
So here's my new updated code:

The line with the "//" at the beginning is the line that causes the coordinate problem when I reactivate that bit of code. Why would not telling tgui about the re-size event, solve the problem? Well at least appear to.

void Sys::menuDisplaySettings(System& rS)
{
    sf::Event event;
    Sys::SubWindow w(350, 500, rS);
    w.setPositionAuto();
    w.setTitle("Display Settings");
    w.enableVertDiv();
    menuDisplaySettingsResetElements(w.yBegin+30, w.xBegin+6, rS);

    for (;;)
    {
        int resize = 0;
        int width = 0;
        int height = 0;

        while (rS.win->pollEvent(event))
        {
            if (event.type == sf::Event::MouseMoved)
            {
                sf::Vector2i position_i = sf::Mouse::getPosition(*rS.win);
                sf::Vector2f position_f = rS.win->convertCoords(position_i);

                sf::Event etmp;
                etmp.type = sf::Event::MouseMoved;
                etmp.mouseMove.x = position_f.x;
                etmp.mouseMove.y = position_f.y;

                rS.win->handleEvent(etmp);
            }

            else if (event.type == sf::Event::MouseButtonPressed || event.type == sf::Event::MouseButtonReleased)
            {
                rS.win->handleEvent(event);
            }

            else if (event.type == sf::Event::Closed) return;

            else if (event.type == sf::Event::Resized)
            {
                if (event.size.width != width && event.size.height != height)
                {
                    resize = 1;
                    width = event.size.width;
                    height = event.size.height;

                    // rS.win->handleEvent(event);
                }
            }
        }

        if (resize)
        {
            rS.win->removeAllObjects();
            rS.win->create(sf::VideoMode(width, height, 32), "SFML Window");
            rS.winPixelWidth = width;
            rS.winPixelHeight = height;
            w.setPositionAuto();
            menuDisplaySettingsResetElements(w.yBegin+30, w.xBegin+6, rS);
        }

        rS.win->clear();
        rS.displayTiles();
        rS.displayUI();
        w.displayWindow();
        rS.win->drawGUI();
        rS.win->display();
    }
}

10
This is the code I had before using the hack:

    for ( ; ; )
    {
        int resize = 0;
        int width = 0;
        int height = 0;

        while (rS.win->pollEvent(event))
        {
            rS.win->handleEvent(event);

            if (event.type == sf::Event::Closed) return;

            if (event.type == sf::Event::Resized)
            {
                resize = 1;
                width = event.size.width;
                height = event.size.height;
            }
        }

        if (resize)
        {
            rS.win->removeAllObjects();

            rS.win->create(sf::VideoMode(width, height, 32), "SFML Window");

            rS.winPixelWidth = width;
            rS.winPixelHeight = height;

            w.setPositionAuto();

            menuDisplaySettingsResetElements(w.yBegin+30, w.xBegin+6, rS);
        }

        rS.win->clear();
        rS.displayTiles();
        rS.displayUI();
        w.displayWindow();
        rS.win->drawGUI();
        rS.win->display();
    }

The event was passed into tgui regardless of what type it was. Why were you getting an infinite lop on linux, anyway? That doesn't happen on my system. We need to investigate this.

tgui must keep a record of the last mouse position after a mousemove event, since I didn't need to convert the button press events, only the mousemove events.

11
So I managed to solve the problem with a dodgy hack:

        while (rS.win->pollEvent(event))
        {
            if (event.type == sf::Event::MouseMoved)
            {
                sf::Vector2i position_i = sf::Mouse::getPosition(*rS.win);
                sf::Vector2f position_f = rS.win->convertCoords(position_i);

                sf::Event etmp;
                etmp.type = sf::Event::MouseMoved;
                etmp.mouseMove.x = position_f.x;
                etmp.mouseMove.y = position_f.y;

                rS.win->handleEvent(etmp);
            }

            if (event.type == sf::Event::MouseButtonPressed || event.type == sf::Event::MouseButtonReleased)
            {
                rS.win->handleEvent(event);
            }

            if (event.type == sf::Event::Closed) return;

            if (event.type == sf::Event::Resized)
            {
                resize = 1;
                width = event.size.width;
                height = event.size.height;
            }
        }
 

I wish there were a way to do this without creating my own event instantiation and passing it into the UI elements, though.

12
Window / Incorrect window mouse coords generated after window resize event.
« on: December 01, 2012, 05:02:52 pm »
I'm experiencing a problem with window mouse coords when resizing the window. Everything works fine until the window is re-sized, at which point the coords being generated appear to be based on the original window size, not the new one*. I do not change the standard view when resizing, I just update everything accordingly, including the UI elements within the window.

*Actually what really seems to be happening is that the new window size coords are converted back to the view from the old window size, such that when the Mousemoved event is passed into my UI elements, they get a messed up coord.

I hope I'm explaining this problem well.

Please help. Thanks.


#include <sstream>

#include <TGUI/TGUI.hpp>

#include "../rgm_system/system.h"
#include "../rgm_ui/ui.h"
#include "../rgm_ui/ui_window.h"

void menuDisplaySettingsResetElements(int y, int x, Sys::System& rS)
{
    tgui::Window& window = *rS.win;

    tgui::Label* label1 = window.addLabel();
    label1->setText("Fullscreen Enabled");
    label1->setTextSize(18);
    label1->setTextColor(sf::Color::Black);
    label1->setPosition(x, y+24*1);

    tgui::Checkbox* checkbox1 = window.addCheckbox("display_settings_fullscreen_mode");
    checkbox1->load("TGUI/objects/Checkbox/Black");
    checkbox1->setText("");
    checkbox1->setPosition(x+250-36, y+24*1);
    checkbox1->setSize(24.0, 24.0);

    tgui::Label* label2 = window.addLabel();
    label2->setText("Scale to Fit");
    label2->setTextSize(18);
    label2->setTextColor(sf::Color::Black);
    label2->setPosition(x, y+24*3);

    tgui::Checkbox* checkbox2 = window.addCheckbox("display_settings_scale_to_fit");
    checkbox2->load("TGUI/objects/Checkbox/Black");
    checkbox2->setText("");
    checkbox2->setPosition(x+250-36, y+24*3);
    checkbox2->setSize(24.0, 24.0);

    tgui::Label* label3 = window.addLabel();
    label3->setText("Tile Smoothing");
    label3->setTextSize(18);
    label3->setTextColor(sf::Color::Black);
    label3->setPosition(x, y+24*5);

    tgui::Checkbox* checkbox3 = window.addCheckbox("display_settings_tile_smoothing");
    checkbox3->load("TGUI/objects/Checkbox/Black");
    checkbox3->setText("");
    checkbox3->setPosition(x+250-36, y+24*5);
    checkbox3->setSize(24.0, 24.0);

    tgui::Label* label4 = window.addLabel();
    label4->setText("Framerate Limit");
    label4->setTextSize(18);
    label4->setTextColor(sf::Color::Black);
    label4->setPosition(x, y+24*7);

    tgui::EditBox* editBox1 = window.addEditBox();
    editBox1->load("TGUI/objects/EditBox/Black");
    editBox1->setTextSize(18);
    editBox1->setBorders(6, 4, 6, 4);
    editBox1->setPosition(x+250-112, y+24*7);
    editBox1->setText("60");
    editBox1->setSize(100, 24);

    tgui::Label* label5 = window.addLabel();
    label5->setText("Fullscreen Mode");
    label5->setTextSize(18);
    label5->setTextColor(sf::Color::Black);
    label5->setPosition(x+250, y+24*1);

    tgui::Label* label6 = window.addLabel();
    label6->setText("Window Height");
    label6->setTextSize(18);
    label6->setTextColor(sf::Color::Black);
    label6->setPosition(x, y+24*9);

    tgui::EditBox* editBox2 = window.addEditBox();
    editBox2->load("TGUI/objects/EditBox/Black");
    editBox2->setTextSize(18);
    editBox2->setBorders(6, 4, 6, 4);
    editBox2->setPosition(x+250-12-100, y+24*9);
    editBox2->setText("600");
    editBox2->setSize(100, 24);

    tgui::Label* label7 = window.addLabel();
    label7->setText("Window Width");
    label7->setTextSize(18);
    label7->setTextColor(sf::Color::Black);
    label7->setPosition(x+250, y+24*9);

    tgui::EditBox* editBox3 = window.addEditBox();
    editBox3->load("TGUI/objects/EditBox/Black");
    editBox3->setTextSize(18);
    editBox3->setBorders(6, 4, 6, 4);
    editBox3->setPosition(x+500-12-100, y+24*9);
    editBox3->setText("1024");
    editBox3->setSize(100, 24);



    tgui::Listbox* listbox = window.addListbox();
    listbox->load(125, 144, "TGUI/objects/Scrollbar/Black", 20);
    listbox->setBorders(2, 2, 2, 2);
    listbox->setPosition(x+500-12-125, y+24*1);

    std::vector<sf::VideoMode> modes = sf::VideoMode::getFullscreenModes();

    for (auto it : modes)
    {
        if (it.bitsPerPixel == 32 && it.width >= 854 && it.height >= 480)
        {
            std::stringstream ss;

            ss << it.width << " x " << it.height;

            listbox->addItem(ss.str());
        }
    }

    listbox->changeColors(rS.guiInst.barDDdivideColour,
                          sf::Color::White,
                          rS.guiInst.barHighlightColour,
                          sf::Color::White);



    tgui::Button* button1 = window.addButton();
    button1->load("TGUI/objects/Button/Black");
    button1->setTextSize(18);
    button1->setText("OK");
    button1->setSize(100.0, 24.0);
    button1->setPosition(x, y+24*12);

    tgui::Button* button2 = window.addButton();
    button2->load("TGUI/objects/Button/Black");
    button2->setTextSize(18);
    button2->setText("Cancel");
    button2->setSize(100.0, 24.0);
    button2->setPosition(x+106, y+24*12);
}

void Sys::menuDisplaySettings(System& rS)
{
    sf::Event event;

    Sys::SubWindow w(350, 500, rS);
    w.setPositionAuto();
    w.setTitle("Display Settings");
    w.enableVertDiv();

    menuDisplaySettingsResetElements(w.yBegin+30, w.xBegin+6, rS);

    int windowHeight = 600;
    int windowWidth = 1024;
    int fsHeight = 600;
    int fsWidth = 1024;
    int fullscreen = 0;
    int scaleToFit = 0;
    int smoothTiles = 0;
    int frameRateLimit = 60;

    for ( ; ; )
    {
        int resize = 0;
        int width = 0;
        int height = 0;

        while (rS.win->pollEvent(event))
        {
            rS.win->handleEvent(event);

            if (event.type == sf::Event::Closed) return;

            if (event.type == sf::Event::Resized)
            {
                resize = 1;
                width = event.size.width;
                height = event.size.height;
            }
        }

        if (resize)
        {
            rS.win->removeAllObjects();

            rS.win->create(sf::VideoMode(width, height, 32), "SFML Window");

            rS.winPixelWidth = width;
            rS.winPixelHeight = height;

            w.setPositionAuto();

            menuDisplaySettingsResetElements(w.yBegin+30, w.xBegin+6, rS);
        }

        rS.win->clear();
        rS.displayTiles();
        rS.displayUI();
        w.displayWindow();
        rS.win->drawGUI();
        rS.win->display();
    }
}

13
Window / Event sample rate
« on: June 28, 2011, 10:20:50 am »
Efficiency problem? I don't mean to be rude, but my program was using 4% or less of CPU. Now, I don't even understand the code any more, since you have changed it. But thanks anyway.

Having run the program, don't you seem something wrong with the behaviour?

14
Window / Event sample rate
« on: April 02, 2011, 03:40:57 pm »
In terms of events, how often is the mouse move position collected?

I want to collect all the mouse move events while they're coming in, but sleep when there are no longer any events.

I'm wondering if I've done something wrong:

Code: [Select]
#include <SFML/Graphics.hpp>

sf::RenderWindow* win_ptr = 0;

int main()
{
    win_ptr = new sf::RenderWindow(sf::VideoMode(1024, 600, 32), "SFML");

    sf::Clock Clock;
    sf::Event event;
    sf::Color black(0, 0, 0);
    sf::Color white(255, 255, 255);
    sf::Image Image1(1024, 600, black);
    sf::Sprite Sprite;
    Sprite.SetImage(Image1);

    bool sleep = false;
    float counter = 0;
    float begin = 0;

    win_ptr->Clear();
    win_ptr->Display();

    while (win_ptr->IsOpened())
    {
        begin = Clock.GetElapsedTime();

        if (win_ptr->GetEvent(event))
        {
            switch (event.Type)
            {
                case (sf::Event::Closed): goto end;
                case (sf::Event::MouseMoved): Image1.SetPixel(event.MouseMove.X, event.MouseMove.Y, white); break;
            }
        }
        else
            sf::Sleep(0.01f);

        if (counter > .029f)
        {
            counter = 0;
            win_ptr->Clear();
            win_ptr->Draw(Sprite);
            win_ptr->Display();
        }

        counter += Clock.GetElapsedTime() - begin;
    }

    end:

    win_ptr->Close();
    return EXIT_SUCCESS;
}

15
Window / Re: App freezes when maximizing window
« on: March 31, 2011, 05:29:33 pm »
Never mind. Fixed it by using my own timing method:

Code: [Select]
   while (win_ptr->IsOpened())
    {
        begin = Clock.GetElapsedTime();

        //input

        if (counter > .029f)
        {
            counter = 0;
            win_ptr->Clear();
            win_ptr->Draw(Sprite);
            win_ptr->Display();
        }

        counter += Clock.GetElapsedTime() - begin;
    }

Pages: [1] 2
anything