Code:
prog.h
public:
virtual bool init();
static cocos2d::CCScene* scene();
CREATE_FUNC(ProgScene);
void spriteMoveFinished(CCNode* sender);
void endCallback(CCObject* pSender);
void endCallbackWork(CCNode* pSender);
prog.cpp
void ProgScene::spriteMoveFinished(CCNode* sender)
{
CCMessageBox("Sprite Move Finished","Sprite Move Finished");
this->runAction(CCCallFuncN::actionWithTarget( this, callfuncN_selector(ProgScene::endCallbackWork))); // WORK
// this->runAction(CCCallFuncN::actionWithTarget( this, callfuncN_selector(ProgScene::endCallback))); // NOT WORK
}
void ProgScene::endCallback(CCObject* pSender)
{
...
CCMessageBox("From endCallback","From endCallback");
}
void ProgScene::endCallbackWork(CCNode* sender)
{
...
CCMessageBox("from endCallbackWork","from endCallbackWork");
}
I'm a beginner in cpp, please help me.
How can i call method endCallback from method actionWithTarget ?
When i use
this->runAction(CCCallFuncN::actionWithTarget( this, callfuncN_selector(ProgScene::endCallback)));
it returns:
error C2440: 'type cast' : cannot convert from 'void (__thiscall ProgScene::* )(cocos2d::CCObject *)' to 'cocos2d::SEL_CallFuncN'
1> Pointers to members have different representations; cannot cast between them
endCallbackWork is good working with
this->runAction(CCCallFuncN::actionWithTarget( this, callfuncN_selector(ProgScene::endCallbackWork)));
Maybe I can use another way than the following ?
this->runAction(CCCallFuncN::actionWithTarget( this, callfuncN_selector(ProgScene::endCallback)));
Related
I am trying to use a timer to repeatedly change the PWM Output over time to have a smooth transition when the brightness changes. I keep getting this error when trying to compile the code:
/Users/jt/Documents/Arduino/libraries/SingleColorLight/SingleColorLight.cpp: In constructor 'CSingleColorLight::CSingleColorLight(int)':
/Users/jt/Documents/Arduino/libraries/SingleColorLight/SingleColorLight.cpp:13:58: error: cannot convert 'CSingleColorLight::DimmerCallback' from type 'void (CSingleColorLight::)(void*)' to type 'void ()(void)'
ets_timer_setfn(&Dimmer, this->DimmerCallback, NULL);
Here is my code:
class CSingleColorLight {
private:
int pin;
int intensitySetPoint;
int intensityActual;
int percentageBuffer;
ETSTimer Dimmer;
int dimmerCount;
public:
CSingleColorLight(int _pin);
bool setIntensity(int _intensity);
int getIntensity();
bool getStatus(void);
bool setStatus(bool _status);
void DimmerCallback(void*);
};
and in the cpp file:
void CSingleColorLight::DimmerCallback(void*) {
if(dimmerCount>0){
dimmerCount--;
intensityActual++;
} else if(dimmerCount<0){
dimmerCount++;
intensityActual--;
} else {
ets_timer_disarm(&Dimmer);
}
analogWrite(pin, percentageToTime[intensityActual]);
return;
}
It asks for a pointer, right? Any idea how to fix this?
Thanks a lot!
If you want DimmerCallback to take a void* argument, then you need to name it, like
void CSingleColorLight::DimmerCallback(void* x)
but you are not using the void* in the code. It looks like you should just get rid of it, so it would be
void CSingleColorLight::DimmerCallback()
int the cpp and
void DimmerCallback();
in the header.
A void* argument is a pointer that can point to any data type, it is not the same as void which is just no argument.
I think I have misunderstood how function pointers work. In this example:
class Helper
{
public:
typedef void (*SIMPLECALLBK)(const char*);
Helper(){};
void NotifyHelperbk(SIMPLECALLBK pCbk)
{ m_pSimpleCbk = pSbk; }
private:
SIMPLECALLBK m_pSimpleCbk;
}
// where i call the func
class Main
{
public:
Main(){};
private:
Helper helper
void SessionHelper(const char* msg);
}
Main.cpp
void Main::SessionHelper(const char* msg)
{
....
}
helper.NotifyHelperbk(&Main::SessionHelper);
I get the following error:
error C2664: 'Main::NotifyHelperbk' : cannot convert parameter 1 from 'void (__thiscall Main::* )(const char *)' to 'Helper::SIMPLECALLBK'
1> There is no context in which this conversion is possible
What am I missing here?
Main::SessionHelper is a non static method. So add static to it to be able to use it as function pointer. Or use member method pointer (you will need a instance to call it).
if you use c++11 you can use std::bind
class Helper
{
public:
void NotifyHelperbk(std::function<void(char*)> func){
/* Do your stuff */
func("your char* here");
}
And your main :
Main.cpp
Main m;
helper.NotifyHelperbk(std::bind(&Main::SessionHelper, m, std::placeholder_1));
I'm trying to use a boost::lockfree queue to manage tasks. These tasks retrieve data and would be processed on a worker thread. Once data is retrieved, a signal should be sent to the main thread with the data. The worker thread is spawned at the start of the application and just keeps polling the queue. I'm new to Boost::Asio but from my research, it seems to be the best mechanism for sending signals between threads.
I've looked at several examples, in particular:
Confused when boost::asio::io_service run method blocks/unblocks
boost asio post not working , io_service::run exits right after post
Here is my code:
#include "stdafx.h"
#include <thread>
#include <boost/asio.hpp>
#include <boost/bind.hpp>
#include <boost/lockfree/spsc_queue.hpp>
#include <boost/optional.hpp>
#include <boost/thread.hpp>
#include <boost/signals2.hpp>
typedef boost::signals2::signal<void(int)> signal_type;
class Task
{
public:
Task(int handle) : _handle(handle) {};
~Task() {};
virtual void Execute()
{
int result = _handle * 2;
}
private:
int _handle;
};
class Manager
{
public:
Manager()
{
_mainService = std::make_shared<boost::asio::io_service>();
_workerService = std::make_shared<boost::asio::io_service>();
_work = std::make_shared<boost::asio::io_service::work>(*_workerService);
_threadStarted = false;
Start();
};
~Manager() {};
void WorkerMain()
{
_workerService->poll();
}
void Start()
{
if (_threadStarted) return;
_workerThread = std::thread(&Manager::WorkerMain, this);
_threadStarted = true;
}
void Stop()
{
if (_threadStarted == false) return;
_mainService->stop();
_workerThread.join();
_mainService.reset();
}
void OnSignalFetchCompleted(int value)
{
int asdf = 0; //do stuff with data on main thread
}
void ProcessData(signal_type& signal)
{
int i = 0;
do
{
_queue.consume_one([&](std::shared_ptr<Task> task)
{
task->Execute();
//get data from task; send out signal with data
});
i++;
} while (i < 3);
}
void QueueData(int handle)
{
_signalFetchCompleted.connect(boost::bind(&Manager::OnSignalFetchCompleted, this, _1));
_workerService->post(boost::bind(&Manager::ProcessData, boost::ref(_signalFetchCompleted))); //!!does not compile
std::shared_ptr<Task> task = std::make_shared<Task>(handle);
_queue.push(task);
}
private:
boost::lockfree::spsc_queue<std::shared_ptr<Task>, boost::lockfree::capacity<1024>> _queue;
std::thread _workerThread;
bool _threadStarted;
std::shared_ptr<boost::asio::io_service> _mainService;
std::shared_ptr<boost::asio::io_service> _workerService;
std::shared_ptr<boost::asio::io_service::work> _work;
signal_type _signalFetchCompleted;
};
int _tmain(int argc, _TCHAR* argv[])
{
std::shared_ptr<Manager> mgr = std::make_shared<Manager>();
mgr->QueueData(5);
mgr->QueueData(10);
mgr->Stop();
return 0;
}
I'm getting a compile error on the _workerService->Post line that I haven't been able to resolve:
1>C:\Boost\boost/bind/mem_fn.hpp(333): error C2784: 'T *boost::get_pointer(const boost::scoped_ptr<T> &)' : could not deduce template argument for 'const boost::scoped_ptr<T> &' from 'const signal_type'
1> C:\Boost\boost/smart_ptr/scoped_ptr.hpp(150) : see declaration of 'boost::get_pointer'
1> C:\Boost\boost/bind/mem_fn.hpp(352) : see reference to function template instantiation 'R (__cdecl &boost::_mfi::dm<R,Manager>::call<const U>(U &,const void *) const)' being compiled
1> with
1> [
1> R=void (signal_type &)
1> , U=signal_type
1> ]
1> C:\Boost\boost/bind/mem_fn.hpp(352) : see reference to function template instantiation 'R (__cdecl &boost::_mfi::dm<R,Manager>::call<const U>(U &,const void *) const)' being compiled
1> with
1> [
1> R=void (signal_type &)
1> , U=signal_type
1> ]
1> C:\Boost\boost/bind/bind.hpp(243) : see reference to function template instantiation 'R (__cdecl &boost::_mfi::dm<R,Manager>::operator ()<T>(const U &) const)' being compiled
1> with
1> [
1> R=void (signal_type &)
1> , T=signal_type
1> , U=signal_type
1> ]
Any help resolving this compile error or general comments on this approach would be greatly appreciated. Thanks.
In light of new information, the problem is with your boost::bind. You are trying to call a member function without an object to call it on: you are trying to call ProcessData but you haven't told the bind on which object you wish to call it on. You need to give it a Manager to call it on:
_workerService->post(boost::bind(&Manager::ProcessData, this, boost::ref(_signalFetchCompleted)));
This will call ProcessData on this and pass in a reference to _signalFetchCompleted
The compiler error seems to be talking about you constructing a boost::asio::io_service::work object and that you are passing it incorrect parameters:
error C2664: 'boost::asio::io_service::work::work(const boost::asio::io_service::work &)' : cannot convert argument 1 from 'std::shared_ptr<boost::asio::io_service>' to 'boost::asio::io_service &'
boost::asio::io_service::work has a constructor which takes a boost::asio::io_service& and a copy constructor; however, you are passing it a std::shared_ptr<boost::asio::io_service>:
_work = std::make_shared<boost::asio::io_service::work>(_workerService);
Here, _workerService is a std::shared_ptr<boost::asio::io_service>, but you need a boost::asio::io_service&. Try the following instead:
_work = std::make_shared<boost::asio::io_service::work>(*_workerService);
I think that boost::asio is not the best solution for your task. Have you read about conditional variables? They are much more simple and can be used to achieve your goal.
I have a C++ API with a cThread class, and this method to create a thread:
void cThread::start(void(*a_function)(void), CThreadPriority a_level);
I've done a class and a init() method to launch a thread and an updateHaptics() method to be executed by the thread:
void EntryClass::init()
{
typedef void (EntryClass::*method)();
method p;
p = &EntryClass::updateHaptics;
// create a thread which starts the main haptics rendering loop
cThread* hapticsThread = new cThread();
hapticsThread->start(p, CTHREAD_PRIORITY_HAPTICS);
}
void EntryClass::updateHaptics(void)
{
// ...
}
My problem is to pass the updateHaptics() method as an argument to the cThread::start() method.
I've got this error:
1>EntryClass.cpp(55): error C2664: 'void chai3d::cThread::start(void (__cdecl *)(void *),const chai3d::CThreadPriority,void *)' : impossible de convertir l'argument 1 de 'method' en 'void (__cdecl *)(void)'
REM: I'm under Windows 8/Visual Studio
The signature you indicated
void(*a_function)(void)
is for a function, not for a class method. A static method will work too
Note the difference with the typedef you used:
void (EntryClass::*method)();
The definition could be:
class EntryClass {
public:
void init();
static void updateHaptics(); // <--- NOTE the static
};
and your implementation
void EntryClass::init()
{
typedef void (*method)(); // <---- NOTE THIS CHANGE
method p;
p = &EntryClass::updateHaptics;
// create a thread which starts the main haptics rendering loop
cThread* hapticsThread = new cThread();
hapticsThread->start(p, CTHREAD_PRIORITY_HAPTICS);
}
void EntryClass::updateHaptics(void)
{
// ...
}
As I know, we can use only static function as a thread proc. Yes we can pass class static function also.
I'm trying to create a C++ application using SDL and SDL_Mixer for audio, and am trying to follow this tutorial. However, using SDL_Mixer's Mix_HookMusicFinished() isn't working, giving the error: argument of type 'void (CApp::)()' does not match 'void (*)()'
I've researched this error, and it seems the problem is that cleanMusic is a member function of CApp. I can't tell how to solve the problem, however, since most problems similar to this one are centered around pthread_create(). My cleanMusic() function needs to be able to access music_ which is a private variable of CApp. How can I resolve the error?
Here is the code for CApp.h, CApp::handleKeyEvents(), and CApp::cleanMusic(). Let me know if you need to see something else.
CApp.h
#ifndef CAPP_H
#define CAPP_H
#include <SDL.h>
#include <SDL_mixer.h>
#include <gl\gl.h>
#include <gl\glu.h>
class CApp {
private:
bool isRunning_;
private:
void cleanMusic();
private:
SDL_Surface *surfDisplay_;
Mix_Music *music_;
bool isRotating_;
GLfloat rQuad_;
public:
CApp();
int run();
public:
bool initialize();
void handleEvents(SDL_Event *event);
void loopData();
void render();
void clean();
public:
void handleKeyEvents(SDL_KeyboardEvent *key);
};
#endif // CAPP_H
CApp::handleKeyEvents()
#include "CApp.h"
void CApp::handleKeyEvents(SDL_KeyboardEvent *key) {
switch(key->keysym.sym) {
case SDLK_m:
if (key->state == SDL_PRESSED) {
if(music_ == NULL) {
music_ = Mix_LoadMUS("resources\\audio\\boop.wav");
Mix_PlayMusic(music_, 0);
Mix_HookMusicFinished(cleanMusic);
isRotating_ = true;
} else {
Mix_HaltMusic();
cleanMusic();
isRotating_ = false;
}
}
break;
default:
break;
}
}
CApp::cleanMusic()
#include "CApp.h"
void CApp::cleanMusic() {
Mix_FreeMusic(music_);
music_ = NULL;
}
Two changes. cleanMusic needs to be static.
static void cleanMusic();
Second, you register the hook with:
Mix_HookMusicFinished(&CApp::cleanMusic);
Since your method is now static, music_ needs to be static as well.
static Mix_Music *music_;
This means that there will only be one instance of this variable shared between all instantiations of CApp. Since I haven't seen all of your code, I can't tell if this is an issue.
void cleanMusic(); is what is known as a member function. A member function is very different from a normal function. The reason your compiler complains is because Mix_HookMusicFinished expects a normal function pointer of type void (*)(), but you are trying to pass a member function pointer of type void (CApp::*)(). These types are incompatible.
The simplest solution is just to make cleanMusic a normal function and Mix_Music *music; a global:
Mix_Music *music;
void cleanMusic() {
Mix_FreeMusic(music);
music = NULL;
}
Another way is to make them both static members:
static void cleanMusic();
static Mix_Music *music_;