stasher::currentbaseObj<classptr
>
: virtual superclass for stasher::create_manage_object
()'s functors
The following example is an alternate version of
showinventory.C
that uses
stasher::currentBaseObj
:
#include <stasher/client.H> #include <stasher/manager.H> #include <stasher/currentbase.H> #include "inventory.H" class subscriptionObj : public stasher::currentBaseObj<inventoryptr> { public: subscriptionObj() {} ~subscriptionObj() {} void update(const inventoryptr &newvalue, bool isinitial) override; void connection_update(stasher::req_stat_t) override; }; void update(const inventoryptr &ptr, bool initial); void showinventory(int argc, char **argv) { if (argc < 2) return; auto client=stasher::client::base::connect(); auto manager=stasher::manager::create(); std::cout << "Showing current inventory, press Enter to stop" << std::endl; auto subscriber=x::ref<subscriptionObj>::create(); x::ref<x::obj> mcguffin=subscriber->manage(manager, client, argv[1]); std::string dummy; std::getline(std::cin, dummy); } void subscriptionObj::update(const inventoryptr &ptr, bool initial) { std::cout << (initial ? "Current inventory:":"Updated inventory:") << std::endl; if (ptr.null()) { std::cout << " (none)" << std::endl; } else { std::cout << " " << std::setw(30) << std::left << "Item" << " " << std::setw(8) << std::right << "Count" << std::setw(0) << std::endl; std::cout << " " << std::setfill('-') << std::setw(30) << "" << " " << std::setw(8) << "" << std::setw(0) << std::setfill(' ') << std::endl; for (auto &item:ptr->stock) { std::cout << " " << std::setw(30) << std::left << item.first << " " << std::setw(8) << std::right << item.second << std::setw(0) << std::endl; } std::cout << std::setw(75) << std::setfill('=') << "" << std::setw(0) << std::setfill(' ') << std::endl; } } void subscriptionObj::connection_update(stasher::req_stat_t status) { std::cout << "Connection update: " << x::tostring(status) << std::endl; } int main(int argc, char **argv) { try { showinventory(argc, argv); } catch (const x::exception &e) { std::cerr << e << std::endl; return 1; } return 0; }
The stasher::currentBaseObj<
template defines a class with two virtual methods,
classptr
>update
() and
connection_update
(); and a
manage
() method.
manage
() takes a manager object, and client
connection object, and an object name as parameters; it invokes
stasher::create_managed_object
with functors that invoke the
update
() and
connection_update
() methods, then calls
the manager's manage_object
() method, like
showinventory.C
does, and returns the managed object's
mcguffin.
To summarize:
Subclass stasher::currentBaseObj<
, where
classptr
>
is
an classptr
x::ref
to a class
that meets the requirements described
in the section called “Requirements”; then implement the
update
() method. Implementing
connection_update
() which reports the
status of the connection, as described in Chapter 10, Asynchronous connection manager,
is optional.
After invoking manage
(),
the object's update
() gets called with the
deserialized object every time it's changed in the repository, with the
first call happening immediately, with the
initial
bool set to
true
, and with
false
for subsequent updates.
In the event that the connection with the object repository gets lost,
and reestablished, another call to update
()
with a true
will follow when the connection gets
reestablished.
manage
() returns the subscription mcguffin from
manage_object
().
Implementing connection_update
() in the
subclass is optional.
The functors created by
manage
(), then get incorporated into the
instantiated managed object, hold a strong reference to the
stasher::currentBaseObj
and its subclass.
The subclass should not store the mcguffin in the class instance, that
creates a circular reference. If an execution thread is running the
subclass, it's generally fine to store the mcguffin on the executing
thread's stack, which will go out of scope and get destroyed when the
executing thread returns.
Also note that
update
() and
connection_update
() are invoked by the functors
with certain limitations, described in
showinventory.C
typically invoked by the client connection thread, and they
have certain limitations, see
stasher::create_managed_object
for more information.