Signed-off-by: Zane Bitter<zbitter(a)redhat.com>
---
matahari.spec.in | 1
src/CMakeLists.txt | 1
src/include/matahari/object.h | 96 +++++++++++++++++++++++++++++++
src/lib/CMakeLists.txt | 2 -
src/lib/mh_object.cpp | 125 +++++++++++++++++++++++++++++++++++++++++
5 files changed, 224 insertions(+), 1 deletions(-)
create mode 100644 src/include/matahari/object.h
create mode 100644 src/lib/mh_object.cpp
This looks cool. Nice work.
I'm wondering if we should add a simple agent that uses it for both
demonstration and testing purposes. It seems like something we may want
a good example to point to for other agent authors.
It would be something like ...
1) Write a relatively simple example agent that handles multiple objects
with an ObjectManager.
2) Always compile, but only install and package this example agent if
some define is present.
3) Add a new Python based test in src/tests/ that exercises the agent to
make sure it works.
4) Update autobuild.sh to get this test agent built/packaged/installed.
Add the new test to be executed on every autobuild run.
diff --git a/matahari.spec.in b/matahari.spec.in
index b0db60a..c40f9fb 100644
--- a/matahari.spec.in
+++ b/matahari.spec.in
@@ -658,6 +658,7 @@ test "x%{buildroot}" != "x"&& rm -rf
%{buildroot}
%if %{with qmf}
%{_includedir}/matahari/agent.h
+%{_includedir}/matahari/object.h
%{_includedir}/matahari/mainloop.h
%{_datadir}/cmake/Modules/FindQPID.cmake
%endif
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index e305951..14a4bd5 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -206,6 +206,7 @@ install(FILES cmake/modules/MatahariMacros.cmake DESTINATION
share/cmake/Modules
if(WITH-QMF)
install(FILES cmake/modules/FindQPID.cmake DESTINATION share/cmake/Modules)
install(FILES include/matahari/agent.h DESTINATION include/matahari)
+ install(FILES include/matahari/object.h DESTINATION include/matahari)
install(FILES include/matahari/mainloop.h DESTINATION include/matahari)
endif(WITH-QMF)
diff --git a/src/include/matahari/object.h b/src/include/matahari/object.h
new file mode 100644
index 0000000..ead6dd6
--- /dev/null
+++ b/src/include/matahari/object.h
@@ -0,0 +1,96 @@
+/* mh_object.cpp - Copyright (C) 2011 Red Hat, Inc.
+ * Written by Zane Bitter<zbitter(a)redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __MATAHARI_OBJECT_H
+#define __MATAHARI_OBJECT_H
+
+#include<qmf/AgentEvent.h>
+#include<qmf/AgentSession.h>
+#include<qmf/Schema.h>
+#include<qmf/Data.h>
+#include<qmf/DataAddr.h>
+
+/**
+ * \file
+ * \brief Utilities for managing multiple objects
+ */
+
+
+/**
+ * An object that is managed by an ObjectManager. Create a subclass of this and
+ * override the invoke() method to handle events destined for the object.
+ */
+class MatahariObject
+{
+public:
+ /** Create the object with the supplied schema. */
+ MatahariObject(qmf::Schema schema);
+ virtual ~MatahariObject();
+
+ /** Get the QMF address of the object. */
+ const qmf::DataAddr& getAddr(void) { return _instance.getAddr(); }
+
+ /** Publish the object in the specified session. */
+ void publish(qmf::AgentSession& session);
+ /** Unpublish the object from the specified session. */
+ void withdraw(qmf::AgentSession& session);
+
+ /**
+ * Handle an event that is destined for this object.
+ * \param session the session from which the event originated.
+ * \param event the event
+ * \return true if the event was handled, false otherwise.
+ */
+ virtual bool invoke(qmf::AgentSession& session, qmf::AgentEvent& event)
+ { return false; }
+
+protected:
+ qmf::Data _instance;
+};
+
+
+class ObjectManagerImpl;
+
+/**
+ * A store that manages a collection of QMF objects.
+ */
+class ObjectManager
+{
+public:
+ /** Initialise for the given session. */
+ ObjectManager(qmf::AgentSession& session);
+ ~ObjectManager();
+
+ /** Publish a new object to the session. */
+ ObjectManager& operator+=(MatahariObject* object);
+ /** Unpublish an object from the session. */
+ ObjectManager& operator-=(MatahariObject* object);
+
+ /**
+ * Handle an event by directing it to the correct object.
+ * \param session the session from which the event originated.
+ * \param event the event
+ * \return true if the event was handled, false otherwise.
+ */
+ bool invoke(qmf::AgentSession& session, qmf::AgentEvent& event) const;
+
+private:
+ ObjectManagerImpl *_impl;
+};
+
+#endif
diff --git a/src/lib/CMakeLists.txt b/src/lib/CMakeLists.txt
index b5ab0f7..67cad82 100644
--- a/src/lib/CMakeLists.txt
+++ b/src/lib/CMakeLists.txt
@@ -43,7 +43,7 @@ else(WIN32)
endif(WIN32)
if(WITH-QMF)
- add_library (mcommon_qmf SHARED mh_agent.cpp)
+ add_library (mcommon_qmf SHARED mh_agent.cpp mh_object.cpp)
set_target_properties(mcommon_qmf PROPERTIES SOVERSION 1.0.0)
target_link_libraries(mcommon_qmf mcommon ${QPIDCOMMON_LIBRARY}
diff --git a/src/lib/mh_object.cpp b/src/lib/mh_object.cpp
new file mode 100644
index 0000000..fcfe5dd
--- /dev/null
+++ b/src/lib/mh_object.cpp
@@ -0,0 +1,125 @@
+/* mh_object.cpp - Copyright (C) 2011 Red Hat, Inc.
+ * Written by Zane Bitter<zbitter(a)redhat.com>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This software is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#include "config.h"
+
+#include<map>
+#include<matahari/object.h>
+extern "C" {
+#include<matahari/logging.h>
+}
+
+struct ObjectManagerImpl
+{
+ ObjectManagerImpl(qmf::AgentSession& session): _session(session) { }
+
+ MatahariObject *find(const qmf::DataAddr& addr);
+
+
+ // This is necessary to avoid a bug (#QPID3344) in libqmf2 versions prior
+ // to 0.14, in which DataAddr objects are not compared correctly when they
+ // are const (as all std::map keys are).
+ struct AddrComparator {
+ bool operator()(const qmf::DataAddr& addr1, const qmf::DataAddr&
addr2)
+ {
+ return const_cast<qmf::DataAddr&>(addr1)< addr2;
+ }
+ };
+
+ typedef std::map<qmf::DataAddr, MatahariObject*, AddrComparator> ObjectMap;
+
+
+ qmf::AgentSession& _session;
+ ObjectMap _objects;
+};
+
+
+MatahariObject*
+ObjectManagerImpl::find(const qmf::DataAddr& addr)
+{
+ ObjectMap::const_iterator it(_objects.find(addr));
+
+ return it != _objects.end() ? it->second : NULL;
+}
+
+
+ObjectManager::ObjectManager(qmf::AgentSession& session):
+ _impl(new ObjectManagerImpl(session))
+{ }
+
+ObjectManager::~ObjectManager()
+{
+ delete _impl;
+}
+
+ObjectManager& ObjectManager::operator+=(MatahariObject* object)
+{
+ object->publish(_impl->_session);
+ if (!object->getAddr().isValid()) {
+ mh_err("Failed to publish object");
+ return *this;
+ }
+ _impl->_objects[object->getAddr()] = object;
+
+ return *this;
+}
+
+ObjectManager& ObjectManager::operator-=(MatahariObject* object)
+{
+ _impl->_objects.erase(object->getAddr());
+ object->withdraw(_impl->_session);
+
+ return *this;
+}
+
+bool ObjectManager::invoke(qmf::AgentSession& session,
+ qmf::AgentEvent& event) const
+{
+ if (event.hasDataAddr()) {
+ MatahariObject *obj = _impl->find(event.getDataAddr());
+
+ if (obj) {
+ return obj->invoke(session, event);
+ }
+
+ mh_err("Target of method call not found");
+ }
+
+ return false;
+}
+
+
+MatahariObject::MatahariObject(qmf::Schema schema): _instance(schema)
+{ }
+
+MatahariObject::~MatahariObject()
+{ }
+
+void
+MatahariObject::publish(qmf::AgentSession& session)
+{
+ session.addData(_instance);
+ mh_debug("Published object %s", getAddr().getName().c_str());
+}
+
+void
+MatahariObject::withdraw(qmf::AgentSession& session)
+{
+ mh_debug("Withdrawing object %s", getAddr().getName().c_str());
+ session.delData(getAddr());
+}
_______________________________________________
Matahari mailing list
Matahari(a)lists.fedorahosted.org
https://fedorahosted.org/mailman/listinfo/matahari