pass argv[] from main to other class - constructor

Hi I have a question about passing argv[] value to the other class. In my code, I want to pass the argv[1] parameter from cmd to the class mainWindow to trigger spacific event. Here is the code. #include "MainWindow.h"
int main(int argc, char *argv[])
{
#if _DEBUG
// Do not print memory leaks at end of program (QtWebKit causes a large number of them, see Menu class)
_CrtSetDbgFlag(_crtDbgFlag &~ _CRTDBG_LEAK_CHECK_DF);
#endif
QApplication app(argc, argv);
app.setApplicationName("Example_Qt");
MainWindow window;
window.show();
return app.exec();
}
MainWindow.cpp
MainWindow::MainWindow() :
m_pCurrentTutorial(0),
m_pCurrentTutorialAREL(0)
{
setupUi(this);
quitTutorialButton->setVisible(false);
QObject::connect(quitTutorialButton, SIGNAL(clicked()), this, SLOT(onQuitTutorialButtonClicked()));
m_pMenu = new Menu(this, this);
// Init the main view for the scene using OpenGL
QGLWidget *glWidget = new QGLWidget(QGLFormat(QGL::SampleBuffers));
m_pGraphicsView = graphicsView;
m_pGraphicsView->setScene(m_pMenu);
m_pGraphicsView->setViewport(glWidget);
m_pGraphicsView->setFrameShape(QFrame::NoFrame);
// Do not show context menu in web view
m_pGraphicsView->setContextMenuPolicy(Qt::NoContextMenu);
}
MainWindow::~MainWindow()
{
delete m_pMenu;
m_pMenu = 0;
delete m_pGraphicsView;
m_pGraphicsView = 0;
}
Mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <vector>
#include <QVBoxLayout>
#include <QWidget>
#include <QWebView>
class TutorialBase;
class TutorialBaseAREL;
#include "Menu.h"
#include "ui_MainWindow.h"
QT_BEGIN_NAMESPACE
class QGraphicsView;
class QBoxLayout;
QT_END_NAMESPACE
class MainWindow : public QMainWindow, public Ui::MainWindow, public Menu::TutorialSelectionCallback
{
Q_OBJECT
public:
MainWindow();
virtual ~MainWindow();
QBoxLayout* getButtonBar();
protected slots:
void onQuitTutorialButtonClicked();
protected:
void keyPressEvent(QKeyEvent *event);
void quitTutorialIfAny();
void startTutorial(int tutorialNumber);
void startTutorialAREL(int tutorialNumber);
TutorialBase* m_pCurrentTutorial;
TutorialBaseAREL* m_pCurrentTutorialAREL;
QGraphicsView* m_pGraphicsView;
Menu* m_pMenu;
};
#endif
Could anyone help me to pass the parameter from the argv[] to mainwindow.cpp ?
Many thanks
Ying

You should be able to just provide another constructor (or replace the current one) which takes a single char * argument, such as:
MainWindow::MainWindow (char *arg) :
m_pCurrentTutorial(0),
m_pCurrentTutorialAREL(0)
{
// body here, including checking argument, such as:
if (strcmp (arg, "-help") == 0) {
provideHelp();
}
}
and then use that constructor when creating your object:
MainWindow window (argv[1]);
Be aware that this new constructor will need to be listed in the class (in Mainwindow.h), not just added as a function to Mainwindow.cpp:
public:
MainWindow();
MainWindow(char*);
virtual ~MainWindow();

Related

A class member function calling from other class member function (arduino)

I am developing nema stepper motor driver interfacing with arduino. I created a class. I named it Axis. I want to create an axis object for each motor with this class. but, I can not call the attachInterrupt function in the arduino.h from the class. It return this error :
In member function 'void Axis::setReverseInt()':
parsstep.cpp:12:77: error: invalid use of non-static member function 'void Axis::revDirection()'
attachInterrupt(digitalPinToInterrupt(reverseDirPin), revDirection, RISING);
Axis::Axis()
{
}
Axis::~Axis()
{
}
void Axis::setReverseInt () {
attachInterrupt(digitalPinToInterrupt(reverseDirPin), revDirection, RISING);
}
void Axis::setStopInt () {
//attachInterrupt(digitalPinToInterrupt(stopPin), stopMotor, RISING);
}
void Axis::revDirection()
{
dirMode = !dirMode;
}
void Axis::stopMotor()
{
moveMotor = !moveMotor;
}
void Axis::startMotor()
{
moveMotor = true;
}
void Axis::moveStep(int pulseRev, byte laps, boolean dir)
{
digitalWrite(dirPin, dir);
int totalPulse = pulseRev * laps;
for (int i = 0; i < totalPulse; i++)
{
speedValue = map((analogRead(speedPin)), 0, 1023, 2000, 10);
digitalWrite(pulsePin, HIGH);
delayMicroseconds(speedValue);
digitalWrite(pulsePin, LOW);
delayMicroseconds(speedValue);
}
}
I faced a similar issue when writing my own libraries for a big project I've been working on. It happened to me while configuring interrupts inside a method. I found a workaround that while it might seem a bit more complex, it does the trick. In my case, I used it for reading a rotary encoder its switch.
What I used is a pointer to an ISR handler and a method to call it. On your setup function you can call the initialization of the ISR service.
First, in your .h file declare the following methods (in addition to your own):
void init();
static void ISRHandler();
void setupISRHandler(uint8_t pin, void (*ISR)(void), int state); // this will configure your ISR
and a pointer:
static Axis *_ISRPointer; // can be declared as private (like in here from the '_' prefix)
Then, in your .cpp file you use it like this:
#include "Axis.h"
Axis *Axis::_ISRPointer = nullptr;
you will initialize the ISR handler during the setup using the init method:
void Axis::init(){
setupISRHandler(reverseDirPin, Axis::ISRHandler, RISING);
}
the setup method looks like:
void Axis::setupISRHandler(uint8_t pin, void (*ISRFunction)(void), int state){
attachInterrupt(digitalPinToInterrupt(pin), ISRFunction, state);
}
the ISRHandler is in charge of calling the ISR routine:
void Axis::ISRHandler(){
_ISRPointer-> revDirection();
}
void Axis::revDirection(void){
// Do not forget to disable interrupts
cli();
// your routine goes here
dirMode= !dirMode;
sei();
}
Therefore, you will do something like this in your main .ino file:
#include "Axis.h"
#include <whateverotherlibraryyouneed.h>
Axis ax = Axis(); // your new object
void setup(){
ax.init();
ax.startMotor();
}
void loop(){
if(day == SUNNY){
ax.moveStep(100, 2 , CLOCKWISE);
} else {
ax.stopMotor();
}
ax.someOtherMethodToControlTheMotor(anyArgumentYouWant);
}
I hope that my convoluted solution helps
Cheers
Dr. Daniel

AdMob Interstitial Cocos2d-x WP8

Can enyone tell me how to call AdMob Interstitial between scenes in my cocos2d-x game?
I have tried this http://robwirving.com/2014/07/21/calling-c-methods-c-winrt-components/ guide, but i don't know how to run it from cocos classes.
Is there any another ways, or some guides?
I've recently made it. You have to do few things. First of all create helper class, which will help you calling native function (I use this for all 3 platforms, but here's just windows phone):
NativeHelper.h:
#ifndef __NATIVE_HELPER_H_
#define __NATIVE_HELPER_H_
#include <string>
#include <functional>
#include "cocos2d.h"
using namespace std;
USING_NS_CC;
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
namespace cocos2d
{
public delegate void CSharpShowInterstitialDelegate();
public ref class WP8NativeEventHelper sealed
{
public:
void WP8NativeEventHelper::SetCSharpShowInterstitialDelegate(CSharpShowInterstitialDelegate^ delegate){
m_CSharpShowInterstitialDelegate = delegate;
}
void CallShowInterstitial();
private:
property static CSharpShowInterstitialDelegate^ m_CSharpShowInterstitialDelegate;
};
}
#endif
class NativeHelper
{
public:
static void showInterstitial(string adSdk);
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
WP8NativeEventHelper^ wp8helper;
#endif
//instance required only for setting callback
static NativeHelper* getInstance();
~NativeHelper()
{
instanceFlag = false;
}
private:
static bool instanceFlag;
static NativeHelper* instance;
NativeHelper() {};
};
#endif // __NATIVE_HELPER_H_
So. We have special C++/CX class Wp8NativeEventHelper, which can "talk" with C#. Here we store a delegate.
How it works:
C# is calling SetCSharpShowInterstitialDelegate and passes a delegate to it, which will be remembered in static property.
Then C++\CX can call it using CallShowInterstitial.
Now NativeHelperWP.cpp:
#if (CC_TARGET_PLATFORM == CC_PLATFORM_WP8)
#ifndef __NATIVE_HELPER_WP_H_
#define __NATIVE_HELPER_WP_H_
#include "NativeHelper.h"
void WP8NativeEventHelper::CallShowInterstitial(){
if (m_CSharpShowInterstitialDelegate)
{
m_CSharpShowInterstitialDelegate->Invoke();
}
}
bool NativeHelper::instanceFlag = false;
NativeHelper* NativeHelper::instance = NULL;
NativeHelper* NativeHelper::getInstance()
{
if(!instanceFlag){
instance = new NativeHelper();
instanceFlag = true;
instance->wp8helper = ref new WP8NativeEventHelper();
}
return instance;
}
void NativeHelper::showInterstitial(){
NativeHelper::getInstance()->wp8helper->CallShowInterstitial();
}
#endif
#endif
Here is just an implementation of CallShowInterstitial. Also in NativeHelper::showInterstitial we're calling C++/CX, which later calls c#.
Now c# code (MainPage.xaml.cs):
outside namespace:
using GoogleAds;
inside class:
private InterstitialAd interstitialAd;
in constructor:
WP8NativeEventHelper helper = new WP8NativeEventHelper();
helper.SetCSharpShowInterstitialDelegate(showInterstitial);
and also create showInterstitial function:
public void showInterstitial() //we recreate interstitial each time, because otherwise it'll show only once, only new requests won't work
{
interstitialAd = new InterstitialAd("MY_AD_UNIT_ID");
AdRequest adRequest = new AdRequest();
#if DEBUG
// Enable test ads.
adRequest.ForceTesting = true;
#endif
interstitialAd.ReceivedAd += OnAdReceived;
interstitialAd.LoadAd(adRequest);
}
and finally OnAdReceived:
private void OnAdReceived(object sender, AdEventArgs e)
{
System.Diagnostics.Debug.WriteLine("Ad received successfully");
interstitialAd.ShowAd();
}
Follow this guide to setup admob: https://developers.google.com/mobile-ads-sdk/docs/admob/wp/quick-start
Now let's use this.
In HelloWorldScene.h add:
#include "NativeHelper.h"
In HelloWorldScene.cpp:
NativeHelper::showInterstitial();
The same way you can show/hide/change position of admob banner for example (however it's buggy so I'm using ad mediation).

Why Can't I override draw method from cocos2d::sprite?

I need to override draw method from sprite to apply some custom stuff, but it doesnt hit my draw override at all. I'm pretty sure I am doing it correctly:
.h file:
virtual void draw(cocos2d::Renderer* renderer, const cocos2d::Mat4& transform, bool transformUpdated);
.cpp file:
void CustomSprite::draw(cocos2d::Renderer* renderer, const cocos2d::Mat4& transform, bool transformUpdated)
{
int x = 0; //breakpoint here
}
my class is
#include "cocos2d.h"
class CustomSprite : public cocos2d::Sprite
{
The solution was:
in .h:
virtual void draw(cocos2d::Renderer *renderer, const cocos2d::Mat4 &transform, uint32_t flags) override;
in .cpp:
void EnergyManager::draw(cocos2d::Renderer* renderer, const cocos2d::Mat4& transform, uint32_t flags)
thanks to Kobyle

Create Splash screen in cocos 2d-x

Hello I am creating an game in cocos2d-x and when I am scheduling an event on splash screen for run game .It shows compilation error (in expansion of macro 'schedule_selector')
Following is my code for this
Splash.h
#ifndef SPLASH_H_
#define SPLASH_H_
#include "cocos2d.h"
class CCSplashLayer : public cocos2d::CCLayer {
private :
void runGame();
public:
static cocos2d::CCScene* createScene();
virtual bool init();
CREATE_FUNC(CCSplashLayer);
};
#endif /* SPLASH_H_ */
And SplashScene.cpp
#include "splash.h"
#include "cocos2d.h"
#include "HelloWorldScene.h"
USING_NS_CC;
bool CCSplashLayer::init() {
if (!Layer::init()) {
return false;
}
Size visibleSize = Director::getInstance()->getVisibleSize();
auto sprite = Sprite::create("splash.png");
sprite->setScale(Director::getInstance()->getContentScaleFactor());
sprite->setPosition(Vec2(visibleSize.width / 2,visibleSize.height/2));
this->addChild(sprite, 0);
//This line cause problem show i symbol on this line in eclipse
this->scheduleOnce(schedule_selector(CCSplashLayer::runGame),4.0f);
return true;
}
Scene* CCSplashLayer::createScene() {
auto scene = CCScene::create();
auto layer = CCSplashLayer::create();
scene->addChild(layer);
return scene;
}
void CCSplashLayer::runGame(){
auto scene = HelloWorld::createScene();
Director::getInstance()->setDepthTest(true);
TransitionScene *transition = TransitionScene::create(0.5f, scene);
Director::getInstance()->pushScene(transition);
}
schedule_selector takes function pointer which needs a float argument for time.
Change method CCSplashLayer::runGame() to CCSplashLayer::runGame(float dt) in defination and declaration.
Also you are pushing a scene over splash scene, which is not recommended way for splash scene. You must replace splash scene with new scene because we never need to display splash again in game unless there is specific design requirement of game.
Try this macro:
#define CCDL_PERFORM_SELECTOR( __OWNER__, __DELAY__, __CALLFUNC_SELECTOR__ ) \
__OWNER__->runAction( cocos2d::Sequence::create( \
cocos2d::DelayTime::create( __DELAY__ ), \
cocos2d::CallFunc::create( CC_CALLBACK_0( __CALLFUNC_SELECTOR__,__OWNER__) ), \
nullptr )); \
(source: https://github.com/duksel/Cocos2dx-DukselLib/blob/master/Cocos2dx-DukselLib/DukselMacros.h#L70-L74)
Allow to use for any CCNode (+subclass) instance.
In your case will be:
bool CCSplashLayer::init()
{
CCDL_PERFORM_SELECTOR( this, 4.f, CCSplashLayer::runGame );
}
try like this...
in init method,
this->runAction(CCSequence::create(CCDelayTime::create(4.0f),
CCCallFuncN::create(this,callfuncN_selector(CCSplashLayer::runGame)),
NULL));
and add this method.
void CCSplashLayer::runGame(){
auto scene = HelloWorld::createScene();
Director::getInstance()->setDepthTest(true);
TransitionScene *transition = TransitionScene::create(0.5f, scene);
Director::getInstance()->pushScene(transition);
}

CCBMemberVariableAssigner callbacks disfunctional for custom CCTableViewCell in CocosBuilder

my goal is to design a CCTableViewCell via CocosBuilder
and load it via CCBReader.
My steps so far:
I added a new non-fullscreen CCNode TestCell.ccb in cocosbuilder,
set the root's custom class to TestCell
and added a CCSprite as the roots child while setting
it's doc-root-var to bg.
My problem: after implementing a loader TestCellLoader
as well as the Cell TestCell the callback-function
TestCell::onAssignCCBMemberVariable is not called at all.
What I tried:
Using a CCLayerLoader instead of a CCNodeLoader worked for me so far,
this is the first time I'm using a CCNodeLoader so maybe I missed
a crucial point.
Thank you,
Ciao!
Ben
Here are the codes:
TestCellLoader.h
#include <cocos2d.h>
#include "cocos-ext.h"
#include "TestCell.h"
using namespace cocos2d;
using namespace cocos2d::extension;
class TestCellLoader : public CCNodeLoader
{
public:
CCB_STATIC_NEW_AUTORELEASE_OBJECT_METHOD(TestCellLoader, create);
protected:
CCB_VIRTUAL_NEW_AUTORELEASE_CREATECCNODE_METHOD(TestCell);
virtual CCNode* loadCCNode(CCNode *, CCBReader * pCCBReader);
};
TestCellLoader.cpp
#include "TestCellLoader.h"
CCNode * TestCellLoader::loadCCNode(CCNode * pParent, CCBReader * pCCBReader)
{
CCLOG("TestCell::loadCCNode");
CCNode * ccNode = this->createCCNode(pParent, pCCBReader);
return ccNode;
}
TestCell.h
class TestCell : public CCTableViewCell, public CCNodeLoaderListener, public CCBMemberVariableAssigner
{
public:
TestCell();
virtual ~TestCell();
static TestCell *create();
virtual bool init();
virtual bool initWithBG(CCSprite* bg);
static TestCell* cellWithBG(CCSprite* bg);
// ccbuilder callbacks
virtual bool onAssignCCBMemberVariable(cocos2d::CCObject * pTarget, const char * pMemberVariableName, cocos2d::CCNode * pNode);
virtual void onNodeLoaded(cocos2d::CCNode * pNode, cocos2d::extension::CCNodeLoader * pNodeLoader);
private:
CC_PROPERTY(CCSprite*, bg, Bg);
};
TestCell.m
#include "TestCell.h"
using namespace cocos2d;
using namespace cocos2d::extension;
TestCell::TestCell(){}
TestCell::~TestCell(){}
#pragma mark creation
TestCell* TestCell::create(){
TestCell *pRet = new TestCell();
pRet->init();
pRet->autorelease();
return pRet;
}
bool TestCell::init(){
return true;
}
bool TestCell::initWithBG(CCSprite* bg){
return true;
}
TestCell* TestCell::cellWithBG(CCSprite* bg){
return new TestCell;
}
#pragma mark - synthesize
void TestCell::setBg(cocos2d::CCSprite *sprite){
this->bg = sprite;
}
CCSprite* TestCell::getBg(){
return this->bg;
}
#pragma mark - ccbuilder callbacks
void TestCell::onNodeLoaded(cocos2d::CCNode * pNode, cocos2d::extension::CCNodeLoader * pNodeLoader)
{
CCLOG("TestCell::onNodeLoaded");
}
bool TestCell::onAssignCCBMemberVariable(CCObject* pTarget, const char* pMemberVariableName, CCNode* pNode)
{
CCLOG("TestCell::onAssignCCBMemberVariable %s", pMemberVariableName);
return false;
}
I guess you used a CCLayer as TestCell.ccb's Root object type. Since when you are creating a new ccb file, CCLayer is as default option.
And this is why you use a CCLayerLoader instead of a CCNodeLoader worked.
So change your TestCell.ccb's Root object type to CCNode, this maybe works.