Cocos2d-x 3.7 C++ CCLoad UIPageView crashing - c++

This happens on all platforms but this description is for iPhone 5s 8.4 simulator, through the Xcode.
I have been working on the game using C++ and cocos2d-x version 3.6 and Cocostudio 2.3.1. All was fine until i updated to the official release of cocos 3.7. App started getting crashes. One of those is particularly interesting regarding UIPageView. So my header and cpp files are like that:
MKEpochSelectionScene.h
#include "cocos2d.h"
#include "cocos-ext.h"
#include <cocos/ui/CocosGUI.h>
class MKEpochSelectionScene : public cocos2d::Scene {
public:
bool init();
CREATE_FUNC(MKEpochSelectionScene);
private:
cocos2d::ui::PageView * mainPageView;
void previousEpoch(Ref* pSender, cocos2d::ui::Widget::TouchEventType eEventType);
void nextEpoch(Ref* pSender, cocos2d::ui::Widget::TouchEventType eEventType);
void showEpoch(Ref* pSender, cocos2d::ui::Widget::TouchEventType eEventType);
};
MKEpochSelectionScene.cpp
#include "MKEpochSelectionScene.h"
#include <editor-support/cocostudio/CocoStudio.h>
#include "MKGameScene.h"
#include "MKLevelSelectionScene.h"
USING_NS_CC;
bool MKEpochSelectionScene::init()
{
if(!Scene::init()) return false;
auto node = CSLoader::createNode("UI/Epoch/Layer.csb");
this->addChild(node);
auto buttonLeft = node->getChildByName<ui::Button *>("Button_Left");
CCASSERT(buttonLeft != nullptr, "Button left is null");
buttonLeft->addTouchEventListener(CC_CALLBACK_2(MKEpochSelectionScene::nextEpoch,this));
auto buttonRight = node->getChildByName<ui::Button *>("Button_Right");
CCASSERT(buttonRight != nullptr, "Button right is null");
buttonRight->addTouchEventListener(CC_CALLBACK_2(MKEpochSelectionScene::previousEpoch,this));
//******CRASHING LINE
mainPageView = (cocos2d::ui::PageView *)node->getChildByName("selectEpoch");
//******CRASHING LINE
CCASSERT(mainPageView != nullptr, "Main pageview is nil");
CCASSERT(mainPageView->getPages().size() > 0, "Page view has zero pages");
return true;
}
//Other methods
//....
}
Sooo.... The thing happens with the mainPageView. Crash occurs on the line where i reference UIPageView from the design file and assign it to the mainPageView ivar. Crash does not say anything, but crashes in the NavMesh file at the following:
So it crashes when i try to pushscene as to switch to this scene from mainMenu. There is one more thing... If i use local variable like: auto mainPageView instead of ivar in the init() method, it does not crash. And if i comment the UIPageView referencing at all e.g. crashing line - it does not crash.
What i have tried: Updated Cocostudio to 2.3.1.1 which is the latest. Republished all of the UI using that new version. Cleaned all caches and stuff of the build. Updates to the new cocos engine version by creating new project with the new version and copying over files from the old version and importing into the project. This is just to say that i have tried several things.
Any help would be appreciated. And i am sure this might be a silly mistake of mine...
Cheers!

I think you are triggering this bug:
https://github.com/cocos2d/cocos2d-x/issues/12962
It is going to fixed in v3.7.1

Related

Show accelerator key in menu

I am using Gtkmm 3.22.30 on Ubuntu and I have been trying to show accelerator keys in my application menu, without success. So far, I have been able to register an accelerator key to my menu items, but for some reason, they don't appear in my menu. I know this is possible, because I have seen it in Inkscape, which I believe is using Gtkmm as well (For example: New is bound to <Control>N:
I have prepared a minimal example to show my problem (and what I have done). Here is the code:
#include <gtkmm.h>
#include <iostream>
class MainWindow : public Gtk::ApplicationWindow
{
public:
MainWindow();
private:
void OnActivateSubItem()
{
std::cout << "Handler called" << std::endl;
}
Gtk::MenuBar m_menuBar;
Gtk::MenuItem m_mainMenu{"Menu"};
Gtk::Menu m_menu;
Gtk::MenuItem m_subItem{"Item"}; // Menu|Item
};
MainWindow::MainWindow()
{
// Setting the menu up:
add(m_menuBar);
m_menuBar.append(m_mainMenu);
m_mainMenu.set_submenu(m_menu);
m_menu.append(m_subItem);
// Adding accelerator:
auto accel_group = Gtk::AccelGroup::create();
add_accel_group(accel_group);
m_menu.set_accel_group(accel_group);
// I would have believed this to do the trick but, meh...
m_subItem.add_accelerator("activate",
accel_group,
GDK_KEY_y,
Gdk::ModifierType::CONTROL_MASK,
Gtk::ACCEL_VISIBLE);
m_subItem.signal_activate().connect([this]{OnActivateSubItem();});
}
int main()
{
auto app = Gtk::Application::create("my.menu.problem");
MainWindow window;
window.show_all();
return app->run(window);
}
which leads to the following:
I was expecting a Ctrl + y entry next to the Item menu item (especially with the Gtk::ACCEL_VISIBLE flag for which I have found no documentation), but nothing is showing except a blank space. When I hit Ctrl + y, "Handler called" appears in the console, so the accelerator works.
I have look through the API but it is very confusing and badly documented (I was not able to find a working example for Gtkmm 3.22.30, not even in the examples coming with the source code).
How can I achieve this?
Notes:
I am looking for an answer which does not involve Gtk::Builder if possible.
The answer can use C code if what I want to do is not possible in Gtkmm, but I would need it to integrate with my Gtkmm code.
add_accel_group(accel_group);
m_menu.set_accel_group(accel_group);
I think the same AccelGroup cannot be assigned to a window and a menu. I searched the docs for details on this and found nothing, but my tummy feeling says me you have to delete one of these lines. And in this example they use the AccelGroup only in the window, too. I suggest to delete the second line.
EDIT: i think you are using a different Gtkmm version than i am, because the code you provided works fine on my machine. Could you please compile following c++ program, run it and post its output ?
#include <gtkmm.h>
#include <iostream>
int main() {
cout << gtk_get_major_version() << "." << gtk_get_minor_version() << "." << gtk_get_micro_version();
}

WxWidgets Sizer Double Frees?

I'm going to preface this question by saying that I am not entirely new to wxWidgets, though I would not consider myself all that experience either.
I'm having a problem which I have narrowed down through testing to be with the wxWidgets wxBoxSizer classes. From what I can tell, I don't think I'm doing anything wrong, and they work while the application is running; however, when the application closes and everything terminates, it seems that about a third of the time it will double-free something and seg fault. I'm writing and building on a linux system, and there doesn't seem to be any problems with anything but these sizers.
I did have many more windows within the HomeFrame class before I stripped it to search for bugs, but the code below still causes the double-free:
I've also looked around StackOverflow and other code forums to see if anyone was having a similar issue, but I couldn't find anything. I'm thinking that it may have something to do with the way I'm storing the sizer pointers in the class as members?
HomeFrame.h:
#pragma once
#include <wx/frame.h>
#include <wx/sizer.h>
namespace qzrgui
{
class HomeFrame: public wxFrame
{
public:
HomeFrame();
~HomeFrame();
private:
// Sizers
wxBoxSizer* _topSizer;
wxBoxSizer* _leftSizer;
wxBoxSizer* _rightSizer;
// Functions
void _setup();
void _createWindows();
};
}
HomeFrame.cpp:
#include "HomeFrame.h"
namespace qzrgui
{
HomeFrame::HomeFrame() :
wxFrame(nullptr, wxID_ANY, "Quizzer")
{
_setup();
}
HomeFrame::~HomeFrame()
{
}
void HomeFrame::_createWindows()
{
// Create sizers.
_topSizer = new wxBoxSizer(wxOrientation::wxHORIZONTAL);
_leftSizer = new wxBoxSizer(wxOrientation::wxVERTICAL);
_rightSizer = new wxBoxSizer(wxOrientation::wxVERTICAL);
}
void HomeFrame::_setup()
{
_createWindows();
}
}
Quizzer.h (wxApp base class):
#pragma once
#include <wx/app.h>
namespace qzrgui
{
class Quizzer : public wxApp
{
public:
virtual bool OnInit();
};
};
Quizzer.cpp:
#include "Quizzer.h"
wxIMPLEMENT_APP(qzrgui::Quizzer);
#include "frames/HomeFrame.h"
namespace qzrgui
{
bool Quizzer::OnInit()
{
wxFrame* frame = new HomeFrame();
frame->Show(true);
return true;
}
}
There is nothing in the code shown here which could result in a crash. You do definitely have (three) memory leak(s) in your code, as you create 3 sizers not associated with any window or another sizer and never delete them, but, while wrong, this can't result in a crash.
There is also not enough information to diagnose what you're seeing. As always with a crash, please build your code with debug information and run it under debugger to see what exactly happens. If you're under a Unix-like system (or even under MSW with the latest MSVS 2019 version), you should also compile with address sanitizer enabled to find the real problem before the crash happens.

C++ Namespace is undeclared

I'm new to C++ and am trying to learn OpenGL. However, when I try to compile my program, I cannot refer to a namespace that I have already created in my header file. The code is as follows:
engine.hpp:
#ifndef ENGINE_HPP
#define ENGINE_HPP
// ...
namespace render {
void Initialise();
namespace inits {
bool glfw_init = false,
glfw_window_init = false,
gl_init = false;
}
}
#endif
engine.cpp:
#include "engine.hpp"
// ...
namespace render {
void Initialise() {
if (glfwInit() == GLFW_FALSE)
inits::glfw_init = false;
}
}
O
I'm not sure why this isn't compiling. I'm using MinGW (GCC) on Windows 10 (64-bit).
My compiler message is:
error: 'inits' has not been declared
Edit: Thank you everybody for your suggestions. It appears that although this was a compiler fluke (after my first edit, since others could not reproduce the issue and a reinstall fixed the issue), it is a symptom of a larger organisational problem within my code. Since I have only invested ~15 minutes into the program, I would prefer to completely rewrite this after learning more about the language. For now, I have created a class and solved the issue discussed. I'm a beginner, and any book/resource recommendations would be welcome!
You're using nested namespaces, so should be:
render::inits::glfw_init = false;
Your code does not what you think it does.
// file engine.hpp
namespace render {
void Initialise();
namespace inits {
bool glfw_init = false, // these variables will be emitted with
glfw_window_init = false, // every source file that
gl_init = false; // #include "engine.hpp"
}
}
will lead to errors ("mulitply defined symbols") at linking/loading. To avoid that you may declare the variables extern or use functions for setting/getting the state (stored in a variable defined in engine.cpp).

Plugins using Pluma

Overview
I am trying to develop a C++ application which allows for user-created plugins.
I found a nice library called Pluma (http://pluma-framework.sourceforge.net/) which functionally seems to be exactly what I want.
After going through their tutorial, I was able to (with a bit of difficulty) convince the plugin to compile. However, it refuses to play nice and connect with the main program; returning various errors depending on how I try to implement them.
Problem
If I comment out the line labeled 'Main problem line' (in the last file, main.cpp), the plugin compiles successfully, and the main app can recognize it, but it says that "Nothing registered by plugin 'libRNCypher'", and none of the functions can be called.
If I compile that line, the main application instead says "Failed to load library 'Plugins/libRNCypher.so'. OS returned error: 'Plugins/libRNCypher.so: undefined symbol: _ZTIN5pluma8ProviderE".
My guess is that it has something to do with the way the plugin was compiled, as compiling it initially did not work and Code::Blocks told me to compile with "-fPIC" as a flag (doing so made it compile).
Code
Code below:
Main.cpp
#include "Pluma/Pluma.hpp"
#include "CryptoBase.h"
int main()
{
pluma::Pluma manager;
manager.acceptProviderType< CryptoBaseProvider >();
manager.loadFromFolder("Plugins", true);
std::vector<CryptoBaseProvider*> providers;
manager.getProviders(providers);
return 0;
}
CryptoBase.h
#ifndef CRYPTOBASE_H_INCLUDED
#define CRYPTOBASE_H_INCLUDED
#include "Pluma/Pluma.hpp"
#include <string>
#include <vector>
#include <bitset>
//Base class from which all crypto plug-ins will derive
class CryptoBase
{
public:
CryptoBase();
~CryptoBase();
virtual std::string GetCypherName() const = 0;
virtual std::vector<std::string> GetCryptoRecApps() const = 0;
virtual void HandleData(std::vector< std::bitset<8> > _data) const = 0;
};
PLUMA_PROVIDER_HEADER(CryptoBase)
#endif // CRYPTOBASE_H_INCLUDED
RNCypher.h (This is part of the plugin)
#ifndef RNCYPHER_H_INCLUDED
#define RNCYPHER_H_INCLUDED
#include <string>
#include <vector>
#include <bitset>
#include "../Encoder/Pluma/Pluma.hpp"
#include "../Encoder/CryptoBase.h"
class RNCypher : public CryptoBase
{
public:
std::string GetCypherName() const
{
return "RNCypher";
}
std::vector<std::string> GetCryptoRecApps() const
{
std::vector<std::string> vec;
vec.push_back("Storage");
return vec;
}
void HandleData(std::vector< std::bitset<8> > _data) const
{
char letter = 'v';
_data.clear();
_data.push_back(std::bitset<8>(letter));
return;
}
};
PLUMA_INHERIT_PROVIDER(RNCypher, CryptoBase);
#endif // RNCYPHER_H_INCLUDED
main.cpp (This is part of the plugin)
#include "../Encoder/Pluma/Connector.hpp"
#include "RNCypher.h"
PLUMA_CONNECTOR
bool connect(pluma::Host& host)
{
host.add( new RNCypherProvider() ); //<- Main problem line
return true;
}
Additional Details
I'm compiling on Ubuntu 16.04, using Code::Blocks 16.01.
The second error message seems to not come from Pluma itself, but a file I also had to link, #include <dlfcn.h> (which might be a Linux file?).
I would prefer to use an existing library rather than write my own code as I would like this to be cross-platform. I am, however, open to any suggestions.
Sorry for all of the code, but I believe this is enough to reproduce the error that I am having.
Thank You
Thank you for taking the time to read this, and thank you in advance for your help!
All the best, and happy holidays!
I was not able to reproduce your problem, however looking at
http://pluma-framework.sourceforge.net/documentation/index.htm,
I've noticed that:
in your RNCypher.h file you miss something like
PLUMA_INHERIT_PROVIDER(RNCypher, CryptoBase)
it seems also that there's no file CryptoBase.cpp containing something like
#include "CryptoBase.h"
PLUMA_PROVIDER_SOURCE(CryptoBase, 1, 1);
finally, in CryptoBase.h I would declare a virtual destructor (see Why should I declare a virtual destructor for an abstract class in C++?) and provide a definition to it, while you should not declare a default constructor without providing a definition to it (see for instance Is it correct to use declaration only for empty private constructors in C++?); of course the last consideration is valid unless there's another file in which you have provided such definitions.

Qt: MainWindow->show() crashes program on call

I've been working on this program using Qt in c++ and so far so good. However I then needed to get this program moved to another machine. I have subversion, so I committed every file in the project folder and checked it out on the new machine. After jumping through some hoops to get it to successfully build and running, I get this error:
ASSERT: "dst.depth() == 32" in file qgl.cpp,.
invalid parameter passed to c runtime function qt
I tried stepping through the program to find the point where it crashes and found that it was after everything had been initialized and show() is called for the class that inherits the QMainWindow class. The c->showView() line calls QMianWindow->show().
----------main.cpp------------
#include <QApplication>
#include "ModelI.h"
#include "ControllerI.h"
#include "Model.h"
#include "Controller.h"
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
ModelI *m = new Model();
ControllerI *c = new Controller(m);
c->showView(); <- ERROR HERE
return a.exec();
}
The confusing part of the problem is that the program works perfectly fine on my machine when show() is called. I don't know what could be different between the two machines to make the program behave so differently. Both use the same version of Qt (SDK 2010.05). Both are developing with Eclipse. The only difference I can find is that my compiler is MinGW 4.5.0 and the other machine's is MinGW 4.5.2.
EDIT 1:
This is what Controller::showView() looks like.
void Controller::showView()
{
mView->show();
}
And this is how mView is initialized.
mView = new View(mModel, this);