Qore dual class implementation (C++/Qore) and calling virtual method from C++ core - qore

I need implement a class QoreFoo in C++ and its dual implementation for Qore script Foo via .qpp. QoreFoo is abstract class providing general API and real functionality is to be added in descendand class (in C++ or Qore). The Foo API calls from core, i.e.C++, need to be propagated to instantiated objects regardless where descendant class is used.
QoreFoo.h
# implement general API
class QoreFoo {
public:
virtual void bar(ExceptionSink *xsink)=0;
};
extern QoreFoo* current_foo;
// just assign instance of a descendant of QoreFoo
void QoreAssignFoo(QoreFoo* n_foo) {
current_foo = n_foo;
}
QoreFoo.cpp
QoreFoo* current_foo = 0;
any.cpp
if (current_foo)
current_foo.bar(xsink); // propagate call via overriden method
When I need implement C++ descendant that is trivial:
QoreFoo2.h
class QoreFoo2: QoreFoo {
void bar(ExceptionSink *xsink) {
# my stuff
printf("Hello World from C++");
}
};
usage.cpp
QoreAssignFoo(new QoreFoo2);
# wait for "Hello World from C++" when core calls current_foo.bar()
.....
But how to do it to propagate call to Qore script class? I think an extra class is needed to call dual class defined in .qpp and overriden in .q
QoreFooHelper.h
class QoreFooHelper: class QoreFoo {
private:
QoreObject* qo;
public:
QoreFooHelper(QoreObject* n_qo): qo(n_qo) {
}
void bar(ExceptionSink *xsink) {
// convert args if any
// call virtual function of Foo class, i.e. qo
qo->evalMethod("bar", 0, xsink);
}
QC_Foo.qpp
# implement assign instance function
nothing assignFoo(*Foo foo) {
QoreAssignFoo(foo->p);
}
#implement class for Qore script
qclass Foo [arg=QoreFooHelper* p]
Foo::constructor() {
assert(self->validInstanceOf(CID_FOO)); // is it correct test to test if inherited from ?
QoreFoo* f = new QoreFooHelper(self);
self->setPrivate(CID_FOO, f);
}
# probably useless as it generates function code
#nothing Foo::bar() {
#}
Test.q
class Foo2 inherits Foo {
nothing bar() {
# my stuff
printf("Hello world from Q");
}
}
Foo2 foo();
assignFoo(foo); # assign instance of Foo2
# wait for "Hello World from Q" message when core calls current_foo.bar()
....
Is this feasible solution or even does exist a better way, e.g. using qpp features or avoiding QoreFooHelper (but I need avoid overhead when fully implemented QoreFoo2 in C++) ?
If not then what is alternative option, e.g. passing callref or closure somehow and do real callback ?
Edit:
When defining Qore class in .qpp then qpp generates class definition QoreClass* initFoo() (add methods, constructors,etc.) and registers it into a namespace repository.
When new QoreObject is to be created then is constructed with QoreClass as parameter found in namespace repo.
.qpp defined constructor normally creates pure C++ QoreFoo instance and assigns as private property (self->setPrivate(CID_FOO, new QoreFoo())), i.e. link from Foo to QoreFoo is established and will be used when defining .qpp methods, where is operating with pure C++ stuff. .qpp generated appropriate C++ code into function "header". self is QoreObject instance.
I think the same is done in runtime for Foo3 script class.
Qpp helps implementing Qore stuff to call C++ stuff.
But I need opposite direction, calling Qore methods from C++, so I think I need call QoreObject::evalMethod(). As QoreObject does not
exist in normal C++ class so extra descendant QoreFooHelper is needed to implement it (with extra problem when passing general objects as parameters).

If the API you want to enforce is a Qore-language class API, then you need to implement your abstract class in Qore and not in C++.
If you have a C++ virtual class hierarchy that should be extended in Qore, then you should use qpp to implement your Qore class in C++ and then allow programmers to extend it naturally by subclassing your classes in Qore.
You can do it like this:
QoreFoo.h
class QoreFoo {
public:
DLLLOCAL QoreFoo(QoreObject* o) : obj(o) {
}
// other functions...
private:
QoreObject* obj; //!< The QoreObject this private data is associated with
};
QC_Foo.qpp
//! This class defines an abstract interface for ...
/**
*/
qclass Foo [arg=QoreFoo* foo; ns=Foo];
//! Constructor
/** Used by subclasses defined in Qore
*/
Foo::constructor() {
self->setPrivate(CID_FOO, new QoreFoo(self));
}
//! a method to ...
/**
*/
abstract nothing Foo::bar();
This allows class Foo to have some private data and an abstract Qore API that can be used by subclasses; subclasses in C++ (implemented with qpp) should declare Foo as a vparent as in the following example:
QoreFoo2.h
#include "qore/intern/QoreFoo.h"
class QoreFoo2 : public QoreFoo {
public:
DLLLOCAL QoreFoo2(QoreObject* o) : QoreFoo(o) {
}
DLLLOCAL void bar(ExceptionSink* xsink) {
printf("Hello World from C++");
}
// other functions...
};
QC_Foo2.qpp
#include "qore/intern/QoreFoo2.h"
//! This class ...
/**
*/
qclass Foo2 [arg=QoreFoo2* foo; ns=Foo; vparent=Foo];
//! Constructor
/** Used by subclasses defined in the Qore programming language.
*/
Foo2::constructor() {
self->setPrivate(CID_FOO2, new QoreFoo2(self));
}
//! a method to ...
/**
*/
nothing Foo2::bar() {
foo->bar();
}
Also the Foo class can be directly subclassed in Qore in the same way:
class Foo3 inherits Foo {
bar() {
print("Hello world from Q");
}
}
EDIT
#TMa if you want to call a Qore-language method from C++, then use QoreObject::evalMethodValue() as already mentioned - you are right that qpp does not generate this code for you.
If you want to make sure that the method is implemented in any Qore-language class that inherits the parent class, then make sure to define an abstract Qore method in your qpp file that defines the parent class.

Related

QObject connect fails in Qt

everyone!
I am having a problem using QObject::connect with some custom classes I've created. First of all, I have created 2 classes that inherit from QObject, they are called: Valve and PushButton. They are instantiated inside controllers called PanelController and SynopticController, which are also QObjects. And these controllers are instantiated inside another class called MasterController, also a QObject. I find this information useful since I think it is a problem of referencing the classes or the way I might be instantiating my classes inside these controllers. I strongly think this, because in my main method, when I do the following snippet of code, the connection works:
...
avionics::synoptic::Valve valveTest(nullptr, avionics::synoptic::ValveName::ABV);
avionics::panel::PushButton pushButtonTest(nullptr, avionics::panel::PanelNames::RECIRC);
QObject::connect(&pushButtonTest, &avionics::panel::PushButton::onStateColorChanged, &valveTest, &avionics::synoptic::Valve::updateState);
...
Basically, the controller classes are:
// MasterController
class MasterController : public QObject {
...
private:
panel::PanelController* panelController{nullptr};
synoptic::SynopticController* synopticController{nullptr};
}
// Panel Controller
class PanelController : public QObject {
...
explicit PanelController(QObject *parent = nulptr){
this->pushButtons.append(new avionics::panel::PushButton(_panelController, avionics::panel::PanelNames::RECIRC));
}
private:
QList<avionics::panel::PushButton*> pushButtons{};
}
// SynopticController
class SynopticController : public QObject {
private:
QList<avionics::synoptic::Valve*> iceValves{};
explicit SynopticController(QObject *parent = nullptr) {
antiIcePneumaticLines.append(new avionics::synoptic::PneumaticLine(_synopticController, avionics::synoptic::PneumaticLineName::APU_2_ABV));
}
}
My problem is that when I do the same call for the QObject::connect either from my MasterController constructor or my main method, the signal doesn't call the slot function. I want to connect pushButtons to valves, and to do this I am using getters from my controllers. The call to QObject::connect that doesn't work is:
QObject::connect(panelController->getpushButtons().at(1), &avionics::panel::PushButton::onStateColorChanged, synopticController->getValves().at(1), &avionics::synoptic::Valve::updateState);
// Example of getter
QList<avionics::panel::PushButton*> PanelController::getPushButtons(){
return pushButtons;
}
I've put some prints inside the method that emits the signal and tried debugging it, but the signal is emitted and the slot isn't called. The classes return from the getters are not undefined or null, I've checked it. Let me know if something wasn't clear. Thanks in advance!

How to use protected function setLocalPort?

I should use setlocalport for my socket connection but the property is protected and i have an error of compilation.
This is in qt application.
m_pSocket = new QTcpSocket();
m_pSocket->setLocalPort(m_iLocalPort);
error: ‘void QAbstractSocket::setLocalPort(quint16)’ is protected
If you want to use protected member like a public one, then you should provide a custom class that is the child of the class whose protected method you intend to use. There is nothing that would forbid you to create a child class inheriting QTcpSocket, and then using the protected method you want. Example for the QTcpSocket case that has been described here can be the following.
// Let us define CustomTcpSocket, i.e. the class inheriting QTcpSocket
#pragma once
#include <QTcpSocket>
class CustomTcpSocket
: public QTcpSocket
{
Q_OBJECT
public:
CustomTcpSocket(QObject* parent = nullptr);
virtual ~CustomTcpSocket();
// This method will be used to call QTcpSocket::setLocalPort which is protected.
void SetLocalPort(quint16 port);
};
Then, we provide the implementation itself.
#include "CustomTcpSocket.h"
CustomTcpSocket::CustomTcpSocket(QObject* parent)
: QTcpSocket(parent)
{
}
CustomTcpSocket::~CustomTcpSocket()
{
}
void CustomTcpSocket::SetLocalPort(quint16 port)
{
// Since method is protected, and scope is the child one, we can easily call this method here.
QAbstractSocket::setLocalPort(port);
}
Now we can easily use this newly created class in the following way.
auto customTcpSocketInstance = new CustomTcpSocket();
customTcpSocketInstance->SetLocalPort(123456);
Through usage of polymorphism, instances of CustomTcpSocket should be accepted by other Qt's APIs. However, there is no guarantee it will work as you would expect it to. Qt developers wanted this method to be protected for some of the reasons. So, use it with caution.

Returning managed pointer from a clone method

In C++11, two types of "managed" pointer types were introduced - shared_ptr and unique_ptr. Let's now assume we have a set of classes that support a clone() method, such as foo->clone() would return a copy of the foo object. If your goal was to return a managed pointer from the clone() method, how would you allow the user of the interface to select which kind of pointer he wants to be returned?
As a sub-question, would you rather return a raw pointer from the clone() method and let the user construct either shared_ptr or unique_ptr by himself? If not, why?
The standard smart pointer to manage a dynamic allocation is always unique_ptr. By contrast, shared_ptr is a very specific tool with specialized features (e.g. type-erased deleter, weak pointer observers) and higher costs (virtual dispatch, locked atomic operations) that should only be used when you definitely know you want it. Public raw pointers are a taboo out of principle, and so the natural clone interface looks like this:
struct Base
{
// must have virtual destructor to destroy through base pointer
virtual ~Base() {}
// non-leaf classes are abstract
virtual std::unique_ptr<Base> clone() const = 0;
};
struct Derived : Base
{
virtual std::unique_ptr<Base> clone() const override
{
return std::unique_ptr<Derived>(new Derived(*this));
// or "return std::make_unique<Derived>(*this)" in C++14
}
};
(Unfortunately, we cannot use any kind of covariant return types here, since the template classes unique_ptr<Base> and unique_ptr<Derived> are unrelated. If you prefer to have a clone function that returns the derived type, you could add a non-virtual function like direct_clone that returns a std::unique_ptr<Derived>, and implement the virtual clone() in terms of that.)
Something along this lines would give you the means to select the kind of smart pointer returned. Would probably be better if encapsulated in a mixin Clonable class template, for maintainability and reusability of the idea.
#include <iostream>
#include <memory>
class Base {
public:
virtual ~Base() {
std::cout << "deleting Base\n";
}
template <template <typename ...Args> class SmartPtr>
SmartPtr<Base> clone() {
return SmartPtr<Base>(this->inner_clone());
}
virtual void speak() const = 0;
private:
virtual Base *inner_clone() const = 0;
};
class C: public Base {
public:
~C() {
std::cout << "deleting C\n";
}
template <template <typename ...Args> class SmartPtr>
SmartPtr<C> clone() {
return SmartPtr<C>(this->inner_clone());
}
void speak() const {
std::cout << "I am C and I inherit from Base!\n";
}
private:
C *inner_clone() const override {
return new C(*this);
}
};
// End boilerplate.
int main()
{
auto original = C{};
// the declarations below should use auto, and are just explicitly typed to
// show the correct return type of clone();
std::shared_ptr<C> shared = original.clone<std::shared_ptr>();
std::unique_ptr<C> unique = original.clone<std::unique_ptr>();
// the declarations below show it working through conversion to a base class
// smart pointer type
std::shared_ptr<Base> sharedBase = original.clone<std::shared_ptr>();
std::unique_ptr<Base> uniqueBase = original.clone<std::unique_ptr>();
// the declarations below show it working through the base class for real
std::shared_ptr<Base> sharedBaseFromBase = sharedBase->clone<std::shared_ptr>();
std::unique_ptr<Base> uniqueBaseFromBase = uniqueBase->clone<std::unique_ptr>();
shared->speak();
unique->speak();
sharedBase->speak();
uniqueBase->speak();
sharedBaseFromBase->speak();
uniqueBaseFromBase->speak();
}
Compiles with gcc 4.8.1, and should in any compiler supporting variadics.
I would still prefer to simply return a unique_ptr and move the result into a shared_ptr, which would be automatic since the call to clone() is in itself an rvalue.

Derive UIC generated Qt UI class from custom interface

I've a simple Qt Question. I want that automatically generated UIC files are derived from a custom interface class like in:
Intention
class MyUiInterface {
public:
virtual void setupUi(QWidget* w) = 0;
virtual void retranslateUi(QWidget*w) = 0;
};
Generated UIC file should look like:
class Ui_MyWidget {
public:
void setupUi(QWidget* w) {
...
}
void retranslateUi(QWidget* w) {
...
}
};
namespace Ui {
class MyWidget : public MyUiInterface , public Ui_MyWidget {};
}
Why?
Every Ui::Class would then implement MyUiInterface. In each class that derives from Ui::Class (see The Multiple Inheritance Approach) I would be able to call setupUi and retranslateUi which makes sense if the class that derives from UI::Class class is a base class either. I want every widget to be derived from my abstrcat base class MyWidgetBase. Consider following:
class MyWidgetBase abstract : public QWidget, protected MyUiInterface {
protected:
void changeEvent(QEvent *e) {
QWidget::changeEvent(e);
if (e->type() == QEvent::LanguageChange) {
retranslateUi(this); // Still abstract here
}
}
};
class MyWidget : public MyWidgetBase : public Ui::MyWidget {
};
The effect is, every time MyWidget::changeEvent() is callled, retranslateUi of that specific class is called. Otherwise changeEvent had to be reimplemented in each class. This would be a bit against "code reuse" concept.
I think Qt UIC is not able to handle this situation isn't it? Is there a similar way to solve this problem?
Unfortunately, reading XML Schema for ui files is telling us that this is not possible to automate using uic compiler.
However, it is unclear to me why you would want to implement that automatically - even if the Uic somehow manages to implement your interface, you will still need to add bodies of the functions by hand, editing generated .h file, as I am sure that there is no way to include custom code in xml file which will translate as C++ code.
Why you just don't reimplement setupUi and retranslateUi in your MyWidget class? Every Ui class will have one of these classes, so you can implement this on this level, instead of base class. It is possible that I am missing something, but I see this as an appropriate way to do this.
class MyWidget : public MyWidgetBase, public Ui::MyWidget {
public:
void setupUi(QWidget* w) {
...
}
void retranslateUi(QWidget* w) {
...
}
};
With this approach, you don't need to reimplement changeEvent() in any of your custom widgets, and changeEvent will still call the appropriate retranslateUi().

To mock an object, does it have to be either implementing an interface or marked virtual?

or can the class be implementing an abstract class also?
To mock a type, it must either be an interface (this is also called being pure virtual) or have virtual members (abstract members are also virtual).
By this definition, you can mock everything which is virtual.
Essentially, dynamic mocks don't do anything you couldn't do by hand.
Let's say you are programming against an interface such as this one:
public interface IMyInterface
{
string Foo(string s);
}
You could manually create a test-specific implementation of IMyInterface that ignores the input parameter and always returns the same output:
public class MyClass : IMyInterface
{
public string Foo(string s)
{
return "Bar";
}
}
However, that becomes repetitive really fast if you want to test how the consumer responds to different return values, so instead of coding up your Test Doubles by hand, you can have a framework dynamically create them for you.
Imagine that dynamic mocks really write code similar to the MyClass implementation above (they don't actually write the code, they dynamically emit the types, but it's an accurate enough analogy).
Here's how you could define the same behavior as MyClass with Moq:
var mock = new Mock<IMyInterface>();
mock.Setup(x => x.Foo(It.IsAny<string>())).Returns("Bar");
In both cases, the construcor of the created class will be called when the object is created. As an interface has no constructor, this will normally be the default constructor (of MyClass and the dynamically emitted class, respectively).
You can do the same with concrete types such as this one:
public class MyBase
{
public virtual string Ploeh()
{
return "Fnaah";
}
}
By hand, you would be able to derive from MyBase and override the Ploeh method because it's virtual:
public class TestSpecificChild : MyBase
{
public override string Ploeh()
{
return "Ndøh";
}
}
A dynamic mock library can do the same, and the same is true for abstract methods.
However, you can't write code that overrides a non-virtual or internal member, and neither can dynamic mocks. They can only do what you can do by hand.
Caveat: The above description is true for most dynamic mocks with the exception of TypeMock, which is different and... scary.
From Stephen Walther's blog:
You can use Moq to create mocks from both interfaces and existing classes. There are some requirements on the classes. The class can’t be sealed. Furthermore, the method being mocked must be marked as virtual. You cannot mock static methods (use the adaptor pattern to mock a static method).

Resources