ddinu / observable Goto Github PK
View Code? Open in Web Editor NEWGeneric observable objects and reactive expressions for C++
License: Apache License 2.0
Generic observable objects and reactive expressions for C++
License: Apache License 2.0
Hi, @ddinu
Is there a way to expose subject as pure observable?
Would be great to have "read-only" interface for subject (hiding subject::notify()
and value::set()
).
Similar to Rx's asObservable()
Users should be able to create observable adapters over the standard library collections.
The wrappers should be inspired by std::queue and the rest of the container adapters in the standard library.
Adapters for new or custom containers should be easy to create.
Can you explain me how would I get the reference to widget object from within the body of the first lambda in the example in the documentation? I am certainly missing something:
[](std::string const & new_value) { /* update the widget : HOW? */ }
I'm trying out this pretty awesome library and ran into a bit of a hiccup. I want some code to take a const&
to my view-model (which contains obvservable::value<>
members) and that code needs to add some subscriptions for changes to the view-model's state. I understand that adding a subscription to a value
modifies its state internally (to maintain a list of subscribers), but I feel that subscribing is "logically const". By subscribing, I don't want to affect the state of a value
, I simply want to be informed when the state changes. So, it seems correct to allow new subscriptions on const value<>
types.
The shared_subscription::unsubscribe
method cannot be called in parallel from multiple threads as documentation claims.
A shared_ptr instance can be "read" (accessed using only const operations) simultaneously by multiple threads. Different shared_ptr instances can be "written to" (accessed using mutable operations such as operator= or reset) simultaneously by multiple threads (even when these instances are copies, and share the same reference count underneath.)
Any other simultaneous accesses result in undefined behavior.
Hi, I really love this library. I see there has not been much activity lately. What is the status? Maybe it's working well for lots of people and no major development is required.
I made a small change in my fork to allow templated OBSERVABLE_ADAPT_FILTER which was very useful for my usecase of deserializing a stream of json strings of different types.
Are you still open to pull requests?
Asynchronous IO done through observable handles (i.e. files or sockets).
This would work nicely with custom expression filters.
Refactor the documentation to use HTML generated by Doxygen for the reference instead of Breathe.
Is it necessary to have 3.8 version of cmake required?
Android Studio provides 3.6.
I'm working on reactive library µReact as a hobby.
Reactive variables works better when they are public members of classes, because such way they are more expressive and require less (or even no) boilerplate code.
But if they made so, then their assignment operator is exposed too, so such members can be reassigned to new values by mistake.
I've seen attempt to protect from it by declaring public members as const, but const members always have been kind of problem in C++.
So observable property approach from Getting started with observable properties comes to the rescue. To protect from reassigned public members should have class that makes construction and assignment private and allows it only for their parameterized Owner class.
So here is the result: https://godbolt.org/z/8rKPWW8fq
#include <iostream>
#include "https://raw.githubusercontent.com/YarikTH/ureact/dev/single_include/ureact/ureact_amalgamated.hpp"
class Foo : ureact::member_signal_user<Foo> {
// the same as inheritance from ureact::member_signal_user<Foo>
// UREACT_USE_MEMBER_SIGNALS(Foo);
public:
Foo(ureact::context& ctx, int aValue, int bValue) {
// Defining reactive variables. We can reassign their values later
a = make_var(ctx, aValue);
b = make_var(ctx, bValue);
// Defining reactive signal using overloaded operator
// Its value will be updated each time its dependencies are changed
x = a + b;
}
member_var_signal<int> a;
member_var_signal<int> b;
member_signal<int> x;
};
int main() {
ureact::context ctx;
Foo foo{ctx, 1, 2};
std::cout << "x (init): " << foo.x() << "\n"; // 3
// Assign a new value to 'a'. Value of 'x' is recalculated automatically
foo.a <<= 10;
std::cout << "x (new): " << foo.x() << "\n"; // 12
// member can't be reassignment from outside of Foo class
// so next line won't compile
// foo.a = make_var( ctx, 20 );
}
The root CMAkeLists.txt is using add_custom_target
. It should use add_library(name INTERFACE ...)
instead.
Should be possible to unsubscribe in the case an observer is no longer valid.
Hi Daniel,
Are the observable properties thread safe?
I see that observable_property can be subscribed to with a std::function.
When this is run, does it spawn on a new thread, or does it run within the thread that modifies the observable_property?
Best,
StaticLink
As far as I can tell, connecting / disconnecting from multiple threads is not safe.
The library needs some examples that are more complex than hello world.
I'm thinking of a simple app based on Qt to show some sort of MVC implementation.
Add how-to guides for subjects and values.
Users should be able to create observable expressions. Something like below:
auto a = value<int> { 5 };
auto b = value<int> { 7 };
value<double> avg = (a + b) / 2.0;
b = 3;
cout << avg.get(); // outpus 4
These expressions are evaluated each time a value changes.
Hello @ddinu
This looks like a Clang/LLDB problem, but would be great to hear any ideas. I will attach the small project of several lines of code.
Problem: LLDB suddenly crashes when debugging code with observable::value<Foo>
if Foo
is within a namespace. Works fine if Foo
is global. observable::subject<Foo>
works perfectly in both cases. Everything works fine when using GCC.
Environment:
MacOS Sierra 10.12.6 (16G29)
Xcode 9.0 (9A235)
Clang Apple LLVM version 9.0.0 (clang-900.0.37)
LLDB version lldb-900.0.45 Swift-4.0
Tested in Xcode and CLion.
Easy way for users to implement their own operations that can be used in expressions.
There are a number of heap allocations in expressions. We should try to reduce this number as much as possible, ideally no allocations would be performed.
The library should have versioned, stable, releases that guarantee backwards compatibility. It should use semantic versioning.
Hi @ddinu
auto unsubscribe() &
{
if(!called_->test_and_set())
{
try {
unsubscribe_();
} catch(...) {
called_.reset();
throw;
}
}
}
What does &
do in auto unsubscribe() & { ...
?
Or &&
in auto release() && { ...
Thanks in advance.
Hello,
It would be cool to keep state of subject even if there are no subscribers at a moment, just like BehaviourSubject do.
Please share your thoughts about it.
Thanks, in general your library is what I was looking for 👍
Seems like the documentation is mostly empty files? Am I missing it?
What advantage is there in this library over, say, Boost.Signal2?
Wrapper around observable subjects and values that run subscribed observers on a thread pool.
Each observer would see events in-order but it might run in parallel with other subscribers and on an arbitrary thread.
Would you like to replace any double quotes by angle brackets around file names for include statements?
All heap allocations should use an allocator. Either a default one or an user-provided one.
There are a few workflows we can use. I know locally we can develop however we want, but I guess we can choose a standard workflow so everything will be clear for everybody.
Personally I like to use the GitFlow workflow, but this means we need write access to ddinu/observable
.
Another workflow is the so called GitFlow for GitHub, based on pull requests.
Also we can define whatever workflow we want as long as we are consistent with the fact that this repository is the official one.
No matter what we choose I think at least a rule that states that we must mention the issue number in the feature branch's name is the minimum we should do.
Improve the doxygen comments to produce better reference documentation.
The following should work:
std::result_of
and std::result_of_t
has been deprecated by C++17. When using the library with C++17 enabled we face several errors in the file utility.hpp
.
1>observable\expressions\utility.hpp(79): error C4996: 'std::result_of_t': warning STL4014: std::result_of and std::result_of_t are deprecated in C++17. They are superseded by std::invoke_result and std::invoke_result_t. You can define _SILENCE_CXX17_RESULT_OF_DEPRECATION_WARNING or _SILENCE_ALL_CXX17_DEPRECATION_WARNINGS to acknowledge that you have received this warning.
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.15.26726\include\type_traits(1855): note: see declaration of 'std::result_of_t'
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.