Comments (20)
Note that modifying the Elements (aka std::vector) from one thread, while the "UI" thread is drawing them might result in crashes.
What is the safe way to do this?
You are modifying and reading your data from two thread. You need to use a mutex to ensure you don't do this at the same time.
https://en.cppreference.com/w/cpp/thread/lock_guard
If you don't want to use mutex, you could also use the Receiver class below as a thread-safe queue to request updates from one thread, but execute them on the UI thread.
https://github.com/ArthurSonzogni/FTXUI/blob/master/include/ftxui/component/receiver.hpp
Using the method you told, causes crashes
Could you investigate why?
and doesn't work well as I am using a low powered device.
I don't really see why we have this implication.
I tried passing the screen object to component class, but I am unable to do so. It gives some error, like function not defined of some sorts.
You will have to investigate and find what happens here. I don't have enough informations.
Is it possible to refresh just one single component, rather than complete screen? I looked up the source, you are always doing element.first.render()
No, this is currently not possible. This is simpler this way.
I could try to print only the required difference, but this would require printing many "displace the cursor to position (x,y)". This wouldn't be better.
What OS are you using? (Windows support is quite limited now)
My use case: I am reading from a file descriptor every 100ms, if new data is received it is pushed to
Elements
variable from the thread. So what i wanna do is, only when i push data, the screen or that component redraws on the screen with updated elements.
Then, use screen.PostEvent(Event::Custom) only when you need a refresh.
from ftxui.
Note that modifying the Elements (aka std::vector) from one thread, while the "UI" thread is drawing them might result in crashes.
What is the safe way to do this?
You are modifying and reading your data from two thread. You need to use a mutex to ensure you don't do this at the same time.
https://en.cppreference.com/w/cpp/thread/lock_guard
...Upon reading on the documentation about lock_guard, I found that it would be better to use a scoped_lock instead as it
offers a replacement for lock_guard that provides the ability to lock multiple mutexes using a deadlock avoidance algorithm.
(So, I guess much robust compared to lock_guard?)However, I just started learning c++ so I'm not sure if scoped_lock would be an overkill just for the mutex lock.
Can I get an opinion on what you think? Thank you.
Hi Thinkty, my memory is a bit rusty, but I don't think using scoped_lock will be any better here, as lock guard does the job and I am using only one mutex not multiple.
Regards
Vedant
from ftxui.
scoped_lock
is always better than lock_guard
and should be used.
However, when locking only one mutex, its behavior is equivalent here.
from ftxui.
A new frame is drawn after processing the last Event. Events can come from several threads (keyboard events, terminal event, operating system event, ...). To get this right, the events are processed behind a thread-safe queue.
To refresh, you can use the thread-safe method: InteractiveScreen::PostEvent(...).
You can send Event::Custom.
There is an example here:
FTXUI/examples/component/homescreen.cpp
Line 374 in 9f8bd4c
std::thread update([&screen]() {
for (;;) {
using namespace std::chrono_literals;
std::this_thread::sleep_for(0.05s);
shift++;
screen.PostEvent(Event::Custom);
}
});
from ftxui.
Note that modifying the Elements (aka std::vector) from one thread, while the "UI" thread is drawing them might result in crashes.
from ftxui.
Note that modifying the Elements (aka std::vector) from one thread, while the "UI" thread is drawing them might result in crashes.
What is the safe way to do this?
Using the method you told, causes crashes and doesn't work well as I am using a low powered device. I tried passing the screen object to component class, but I am unable to do so. It gives some error, like function not defined of some sorts.
Is it possible to refresh just one single component, rather than complete screen? I looked up the source, you are always doing element.first.render()
My use case: I am reading from a file descriptor every 100ms, if new data is received it is pushed to Elements
variable from the thread. So what i wanna do is, only when i push data, the screen or that component redraws on the screen with updated elements.
from ftxui.
You are modifying and reading your data from two thread. You need to use a mutex to ensure you don't do this at the same time.
https://en.cppreference.com/w/cpp/thread/lock_guard
I thought to do this, but how can i use mutex inside the render function, I don't think I'd need one since Elements
is a std::vector<> which is thread safe by default. Since only thread is modifying and the render function is only reading the Elements
.
No, this is currently not possible. This is simpler this way.
I could try to print only the required difference, but this would require printing many "displace the cursor to position (x,y)". This
wouldn't be better.
I solved this issue by defining a global variable to record state.
What OS are you using? (Windows support is quite limited now)
Linux Mint 20 :) I avoid windows like the plague.
Then, use screen.PostEvent(Event::Custom) only when you need a refresh.
I put a if loop inside the while loop in thread like this,
std::thread update([&screen]() {
for (;;) {
using namespace std::chrono_literals;
std::this_thread::sleep_for(std::chrono::milliseconds(1));
if(update_screen)
{
update_screen = false;
screen.PostEvent(Event::Custom);
}
}
});
from ftxui.
I thought to do this, but how can i use mutex inside the render function.
You can lock the mutex inside the Component::Render() method you overrode. In the component using the vector.
I don't think I'd need one since
Elements
is a std::vector<> which is thread safe by default. Since only thread is modifying and the render function is only reading theElements
.
If one thread is iterating on the std::vector, while the other modify the vector, it might be reallocated elsewhere. Then the first thread will read unallocated area.
std::thread update([&screen]() { for (;;) { using namespace std::chrono_literals; std::this_thread::sleep_for(std::chrono::milliseconds(1)); if(update_screen) { update_screen = false; screen.PostEvent(Event::Custom); } } });
Yes, this would work.
I would have expected something like this instead:
void NewDataReceivedFromFileDescriptor(...) {
[...]
{
std::lock_guard<std::mutex> lock(mutex);
[...] // Modify the UI data.
}
screen.PostEvent(Event::Custom); // Refresh the UI.
}
Element MyComponent::Render() {
std::lock_guard<std::mutex> lock(mutex); // Access data modified from another thread.
return vbox([...])
}
from ftxui.
Great, did this, and it worked.
So, I have completed the subproject.
thanks for the prompt response here.
from ftxui.
Great to hear that!
I am guessing your project is: simpPRU
I will add a link to it into the FTXUI Readme, It would be nice seeing a screenshot of the UI.
from ftxui.
Great to hear that!
I am guessing your project is: simpPRU
I will add a link to it into the FTXUI Readme, It would be nice seeing a screenshot of the UI.
Here's the pic: https://imgur.com/5V1FSm4, Please don't post the link, rather download the image and upload to your repo, as imgur links from anonymous users expire after a week or so.
This is my Google Summer of Code Project, here's the link: https://github.com/VedantParanjape/simpPRU.
Do star and share my project if you like it ;)
Regards,
Vedant
from ftxui.
Here's the pic: https://imgur.com/5V1FSm4, Please don't post the link, rather download the image and upload to your repo, as imgur links from anonymous users expire after a week or so.
Thanks!
I was very happy including a link to: https://github.com/AnisBdz/CPU because it showed a really nice interface using FTXUI in their README.
I was thinking I could include a link to your repository and see a nice TUI too. It's up to you whether you prefer having one or not. I will add a link to your repository no matter what.
This was my Google Summer of Code Project, here's the link: https://github.com/VedantParanjape/simpPRU.
Do star and share my project if you like it ;)
Sure! I will!
Note: I happen to work at Google (on chrome). I am very happy to see one of my project being used for GSoC!
from ftxui.
Here's the pic: https://imgur.com/5V1FSm4, Please don't post the link, rather download the image and upload to your repo, as imgur links from anonymous users expire after a week or so.
Thanks!
I was very happy including a link to: https://github.com/AnisBdz/CPU because it showed a really nice interface using FTXUI in their README.
I was thinking I could include a link to your repository and see a nice TUI too. It's up to you whether you prefer having one or not. I will add a link to your repository no matter what.
You could link my repository for now, in a few days, I'll finish writing docs, which will include a a detailed guide with screenshots, will update you then.
This is my Google Summer of Code Project, here's the link: https://github.com/VedantParanjape/simpPRU.
Do star and share my project if you like it ;)Sure! I will!
Note: I happen to work at Google (on chrome). I am very happy to see one of my project being used for GSoC!
Wow, that's great. I have applied for Google SWE Internship 2021. Coding round's on 16th, wish me luck :) I would like to ask some questions about the same, if you are free, could I drop you a mail?
from ftxui.
I thought to do this, but how can i use mutex inside the render function.
You can lock the mutex inside the Component::Render() method you overrode. In the component using the vector.
I don't think I'd need one since
Elements
is a std::vector<> which is thread safe by default. Since only thread is modifying and the render function is only reading theElements
.If one thread is iterating on the std::vector, while the other modify the vector, it might be reallocated elsewhere. Then the first thread will read unallocated area.
std::thread update([&screen]() { for (;;) { using namespace std::chrono_literals; std::this_thread::sleep_for(std::chrono::milliseconds(1)); if(update_screen) { update_screen = false; screen.PostEvent(Event::Custom); } } });Yes, this would work.
I would have expected something like this instead:void NewDataReceivedFromFileDescriptor(...) { [...] { std::lock_guard<std::mutex> lock(mutex); [...] // Modify the UI data. } screen.PostEvent(Event::Custom); // Refresh the UI. } Element MyComponent::Render() { std::lock_guard<std::mutex> lock(mutex); // Access data modified from another thread. return vbox([...]) }
I gave this a bit of thought, why don't you make it a std::atomic variable, i.e this.
std::atomic<std::vector<std::shared_ptr<Node>>>
Won't it give flexibility to a user? I mean beginners might not even know what a mutex is !
from ftxui.
Wow, that's great. I have applied for Google SWE Internship 2021. Coding round's on 16th, wish me luck :) I would like to ask some questions about the same, if you are free, could I drop you a mail?
Yes sure, no problems. Feel free to do so on the email I am using for git.
I gave this a bit of thought, why don't you make it a std::atomic variable, i.e this.
std::atomic<std::vector<std::shared_ptr>>
Won't it give flexibility to a user? I mean beginners might not even know what a mutex is !
Here is a link about what std::atomic is: https://stackoverflow.com/a/31978762
You can't have atomic operations on an std::vector. For simple type like int,float,double,... std::atomic can be useful because the compiler can use some special CPU instructions.
Reallocating a memory area somewhere else is not something that can be done atomically.
from ftxui.
Wow, that's great. I have applied for Google SWE Internship 2021. Coding round's on 16th, wish me luck :) I would like to ask some questions about the same, if you are free, could I drop you a mail?
Yes sure, no problems. Feel free to do so on the email I am using for git.
Cool !
I gave this a bit of thought, why don't you make it a std::atomic variable, i.e this.
std::atomic<std::vectorstd::shared_ptr>
Won't it give flexibility to a user? I mean beginners might not even know what a mutex is !Here is a link about what std::atomic is: https://stackoverflow.com/a/31978762
You can't have atomic operations on an std::vector. For simple type like int,float,double,... std::atomic can be useful because the compiler can use some special CPU instructions.
Reallocating a memory area somewhere else is not something that can be done atomically.
Ohh, I see. I didn't know about this, gotta read more about C++
from ftxui.
Note that modifying the Elements (aka std::vector) from one thread, while the "UI" thread is drawing them might result in crashes.
What is the safe way to do this?
You are modifying and reading your data from two thread. You need to use a mutex to ensure you don't do this at the same time.
https://en.cppreference.com/w/cpp/thread/lock_guard
...
Upon reading on the documentation about lock_guard, I found that it would be better to use a scoped_lock instead as it offers a replacement for lock_guard that provides the ability to lock multiple mutexes using a deadlock avoidance algorithm.
(So, I guess much robust compared to lock_guard?)
However, I just started learning c++ so I'm not sure if scoped_lock would be an overkill just for the mutex lock.
Can I get an opinion on what you think? Thank you.
from ftxui.
I see, thank you!
from ftxui.
scoped_lock
is always better thanlock_guard
and should be used.However, when locking only one mutex, its behavior is equivalent here.
Encountering a contrast of opinion, I think the behavior is equivalent indeed. Also, I think the overhead of using scoped_lock
over lock_guard
might be quite subtle to have an impact on performance (but I am not sure)
https://stackoverflow.com/questions/59966836/stdscoped-lock-behaviour-with-a-single-mutex
http://eel.is/c++draft/thread.mutex#thread.lock.scoped-2
Initializes pm with tie(m...). Then if sizeof...(MutexTypes) is 0, no effects. Otherwise if sizeof...(MutexTypes) is 1, then m.lock(). Otherwise, lock(m...).
from ftxui.
@thinkty if it works don't touch it 😂
from ftxui.
Related Issues (20)
- The scrollbar doesn't work in the "homescreen.cpp" demo HOT 3
- [feature request] Scatter plots HOT 1
- Dynamically adding elements to Checkboxes HOT 5
- Correctness of layout requirement for flexbox. Scrollbar implementation. HOT 1
- I've tried everything. I need help HOT 1
- Compression priority when rendering a vbox with inadequate space. HOT 2
- lifecycle problem HOT 2
- Final link failed: Bad value HOT 3
- Fix for Visual Studio color and bgcolor unresolved symbols HOT 1
- Modal windows, what am I doing wrong? HOT 2
- Catching events for nested components HOT 2
- window element with light border style HOT 2
- Adding interactive component into a table HOT 4
- CtrlH not work but others CtrlA,CtrlB... can HOT 1
- Changes cursor in underlying terminal
- RGBA's Alpha not work in alacritty HOT 3
- How to scroll elements , not components HOT 2
- "input" example allows line breaks in phone number HOT 1
- Creating a table with 2 columns HOT 7
- Knob Support HOT 6
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from ftxui.