Cant move the layout up when keyboard presented - c++

I'm trying to move the layout up when the keyboard is presented cause it hides my input textfield
but my app crash from line HASH_FIND_PTR(_targets, &tmp, element); from this class
void ActionManager::addAction(Action *action, Node *target, bool paused)
{
CCASSERT(action != nullptr, "");
CCASSERT(target != nullptr, "");
tHashElement *element = nullptr;
// we should convert it to Ref*, because we save it as Ref*
Ref *tmp = target;
HASH_FIND_PTR(_targets, &tmp, element); //error
if (! element)
{
element = (tHashElement*)calloc(sizeof(*element), 1);
element->paused = paused;
target->retain();
element->target = target;
HASH_ADD_PTR(_targets, target, element);
}
actionAllocWithHashElement(element);
CCASSERT(! ccArrayContainsObject(element->actions, action), "");
ccArrayAppendObject(element->actions, action);
action->startWithTarget(target);
}
I'm using cocos2d-x 3.2
i have debug and it's crashing after this line m_pLayout->runAction(moveBy);
anyone please give me some advice how can i solve it thanks
My LoginScene.h
#include "cocos2d.h"
#include "cocos-ext.h"
#include "CocosGUI.h"
USING_NS_CC;
USING_NS_CC_EXT;
using namespace ui;
class LoginScene : public Scene
{
public:
LoginScene(bool pPortrait=false);
~LoginScene();
virtual void onEnter();
virtual void onExit();
void onLogin(Ref* pSender, Widget::TouchEventType type);
void onRegister(Ref* pSender, Widget::TouchEventType type);
void TextFieldEvent(Ref* pSender,TextField::EventType type);
protected:
Layout* m_pLayout;
Layer* m_pUILayer;
};
and LoginScene.cpp
#include "LoginScene.h"
#include "cocostudio/CCSSceneReader.h"
#include "cocostudio/CCSGUIReader.h"
#include "cocostudio/CCActionManagerEx.h"
#include <sqlite3.h>
LoginScene::LoginScene(bool pPortrait):m_pLayout(NULL),m_pUILayer(NULL)
{
Scene::init();
}
LoginScene::~LoginScene()
{
}
void LoginScene::onEnter()
{
Scene::onEnter();
m_pUILayer=Layer::create();
m_pUILayer->scheduleUpdate();
addChild(m_pUILayer);
//register root from json
m_pLayout=dynamic_cast<Layout*>(cocostudio::GUIReader::getInstance()->widgetFromJsonFile("LoginScene/LoginScene.json"));
m_pUILayer->addChild(m_pLayout);
//button initialize
Button *btnLogin=static_cast<Button*>(Helper::seekWidgetByName(m_pLayout, "btnLogin"));
btnLogin->addTouchEventListener(CC_CALLBACK_2(LoginScene::onLogin, this));
Button *btnRegister=static_cast<Button*>(Helper::seekWidgetByName(m_pLayout, "btnRegister"));
btnRegister->addTouchEventListener(CC_CALLBACK_2(LoginScene::onRegister, this));
//textfield initialize
TextField *txtUsername=static_cast<TextField*>(Helper::seekWidgetByName(m_pLayout, "txtUsername"));
txtUsername->addEventListenerTextField(m_pLayout, textfieldeventselector(LoginScene::TextFieldEvent));
TextField *txtPassword=static_cast<TextField*>(Helper::seekWidgetByName(m_pLayout, "txtPassword"));
txtPassword->addEventListenerTextField(m_pLayout, textfieldeventselector(LoginScene::TextFieldEvent));
}
void LoginScene::onExit()
{
m_pUILayer->removeFromParent();
cocostudio::GUIReader::destroyInstance();
cocostudio::ActionManagerEx::destroyInstance();
cocostudio::SceneReader::destroyInstance();
Scene::onExit();
}
void LoginScene::onLogin(Ref* pSender, Widget::TouchEventType type)
{
if(type==Widget::TouchEventType::ENDED)
{
CCLOG("abc");
}
}
void LoginScene::onRegister(Ref* pSender, Widget::TouchEventType type)
{
if (type==Widget::TouchEventType::ENDED)
{
CCLOG("abc");
}
}
void LoginScene::TextFieldEvent(Ref* pSender,TextField::EventType type)
{
#if (CC_TARGET_PLATFORM == CC_PLATFORM_IOS)
switch (type)
{
case TextField::EventType::ATTACH_WITH_IME:
{
TextField* txtUsername=dynamic_cast<TextField*>(pSender);
MoveBy* moveBy=MoveBy::create(0.5f, Vec2(0,txtUsername->getContentSize().height*2.5));
m_pLayout->runAction(moveBy);
}
break;
case TextField::EventType::DETACH_WITH_IME:
{
TextField* txtUsername=dynamic_cast<TextField*>(pSender);
MoveBy* moveBy=MoveBy::create(0.1f, Vec2(0,-txtUsername->getContentSize().height*2.5));
m_pLayout->runAction(moveBy);
}
break;
default:
break;
}
#endif
}

Related

Access violation while using std::function assigned to a member function using std::bind()

I am making a game engine. I implemented an event system such that my window takes a WindowData struct which has information about creating a window. It has a field named eventCallback which is a placeholder for a callback function which my window will call when an event occurs.
But, when I am trying to assign my placeholder to my callback function in my client code, I am getting an access violation.
The placeholder is std::function, and I am using std::bind().
This is my client code:
#include "JetByte.h"
#include <iostream>
#include <memory>
#include <functional>
class App : public JetByte::Application
{
public:
App();
void OnInit() override;
void OnUpdate() override;
void OnDestroy() override;
bool EventCallback(JetByte::Event& e);
~App();
private:
bool runningFlag;
std::shared_ptr<JetByte::Window> window;
std::shared_ptr<JetByte::GraphicsContext> context;
};
App::App()
{
}
void App::OnInit()
{
try
{
runningFlag = true;
JetByte::WindowData data;
data.title = "My window";
data.eventCallback = std::bind(&App::EventCallback, this, std::placeholders::_1);
window = JetByte::Window::create({ "My Window" });
context = JetByte::GraphicsContext::Create(window);
}
catch (const std::exception& e)
{
std::cout << e.what() << std::endl;
}
}
void App::OnUpdate()
{
while (runningFlag)
{
context->Swap();
window->Update();
}
}
void App::OnDestroy()
{
JetByte::EventDispatcher::Stop();
context.reset();
window.reset();
}
bool App::EventCallback(JetByte::Event& e)
{
if (e.GetEventType() == JetByte::EventType::WindowClose)
{
std::cout << "window closed" << std::endl;
runningFlag = false;
}
return true;
}
App::~App()
{
}
JetByte::Application* JetByte::ClientApplicationPortal() {
return new App();
}
And this is my WindowData struct:
struct WindowData {
const char* title = "JetByte Application";
int width = 500;
int height = 500;
bool vsync = true;
std::function<bool(Event&)> eventCallback;
};

error: multiple definition of `PlayerFrame::PlayerFrame(QObject*)'

The project im trying to build is a media player with c++ and qt inclusion. However im failing to do this due to error , which i am not sure why or how it occurs. Please excuse me since this is my first ever project with c ++ or QT .
The Error is multiple defintions of frames for the media player which i am not sure because in header file only definitions are written and source (cpp) the code is written . I would really appreciate the help , thank you everyone for taking time of your day to help means a lot.
Code:
playeframe.h
#include <QAbstractVideoSurface>
#include <QImage>
#include <QVideoFrame>
#include <QLabel>
class PlayerFrame : public QAbstractVideoSurface
{
Q_OBJECT
public:
PlayerFrame(QObject *parent = nullptr);
void stopVideo();
Q_SIGNALS:
void fnSurfaceStopped(QPixmap pix);
private slots:
void fnClearPixmap();
private:
QPixmap CapImage;
QImage::Format imgFormat;
QVideoFrame curFrame;
bool Videostart(const QVideoSurfaceFormat &format);
QList<QVideoFrame::PixelFormat> supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const;
bool isFormatSupported(const QVideoSurfaceFormat &format) const;
bool present(const QVideoFrame &frame);
};
#endif
playerframe.cpp
#include "playerframe.h"
#include <QtWidgets>
#include <qvideosurfaceformat.h>
#include "playerwindow.h"
PlayerFrame::PlayerFrame(QObject *parent)
: QAbstractVideoSurface(parent)
, imgFormat(QImage::Format_Invalid)
{
}
bool PlayerFrame::Videostart(const QVideoSurfaceFormat &format)
{
QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(format.pixelFormat());
QSize size = format.frameSize();
if (imageFormat != QImage::Format_Invalid && !size.isEmpty())
{
this->imgFormat = imageFormat;
QAbstractVideoSurface::start(format);
return true;
}
else return false;
}
void PlayerFrame::fnClearPixmap()
{
CapImage = QPixmap();
}
void PlayerFrame::stopVideo()
{
QAbstractVideoSurface::stop();
}
QList<QVideoFrame::PixelFormat> PlayerFrame::supportedPixelFormats(QAbstractVideoBuffer::HandleType handleType) const
{
if (handleType == QAbstractVideoBuffer::NoHandle) {
return QList<QVideoFrame::PixelFormat>()
<< QVideoFrame::Format_RGB32
<< QVideoFrame::Format_ARGB32
<< QVideoFrame::Format_ARGB32_Premultiplied
<< QVideoFrame::Format_RGB565
<< QVideoFrame::Format_RGB555;
}
else
{
return QList<QVideoFrame::PixelFormat>();
}
}
bool PlayerFrame::isFormatSupported(const QVideoSurfaceFormat &format) const
{
QImage::Format imageFormat = QVideoFrame::imageFormatFromPixelFormat(format.pixelFormat());
QSize size = format.frameSize();
return imageFormat != QImage::Format_Invalid && !size.isEmpty() && format.handleType() == QAbstractVideoBuffer::NoHandle;
}
bool PlayerFrame::present(const QVideoFrame &frame)
{
if (surfaceFormat().pixelFormat() != frame.pixelFormat() || surfaceFormat().frameSize() != frame.size())
{
setError(IncorrectFormatError);
stop();
return false;
}
else
{
if (!CapImage.isNull())
{
fnSurfaceStopped(CapImage);
}
curFrame = frame;
if (curFrame.map(QAbstractVideoBuffer::ReadOnly))
{
QImage image(
curFrame.bits(),
curFrame.width(),
curFrame.height(),
curFrame.bytesPerLine(),
imgFormat);
if (CapImage.isNull())
{
CapImage = QPixmap::fromImage(image.copy(image.rect()));
}
curFrame.unmap();
}
return true;
}
}

Can't draw sf::RectangleShape s stored in vector (Tetris clone)

I am trying to storesf::RectangleShape's into thestd::vectorand then draw each of them into thesf::RenderWindow.
Single rectangle shape is representing 1x1 tetromino and i would like to store it into the vector each time it reaches the bottom of the window. Then I would like to reset the position of the current tetromino to the default position.
I think I'm not even to able store it correctly. Each time the tetromino reaches the bottom it gives me this error message:
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Bellow please find my current code. I just started working on it and already got stuck.
Definitions.h
#pragma once
// Point structure
struct Point
{
int dim_x;
int dim_y;
};
// Field Dimensions
const int fieldRows = 10;
const int fieldColumns = 9;
const int pointSize = 50.f;
// For checkingEdges funntion within the Tetrnomino.h
enum Edge
{
leftEdge,
rightEdge,
noneEdge
};
Game.h
#pragma once
#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include "Definitions.h"
#include "Tetromino.h"
class Game
{
public:
Game();
~Game();
// Game starter
void run();
// Accessors
bool running();
private:
// Updating and rendering the game window
void update();
void render();
// Initialization
void initVariables();
void initWindow();
void initBacgroundMusic();
// Polling
void pollEvents();
// Window logic stuff
sf::RenderWindow* _window;
sf::Event _event;
void drawStack();
// Bacground Music
sf::Music _ost;
// Tetromino + Its logic
Tetromino _T;
sf::Time delayTime = sf::milliseconds(300);
sf::Clock clock;
};
Tetromino.h
#pragma once
#include <SFML/Graphics.hpp>
#include <vector>
#include "Definitions.h"
class Tetromino
{
public:
Tetromino();
~Tetromino();
// Initialization
void initTetromino();
// Tetromonino logic
void moveTetromino();
Edge checkEdges();
// Getters & Setters
sf::RectangleShape getTetromino();
sf::RectangleShape getStackPart(int part);
int getStackSize();
void setTetromino(sf::RectangleShape &t);
private:
// The current tetromino
sf::RectangleShape _tetromino;
std::vector<sf::RectangleShape> _stack;
};
Game.cpp
#include "Game.h"
//-----Consturcotrs and Destructors-----//
Game::Game()
{
//Basic Initialization
_T.initTetromino();
initVariables();
}
Game::~Game()
{
delete _window;
}
//-----Private Functions-----//
void Game::run()
{
update();
render();
}
bool Game::running()
{
return _window->isOpen();
}
void Game::update()
{
sf::Time elapsed = clock.getElapsedTime();
pollEvents();
if (elapsed >= delayTime)
{
_T.moveTetromino();
clock.restart();
}
}
void Game::render()
{
_window->clear(sf::Color::White);
_window->draw(_T.getTetromino());
drawStack();
_window->display();
}
void Game::initVariables()
{
_window = nullptr;
initWindow();
initBacgroundMusic();
}
void Game::initWindow()
{
_window = new sf::RenderWindow(sf::VideoMode(fieldColumns * pointSize, fieldRows * pointSize), "Tetris v0.2", sf::Style::Default);
_window->setVerticalSyncEnabled(true);
_window->setFramerateLimit(60);
}
void Game::initBacgroundMusic()
{
_ost.openFromFile("../QT_SFML_Tetris/Music.ogg");
_ost.play();
_ost.setLoop(true);
_ost.setVolume(50.f);
}
void Game::pollEvents()
{
while (_window->pollEvent(_event))
{
if (_event.type == sf::Event::Closed) {_window->close();}
if (_event.type == sf::Event::KeyPressed)
{
if (_event.key.code == sf::Keyboard::Escape){_window->close();}
if (_event.key.code == sf::Keyboard::Left && _T.checkEdges() != leftEdge)
{
sf::RectangleShape t = _T.getTetromino();
t.setPosition(t.getPosition().x - pointSize, t.getPosition().y);
_T.setTetromino(t);
render();
}
if (_event.key.code == sf::Keyboard::Right && _T.checkEdges() != rightEdge)
{
sf::RectangleShape t = _T.getTetromino();
t.setPosition(t.getPosition().x + pointSize, t.getPosition().y);
_T.setTetromino(t);
render();
}
if (_event.key.code == sf::Keyboard::Down)
{
sf::RectangleShape t = _T.getTetromino();
t.setPosition(t.getPosition().x, t.getPosition().y+ pointSize);
_T.setTetromino(t);
render();
}
}
}
}
**void Game::drawStack()**
{
for (unsigned int i = _T.getStackSize(); i > 0; --i)
{
_window->draw(_T.getStackPart(i));
}
}
main.cpp
#include <Game.h>
int main()
{
Game game;
while (game.running())
{
game.run();
}
return 0;
}
Tetromino.cpp
#include "Tetromino.h"
//-----Consturcotrs and Destructors-----//
Tetromino::Tetromino()
{
}
Tetromino::~Tetromino()
{
}
//-----Public Functions-----//
void Tetromino::initTetromino()
{
_tetromino.setPosition(sf::Vector2f((fieldColumns * pointSize - pointSize) / 2, 0.f));
_tetromino.setSize(sf::Vector2f(pointSize, pointSize));
_tetromino.setFillColor(sf::Color::Red);
}
void Tetromino::moveTetromino()
{
_tetromino.move(0.f, pointSize);
if (_tetromino.getPosition().y > fieldRows * pointSize - pointSize)
{
_stack.push_back(_tetromino);
_tetromino.setPosition(sf::Vector2f((fieldColumns * pointSize - pointSize) / 2, 0.f));
}
}
Edge Tetromino::checkEdges()
{
if (_tetromino.getPosition().x == 0)
{
return leftEdge;
}
else if (_tetromino.getPosition().x == (fieldColumns * pointSize) - pointSize)
{
return rightEdge;
}
else return noneEdge;
}
sf::RectangleShape Tetromino::getTetromino()
{
return _tetromino;
}
sf::RectangleShape Tetromino::getStackPart(int part)
{
return _stack[part];
}
int Tetromino::getStackSize()
{
return _stack.size();
}
void Tetromino::setTetromino(sf::RectangleShape &t)
{
_tetromino = t;
}
I think the main issue could be within this line:
_stack.push_back(_tetromino);
In the drawStack() method you try to iterate backwards.
There is a reverse iterator doing this for you.
you have an off-by one error in your index calculation, which works only with an empty vector (exactly to prevent these errors you should use the iterator!)
You may want to read about iterators in C++ here is a small example.
According to your code it will look like (note that you need also a getStack()-method in Tetromino.hpp, returning the reference of the vector):
void Game::drawStack()
{
for (auto it = _T.getStack().rbegin(); it != _T.getStack().rend(); it++)
{
_window->draw(*it);
}
}
If you want to keep the index, I this is a fix:
void Game::drawStack()
{
for (int i = _T.getStackSize()-1; i >= 0; --i)
{
_window->draw(_T.getStackPart(i));
}
}

R6025 pure virtual function call (class derived from sf::InputStream)

For my game, I want to use PhysFs to extract music files that are in a zip file
I created a custom class MusicStream that inherits from sf::InputStream that I use as an sf::Music's stream.
This is my basic program:
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>
#include "musicstream.h"
#include "physfs.h"
int main() {
PHYSFS_init(0);
PHYSFS_addToSearchPath("data.zip", 0);
std::string musicFile = "music.ogg";
if (PHYSFS_exists(musicFile.c_str()) == 0) {
PHYSFS_deinit();
return EXIT_FAILURE;
}
sf::RenderWindow window(sf::VideoMode(200, 200), "SFML works!");
sf::Music myMusic;
MusicStream myStream(musicFile.c_str());
if (!myStream.getError()) {
myMusic.openFromStream(myStream);
myMusic.play();
}
while (window.isOpen()) {
sf::Event event;
while (window.pollEvent(event)) {
if (event.type == sf::Event::Closed) window.close();
}
}
myMusic.stop();
PHYSFS_deinit();
return 0;
}
This works flawlessly, except for one thing:
When I close the window and the program exits, I'm getting a runtime error R6025 pure virtual function call and the program crashes.
So apparently a pure virtual function is called (sf::InputStream's dtor??), but I implemented all of sf::InputStream's functions and it doesn't make sense to me.
Also, I'm not really sure if the code is relevant but in case it is, this is the custom class:
musicstream.h
#ifndef MUSIC_STREAM_H_INCLUDED
#define MUSIC_STREAM_H_INCLUDED
#include <SFML/System.hpp>
#include "physfs.h"
class MusicStream : public sf::InputStream {
public:
MusicStream();
MusicStream(const char *fileName);
virtual ~MusicStream() override;
sf::Int64 read(void *data, sf::Int64) override;
sf::Int64 seek(sf::Int64 position) override;
sf::Int64 tell() override;
sf::Int64 getSize() override;
bool getError() const;
private:
PHYSFS_File *file_;
bool error_;
};
#endif
musicstream.cpp
#include "musicstream.h"
MusicStream::MusicStream() :
error_(true)
{
}
MusicStream::MusicStream(const char *filename) :
error_(false)
{
file_ = PHYSFS_openRead(filename);
if (file_ == nullptr) {
error_ = true;
}
}
MusicStream::~MusicStream() {
if (error_) { return; }
PHYSFS_close(file_);
}
sf::Int64 MusicStream::read(void *data, sf::Int64 size) {
if (error_) { return 0; }
sf::Int64 fileRead = PHYSFS_read(file_, data, 1, size);
if (fileRead == -1) {
return 0;
}
return fileRead;
}
sf::Int64 MusicStream::seek(sf::Int64 position) {
if (error_) { return -1; }
if (PHYSFS_seek(file_, position) == 0) {
return -1;
}
return position;
}
sf::Int64 MusicStream::tell() {
if (error_) { return -1; }
sf::Int64 position = PHYSFS_tell(file_);
return position;
}
sf::Int64 MusicStream::getSize() {
if (error_) { return -1; }
sf::Int64 size = PHYSFS_fileLength(file_);
return size;
}
bool MusicStream::getError() const {
return error_;
}
The problem were these two lines:
sf::Music myMusic;
MusicStream myStream(musicFile.c_str());
I swapped them and got rid of the error. It's because music is played in its own thread. It tried reading from the stream after it was destroyed. Now the music is destroyed before the stream is.

undefined reference to `InputHandler::InputHandler()'

I get this error
undefined reference to `InputHandler::InputHandler()' on line 22
I am working on a InputHandler Class in SDL
InputHandler.h
/*
* InputHandler.h
*
* Created on: 16 apr. 2014
* Author: JAN
*/
#ifndef INPUTHANDLER_H_
#define INPUTHANDLER_H_
#include "SDL2/SDL.h"
#include "Vector2D.h"
class InputHandler
{
public:
static InputHandler* Instance()
{
if(s_pInstance == 0)
{
s_pInstance = new InputHandler();
}
return s_pInstance;
}
void reset();
// update and clean the input handler
void update();
void clean();
// keyboard events
bool isKeyDown(SDL_Scancode key) const;
// joystick events
int getAxisX(int joy, int stick) const;
int getAxisY(int joy, int stick) const;
bool getButtonState(int joy, int buttonNumber) const;
// mouse events
bool getMouseButtonState(int buttonNumber) const;
Vector2D* getMousePosition() const;
private:
InputHandler();
~InputHandler();
InputHandler(const InputHandler&);
InputHandler& operator=(const InputHandler&);
// private functions to handle different event types
// handle keyboard events
void onKeyDown();
void onKeyUp();
// handle mouse events
void onMouseMove(SDL_Event& event);
void onMouseButtonDown(SDL_Event& event);
void onMouseButtonUp(SDL_Event& event);
// handle joysticks events
void onJoystickAxisMove(SDL_Event& event);
void onJoystickButtonDown(SDL_Event& event);
void onJoystickButtonUp(SDL_Event& event);
// member variables
// keyboard specific
const Uint8* m_keystates;
// singleton
static InputHandler* s_pInstance;
};
typedef InputHandler TheInputHandler;
#endif
InputHandler.cpp
/*
* InputHandler.cpp
*
* Created on: 16 apr. 2014
* Author: JAN
*/
#include "InputHandler.h"
#include "Game.h"
InputHandler* InputHandler::s_pInstance = 0;
bool InputHandler::isKeyDown(SDL_Scancode key) const
{
if(m_keystates != 0)
{
if(m_keystates[key] == 1)
{
return true;
}
else
{
return false;
}
}
return false;
}
void InputHandler::update()
{
SDL_Event event;
while(SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_KEYDOWN:
onKeyDown();
break;
case SDL_KEYUP:
onKeyUp();
break;
default:
break;
}
}
}
void InputHandler::onKeyDown()
{
m_keystates = SDL_GetKeyboardState(0);
}
void InputHandler::onKeyUp()
{
m_keystates = SDL_GetKeyboardState(0);
}
I am new to programming in c++ and working with SDL. So it's probably a stupid error but if someone can explain me that would be great! Kinda stuck on this right now don't know what i am doing wrong
You haven't defined the default constructor anywhere.
Add it to the cpp file.
You seem to be missing quite a few other members, too.
In class InputHandler your constructor must be like this: InputHandler(){}