CCFiniteTimeAction::getDuration() EXC_BAD_ACCESS when creating a CCSequence - c++

I was able to run this code without getting an error on the iPhone simulator. However, when I run it on my iPhone, I am getting a EXC_BAD_ACCESS error. Here is the code:
CCAnimate * explosionAnimate = CCAnimate::create(explosionAnimation);
CCCallFuncN * callFuncN = CCCallFuncN::create(this,callfuncN_selector(GameLayer::removeChildFromParent));
CCFiniteTimeAction * explosionSequence = CCSequence::create(explosionAnimate, callFuncN);
CCSprite * explosionSprite = CCSprite::createWithSpriteFrameName("explosion_frame_1");
addChild(explosionSprite);
explosionSprite->setPosition(point);
explosionSprite->runAction(explosionSequence);
}
void GameLayer::removeChildFromParent(CCNode * child)
{
child->removeFromParent();
}
The error occurs when CCSequence::create(...) is called. Debugging through CCSequence::create(...)
CCFiniteTimeAction* CCSequence::create(CCFiniteTimeAction *pAction1, va_list args)
{
CCFiniteTimeAction *pNow;
CCFiniteTimeAction *pPrev = pAction1;
while (pAction1)
{
pNow = va_arg(args, CCFiniteTimeAction*);
if (pNow)
{
pPrev = createWithTwoActions(pPrev, pNow);
}
else
{
break;
}
}
return pPrev;
}
I am seeing that "createWithTwoActions" get's called twice. That doesn't seem right. On the 2nd call to "createWithTwoActions". The error occurs within CCFiniteTimeAction, specifically at the getDuration() inline function:
inline float getDuration(void) { return m_fDuration; }
Any ideas why this would be occurring?

I was able to resolve the issue by calling CCSequence::create() like:
CCSequence::create(explosionAnimate, callFuncN, NULL);
instead of:
CCSequence::create(explosionAnimate, callFuncN);
I'm guessing this has to do with the nature of CCFiniteAction pointers and C++ variable length arguments.

Related

C# Else confusion

so i keep gettin an error on (else) and im not to sure what i did wrong, i cant seem to find the problem, please help, im pretty new to coding so heres the entire code i have so far
{
public float speed;
private Rigidbody2D myRigidbody;
private Vector3 change;
private Animator animator;
// Start is called before the first frame update
void Start()
{
animator = GetComponent<Animator>();
myRigidbody = GetComponent<Rigidbody2D>();
}
// Update is called once per frame
void Update()
{
change = Vector3.zero;
change.x = Input.GetAxisRaw("Horizontal") * Time.deltaTime * speed;
change.y = Input.GetAxisRaw("Vertical") * Time.deltaTime * speed;
if (change != Vector3.zero)
transform.Translate(new Vector3(change.x, change.y));
MoveCharacter();
UpdateAnimationAndMove();
}
void UpdateAnimationAndMove()
{
{
animator.SetFloat("moveX", change.x);
animator.SetFloat("moveY", change.y);
animator.SetBool("moving", true);
} else {
animator.SetBool("moving", false);
}
}
void MoveCharacter()
{
myRigidbody.MovePosition(transform.position + change.normalized * speed * Time.deltaTime);
}
}
You can't use else, without a corresponding if before it.
if(condition)
{
// IF condition is true, this gets executed
}
else
{
// ELSE this gets executed
}

make_fcontext/jump_fcontext used with shared stack

Is there a way to use boost context make_fcontext/jump_fcontext with a shared stack to share coroutine memory by saving/restoring the stack ?
It seems that make_fcontext and jump_fcontext write on the stack themselves and I get crashes when trying to save/restore stack on yield/resume, but it is really hard for me to get what happens as make_fcontext/jump_fcontext are pure assembly code.
Here is the coroutine methods which trigger segmentation fault (the same code works very well if I use a different stack for each coroutine and I don't use the saveStack/restoreStack)
void resume()
{
if (yielded)
{
restoreStack();
yielded = false;
}
else
{
running = true;
thisContext = boost::context::make_fcontext(
(char*)sharedStackPtr + sharedStackSize ,
sharedStackSize,
my_entry_func);
}
boost::context::jump_fcontext(&yieldContext, thisContext, reinterpret_cast<intptr_t>(this));
}
void yield()
{
yielded = true;
saveStack();
boost::context::jump_fcontext(&thisContext, yieldContext, 0);
}
void restoreStack()
{
char* stackTop = (char*)sharedStackPtr + sharedStackSize ;
memcpy(stackTop - savedStackSize, savedStackPtr, savedStackSize);
}
void saveStack()
{
char dummy = 0;
char* stackPointer = &dummy;
char* stackTop = (char*)sharedStackPtr + sharedStackSize ;
assert((stackPointer < stackTop) && (stackPointer >= sharedStackPtr ));
savedStackSize = stackTop - stackPointer;
if (savedStackPtr == nullptr)
{
savedStackPtr = coroutine_stack_alloc(savedStackSize);
}
else
{
savedStackPtr = coroutine_stack_realloc(savedStackPtr, savedStackSize);
}
memcpy(savedStackPtr, stackPointer, savedStackSize);
}
Any idea ? Is there something I do wrong somewhere ?
make_fcontext() must be applied to a stack inorder to initialize the stack before it can be used with jump_fcontext(). Ofcourse you could re-use a stack by applying make_fcontext() after the execution context is finished.

Cocos2d-x: 0xC0000005: Access violation reading location 0xCDCDCDD1

everyone:
The problem is strange. I paste my code first.
void GameObjectsLayer::updateEnemy(float interval)
{
UNREFERENCED_PARAMETER(interval);
Enemy *lpEnemy = new Enemy("enemy1.png", 1, 10, 8);
lpEnemy->getSprite()->setAnchorPoint(CCPointZero);
lpEnemy->setPosition(ccp(-30, 400));
CCMoveTo *lpMoveAction = CCMoveTo::create(350.0f / ENEMY1_MOVE_SPEED, ccp(320, lpEnemy->getPosition().y));
CCCallFuncND *lpCallback = CCCallFuncND::create(lpEnemy->getSprite(), callfuncND_selector(GameObjectsLayer::removeEnemy), lpEnemy);
CCSequence *lpSeqActions = CCSequence::create(lpMoveAction, lpCallback, NULL);
this->addChild(lpEnemy->getSprite(), 10);
lpEnemy->getSprite()->runAction(lpSeqActions);
// When I set the breakpoint here, the _vEnemies is valid and the application runs well.
_vEnemies->push_back(lpEnemy);
}
void GameObjectsLayer::removeEnemy(CCNode *lpSender, void *lpParam)
{
Enemy *lpEnemy = (Enemy*)lpParam;
lpEnemy->getSprite()->stopAllActions();
this->removeChild(lpSender);
// When access the _vEnemies variable here, the exception occurs at "_vEnemies->begin()"
// I set a breakpoint here, the address of _vEnemies is invalid, but I set a breakpoint in the previous function, the _vEnemies has a valid address, what happened? I really can't comprehend the behavior. _vEnemies is the member variable of this class.
std::vector<Enemy*>::iterator iter = _vEnemies->begin();
while (iter != _vEnemies->end())
{
if (lpEnemy == *iter)
{
this->removeChild(lpEnemy->getSprite());
//delete *iter;
iter = _vEnemies->erase(iter);
continue;
}
++iter;
}
delete lpEnemy;
}
these two methods are used in two CCSchedules, which is intialized in init() method, the codes are below:
bool GameObjectsLayer::init()
{
bool bRet = false;
do
{
/* not important, omit them */
this->schedule(schedule_selector(GameObjectsLayer::updateEnemy), 5.0f);
this->schedule(schedule_selector(GameObjectsLayer::enemyShoot), 1.0f);
scheduleUpdate();
bRet = true;
}
while (0);
return bRet;
}
I got a head-ache. I don't know what happened. The version of my cocos2d-x is 2.1.5, and IDE is VS2012. Thanks for help..
Well, this is an old one, but for anyone who might stumble here :
The problem seems to be in this line
CCCallFuncND *lpCallback = CCCallFuncND::create(lpEnemy->getSprite(), callfuncND_selector(GameObjectsLayer::removeEnemy), lpEnemy);
The signature for this (from docs) is
static CCCallFuncND* create ( CCObject *pSelectorTarget,
SEL_CallFuncND selector,
void * d
)
*pSelectorTarget is the object on which the selector is called. So in this example it should be this instead of lpEnemy->getSprite().
Frankly, It seems a little strange to me that it didn't crash earlier.

Callback function confuses argument?

I have a sfml window container, and it appears to be working, however the glViewPorts are the wrong size, which I assume is because the wrong sf::Window is being passed.
Here is a function which adds to the window: It takes some information about the sfml window.
int WindowContainer::PushBack(WindowData& data)
{
if(data.WindowSettingsOK() && data.VideoModeOK()){
mWindowVector.resize(mWindowVector.size() + 1);
mDisplayFuncVector.resize(mWindowVector.size());
mInputFuncVector.resize(mWindowVector.size());
mWindowVector.at(mWindowVector.size() - 1) = new sf::Window();
mWindowVector.at(mWindowVector.size() - 1)->Create(data.VideoMode(), data.Title(), data.Style(), data.Settings());
mWindowVector.at(mWindowVector.size() - 1)->SetPosition(data.PositionX(), data.PositionY());
mDisplayFuncVector.at(mWindowVector.size() - 1) = nullptr;
mInputFuncVector.at(mWindowVector.size() - 1) = nullptr;
return 0;
}
else{
PrintError(ErrorMessageType::BadSettings);
return 1;
}
}
Alternatively, this function may be called to setup the display and input function callbacks:
int WindowContainer::PushBack(WindowData& data, function_p displayFunc, function_p inputFunc)
{
int return_val = PushBack(data);
mDisplayFuncVector.at(mWindowVector.size() - 1) = displayFunc;
mInputFuncVector.at(mWindowVector.size() - 1) = inputFunc;
return return_val;
}
Then, when the window needs .Display()'ing, this function is called:
void WindowContainer::ProcessDisplay()
{
for(unsigned int i = 0; i < mWindowVector.size(); i ++){
if(mDisplayFuncVector.at(i) != nullptr){
mDisplayFuncVector.at(i)(*mWindowVector.at(i), mClock, (const void*&)mExternalDrawingDataPointer);
}
mWindowVector.at(i)->Display();
}
}
... This is all good, until the result on the screen is that resizing one window affects the viewport of both windows. This suggests that calling the callback function: mDisplayFuncVector.at(i)(*mWindowVector.at(i), mClock, (const void*&)mExternalDrawingDataPointer); gives the argument of *mWindowVector.at(0) each time, instead of each window individually. (As in *mWindowVector.at(i))
Can anyone help with this problem?
The main loop contains this code:
while(container.Access(0)->IsOpened()){
container.ProcessInput();
container.ProcessDisplay();
}
Container.Access(int) is this function:
const sf::Window*& WindowContainer::Access(unsigned int index)
{
if(index > mWindowVector.size()){
PrintError(ErrorMessageType::IndexOutOfRange);
}
else{
return (const sf::Window*&)mWindowVector.at(index);
}
return (const sf::Window*&)mWindowVector.at(0);
}
Thanks again, I'm sure I have made a mistake somewhere but cannot spot it.
I have been thinking about this question and suspect openGL becomes confused with which window is it drawing to if more than one object is pushed back without a call to Display() to sync everything.
I am yet to test this and confirm.
EDIT The window container now works. It has nothing to do with the callback functions argument.

Erasing a pointer from a vector

I'm trying to erase a pointer to an object, but I keep crashing the console (PS2), I don't get any errors due to the way the console is set up, so I'm not quite sure what is going on.
I've listed the two lines that error, this didn't error until I added these lines.
for(listIter = m_downDirectionList.begin(); listIter != m_downDirectionList.end(); listIter++)
{
Projectile* proj = dynamic_cast<Projectile*>(*listIter);
if (proj->getZWorldCoord() >= (defaultLevelDepth + zOffset))
{
proj->getPoolOwner()->releaseAProjectile(proj);
//(*listIter) = NULL; // THIS ERRORS, also tried = 0.
//listIter = m_downDirectionList.erase(listIter); // THIS ALSO ERRORS
}
else
{
(*listIter)->update(camera, zOffset);
}
}
What am I doing wrong?
Thanks.
EDIT:
Clarification, just having this line.
listIter = m_downDirectionList.erase(listIter);
this also errors.
for(listIter = m_downDirectionList.begin(); listIter != m_downDirectionList.end(); )
{
Projectile* proj = dynamic_cast<Projectile*>(*listIter);
if (proj->getZWorldCoord() >= (defaultLevelDepth + zOffset))
{
proj->getPoolOwner()->releaseAProjectile(proj);
listIter = m_downDirectionList.erase(listIter);
}
else
{ //m_downDirectionList[p]->update(camera, zOffset);
(*listIter)->update(camera, zOffset);
listIter++
}
}
m_downDirectionList.erase (listIter);