summaryrefslogtreecommitdiff
path: root/include/libcamera/object.h
AgeCommit message (Collapse)Author
2020-02-18libcamera: Use C++14 std::*_t type traitsLaurent Pinchart
C++14 introduced useful type traits helpers named std::*_t as aliases to std::*<...>::type. Use them to simplify the code. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2020-01-22libcamera: signal: Make slots list privateLaurent Pinchart
The slots list is touched from most of the Signal template functions. In order to prepare for thread-safety, move handling of the list to a small number of non-template functions in the SignalBase class. This incidently fixes a bug in signal disconnection handling where the signal wasn't removed from the object's signals list, as pointed out by the signals unit test. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2020-01-07libcamera: bound_method: Rename Bound*Method to BoundMethod*Laurent Pinchart
Most of the bound method classes are named with a BoundMethod prefix, except for BoundMemberMethod and BoundStaticMethod. Rename them to BoundMethodMember and BoundMethodStatic respectively to make the code more coherent. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2020-01-07libcamera: bound_method: Propagate method return valueLaurent Pinchart
Propagate the return value of the bound method all the way to the caller of activate(). The value is stored in the arguments pack for indirect invocation. As C++ doesn't allow instantiating a variable of type void, we need to specialize the template class BoundMethodPack for methods returning void. This in turn requires template specialization for the BoundMethodArgs class in order to store the return value in the pack, and for the BoundMemberMethod class to extract the return value from the pack. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2020-01-07libcamera: bound_method: Support bindings to non-void methodsLaurent Pinchart
The bound method implementation is restricted to binding to void methods as return values are not supported. This complicates usage of bound methods, as non-void methods used a slots or Object::invokeMethod() targets need to be wrapped in a void method. Simplify this by supporting arbitrary return types and ignoring the return value. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2020-01-07libcamera: object: Use activate() in invokeMethod()Laurent Pinchart
The Object::invokeMethod() implementation duplicates pack creation code from BoundMemberMethod::activate(). Call activate() instead of activatePack() to share code. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2020-01-03libcamera: object: Support reference arguments in invokeMethod()Laurent Pinchart
Invoking a method that takes a reference argument with Object::invokeMethod() results in a compilation error: ../test/object-invoke.cpp:131:11: error: no matching member function for call to 'invokeMethod' object_.invokeMethod(&InvokedObject::methodWithReference, ~~~~~~~~^~~~~~~~~~~~ ../include/libcamera/object.h:33:7: note: candidate template ignored: deduced conflicting types for parameter 'Args' (<const int &> vs. <int>) void invokeMethod(void (T::*func)(Args...), ConnectionType type, Args... args) This is due to the fact that implicit type conversions (from value to reference in this case) takes place after template argument type deduction, during overload resolution. A similar issue would occur if T::func took a long argument and invokeMethod() was called with an in argument. Fix this by specifying to sets of argument types in the invokeMethod() template, one for the arguments to the invoked method, and one for the arguments to invokeMethod() itself. The compiler can then first perform type deduction separately, and implicit conversion in a second step. Reported-by: Paul Elder <paul.elder@ideasonboard.com> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Paul Elder <paul.elder@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org>
2019-11-08libcamera: Remove unneeded semicolonsLaurent Pinchart
Comply with the coding style by removing lots of unneeded semicolons. Fix a few other coding style violations on the lines touched by those fixes. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Kieran Bingham <kieran.bingham@ideasonboard.com>
2019-10-29libcamera: object: Add connection type parameter to invokeMethod()Jacopo Mondi
Allow specifying a different connection type than ConnectionTypeQueued for Object::invokeMethod(). Signed-off-by: Jacopo Mondi <jacopo@jmondi.org> Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-10-29libcamera: object: Use bound method activePack() for invokeMethod()Laurent Pinchart
The BoundMethodBase::activatePack() and the internal Object::invokeMethod() are duplicate implementation of the same mechanism. Use the former to replace the latter. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-08-17libcamera: object: Create parent-child relationshipsLaurent Pinchart
Add a parent Object to Object instances, and track the parent-children relationships. Children are bound to the same thread as their parent, and moving an Object to a thread automatically moves all its children. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-08-17libcamera: object: Notify objects of thread moveLaurent Pinchart
Send a synchronous message to objects just before they get moved to a new thread. This allows the object to perform any required processing. EventNotifier and Timer objects will use this mechanism to move themselves to the new thread's event disaptcher. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-08-17libcamera: object: Add an asynchronous method invocation methodLaurent Pinchart
Add a helper invokeMethod() to the Object class that allows asynchrnous invocation of any method of an Object instance. Asynchronous invocation occurs when control returns to the event dispatcher of the target object's thread, in the context of that thread. To support this, generalise the SignalMessage implementation to support automatic deletion of the associated BoundMethod, and rename the message to InvokeMessage to reflect the more generic purpose. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-08-17libcamera: signal: Split Slot implementation to reusable classesLaurent Pinchart
Move the Slot* classes to bound_method.{h,cpp} and rename them to Bound*Method*. They will be reused to implement asynchronous method invocation similar to cross-thread signal delivery. This is only a move and rename, no functional changes are included. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-08-17libcamera: object: Make message() method protectedLaurent Pinchart
The message() method shouldn't be called externally (except by a few friend classes), make it protected. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Jacopo Mondi <jacopo@jmondi.org> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-07-11libcamera: signal: Fix Object handling in multiple inheritance casesLaurent Pinchart
The SlotBase implementation stores the receiver object pointer as a void pointer internally. The pointer is then cast back to an Object pointer when the receiver object class derives from Object. When the receiver is an object that inherits from both the Object class and other classes, the Object data members may not be stored at the beginning of the object memory. The cast back to an Object pointer is thus incorrect. Fix this by casting the receiver object pointer to an Object pointer where the type of the receiver object is known, and pass it along with the receiver void pointer to the SlotBase class. The SlotBase class stores both pointers internally, and doesn't need the isObject_ field anymore as the same information is obtained from checking if the Object pointer is null. To avoid confusing the two pointers, use the same naming scheme through the whole implementation: "obj" points to a receiver object as an unknown type, and "object" to the receiver object cast to an Object. The latter is null when the receiver object doesn't inherit from the Object class. To further clarify the code, remove direct access to the SlotBase "obj" and "object" fields as much as possible. They are replaced by two new methods : - SlotBase::disconnect() to disconnect a signal from the slot's receiver object - SlotBase::match() to test if an object pointer matches the slot The match() method is a template method with a specialisation for the Object type, to compare either the obj or the object pointer depending on the type of the parameter. This is required as the Object destructor calls the SignalBase::disconnect() method for signal connected to the object, and passes a pointer to Object to that method, while the actual object may have a different address due to the issue explained above. The pointer must thus be compared with the stored Object pointer in that case, not to the pointer to the receiver object. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-07-11libcamera: thread: Add a messaging passing APILaurent Pinchart
Create a new Message class to model a message that can be passed to an object living in another thread. Only an invalid message type is currently defined, more messages will be added in the future. The Thread class is extended with a messages queue, and the Object class with thread affinity. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>
2019-02-13libcamera: signal: Disconnect signal automatically on slot deletionLaurent Pinchart
When a signal is connected to a member function slot, the slot is not disconnected when the slot object is deleted. This can lead to calling a member function of a deleted object if the signal isn't disconnected manually by the slot object's destructor. Make signal handling easier by implementing a base Object class that tracks all connected signals and disconnects from them automatically when the object is deleted, using template specialization resolution in the Signal class. As inheriting from the Object class may to a too harsh requirement for Signal usage in applications, keep the existing behaviour working if the slot doesn't inherit from the Object class. We may reconsider this later and require all slot objects to inherit from the Object class. Signed-off-by: Laurent Pinchart <laurent.pinchart@ideasonboard.com> Reviewed-by: Niklas Söderlund <niklas.soderlund@ragnatech.se>