Jump to content

use_count() in smart_ptr<Window> increments with each input event


Lupin
 Share

Go to solution Solved by Josh,

Recommended Posts

 

The reference counter in smart_ptr<Window> increments with each input event, e.g. mouse movement, key presses, etc.
Seems like, it stops after reaching the number of 1005 references (the program continues to work normally).
This doesn't seem to be a problem, but it may be a sign that there is an small bug somewhere?

You can check this by adding inside the render loop:

window->SetText(WString(window.use_count()));

Latest dev build, checked on Debug and Release.
I didn't notice anything similar with other objects.

 

  • Upvote 1
Link to comment
Share on other sites

The window is getting stored as the event source in all those events that are being added to the event queue. Each time an event is removed from the queue by calling WaitEvent, that number will go down.

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

It's still at least 5 counts after FlushEvents(); I'm not sure if it's related but old window still open after creating a new window even if i use a window->Close();

It was working for me in a beta several months ago even without Close().

#include "UltraEngine.h"

using namespace UltraEngine;

int main(int argc, const char* argv[])
{
    //Get the displays
    auto displays = GetDisplays();

    //Create a window
    auto window = CreateWindow("Ultra Engine", 0, 0, 1280, 720, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR);

    //Create a world
    auto world = CreateWorld();

    //Create a framebuffer
    auto framebuffer = CreateFramebuffer(window);

    //Create a camera
    auto camera = CreateCamera(world);
    camera->SetClearColor(0.125);

    //Main loop
    while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false)
    {
        if (window->KeyDown(KEY_SPACE))
        {
          FlushEvents();
        }
        if (window->KeyDown(KEY_C))
        {
            window->Close();
        }
        if (window->KeyDown(KEY_E))
        {
            window->Close();
            window = CreateWindow("Quake Tactics", 0, 0, 720, 480,
                GetDisplays()[0], WINDOW_TITLEBAR | WINDOW_CENTER);
            framebuffer = CreateFramebuffer(window);
        }
        window->SetText(WString(window.use_count()));
        world->Update();
        world->Render(framebuffer);
    }
    return 0;
}

 

Link to comment
Share on other sites

 

Tahnks for replies.
After reading, I realized that instead of describe the problem, I wrote an observation, that I (mistakenly) thought explained the source of the problem.

A potential bug, as correctly described Dreikblack, is that:
Once a window has been created, it cannot be physically closed other than by completely terminating the program.

I think this is a minor, low priority thing, but could be looked into at some point. Or maybe there is a workaround?

#include "UltraEngine.h"
#include <iostream>
#include <chrono>
#include <thread>

using namespace UltraEngine;

void RunTestProc() {
    auto window = CreateWindow("Ultra Engine", 0, 0, 800, 600, GetDisplays()[0], WINDOW_CENTER | WINDOW_TITLEBAR);
    auto world = CreateWorld();
    auto framebuffer = CreateFramebuffer(window);
    auto camera = CreateCamera(world, PROJECTION_ORTHOGRAPHIC);
    while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false) { world->Update(); world->Render(framebuffer); }
    window->FlushKeys(); window->FlushMouse();
    FlushEvents();
    std::cout << "before exit func window.use_count = " << window.use_count() << std::endl;
}

int main(int argc, const char* argv[])
{
    RunTestProc();
   
    // theoretically there are no user object references left at this point, so the window should be closed ?
    // but it is still open, although non - functional.

    std::this_thread::sleep_for(std::chrono::milliseconds(1000)); // just to be sure...
    Print("\nCan you still see the window?\n");
    system("pause");
    return 0;
}

It seems to me that some resources are not being deleted, even though all user-created references have gone out of scope.
Perhaps they are what keep the window alive?

Quote

Loading shader family "Shaders/PBR.fam"
Loading shader family "Shaders/Sky.fam"
Loading shader family "Shaders/Unlit.fam"
Loading posteffect "Shaders/Refraction.fx"
Loading shader module "Shaders/BlurX.frag.spv"
Loading shader module "Shaders/BlurY.frag.spv"
before exit func window.use_count = 4
Deleting shader family "Shaders/Sky.fam"

Can you still see the window?

Press any key to continue...
Deleting shader family "Shaders/Unlit.fam"

 

 

  • Thanks 1
Link to comment
Share on other sites

  • 2 weeks later...

The simplest case seems to work correctly:

#include "UltraEngine.h"

using namespace UltraEngine;

int main(int argc, const char* argv[])
{
    //Get the displays
    auto displays = GetDisplays();

    //Create a window
    auto window = CreateWindow("Ultra Engine", 0, 0, 1280, 720, displays[0], WINDOW_CENTER | WINDOW_TITLEBAR);

    Print(uint64_t(window.use_count()));

    FlushEvents();
     
    Print(uint64_t(window.use_count()));

    return 0;
}

Prints:

3
1

 

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

@Lupin In your example above the window gets sent to the rendering thread, which will keep it in memory until a different window is sent to replace it.

This example is a variation of @Dreikblack and it shows that the last window is somehow remaining in memory. It always keeps two windows open, but removes the earlier one when I create a new one:

#include "UltraEngine.h"

using namespace UltraEngine;

int main(int argc, const char* argv[])
{
    int n = 0;

    //Get the displays
    auto displays = GetDisplays();

    //Create a window
    auto window = CreateWindow(String(n), 0, 0, 800, 600, displays[0], WINDOW_TITLEBAR);

    //Create a world
    auto world = CreateWorld();

    //Create a framebuffer
    auto framebuffer = CreateFramebuffer(window);

    //Create a camera
    auto camera = CreateCamera(world);
    camera->SetClearColor(0.125);

    //Main loop
    while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false)
    {
        if (window->KeyDown(KEY_E))
        {
            FlushEvents();
            ++n;
            window = CreateWindow(String(n), window->position.x + 50, window->position.y + 50, window->size.x, window->size.y, window->display, window->style);
            framebuffer = CreateFramebuffer(window);
        }
        //window->SetText(WString(window.use_count()));
        world->Update();
        world->Render(framebuffer);
    }
    return 0;
}

 

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

  • Solution

Okay, here is a working example that proves the window and framebuffer reference counting are working correctly. Note you must call PeekEvent / WaitEvent or FlushEvents to clear the event queue each frame. It is also necessary to call World::Render if you create a framebuffer, because otherwise the rendering command buffer never gets cleared and it keeps the old framebuffer in memory.

#include "UltraEngine.h"

using namespace UltraEngine;

int main(int argc, const char* argv[])
{
    int n = 0;

    //Get the displays
    auto displays = GetDisplays();

    //Create a window
    auto window = CreateWindow(String(n), 0, 0, 800, 600, displays[0], WINDOW_TITLEBAR);

    //Create a framebuffer
    auto framebuffer = CreateFramebuffer(window);

    auto world = CreateWorld();
    auto camera = CreateCamera(world);

    //Main loop
    while (window->Closed() == false and window->KeyDown(KEY_ESCAPE) == false)
    {
        while (PeekEvent()) WaitEvent();

        if (window->KeyDown(KEY_SPACE))
        {
            ++n;
            int count = window.use_count();
            window = CreateWindow(String(n), window->position.x + 50, window->position.y + 50, window->size.x, window->size.y, window->display, window->style);
            framebuffer = CreateFramebuffer(window);
        }
        world->Update();
        world->Render(framebuffer);
    }
    return 0;
}

 

  • Thanks 1

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...