While using ccWave, one of the parameters was grid and it showed that the value should be of type ccGridSize.
I would like to know what a ccGridSize is..
What value should be given for a ccGridSize variable?
The code for ccWaves is as follows...
[CCWaves actionWithWaves:<(int)> amplitude:<(float)>
horizontal:<(BOOL)> vertical:<(BOOL)>
grid:<(ccGridSize)> duration:<(ccTime)>];
What value can be given in the place of the parameter grid???
Cocos2d defines ccGridSize as:
typedef struct _ccGridSize
{
NSInteger x;
NSInteger y;
} ccGridSize;
And provides an inline factory function:
static inline ccGridSize ccg(const NSInteger x, const NSInteger y);
So you can write your call as:
... grid:ccg(gridSizeX, gridSizeY)
Where gridSizeX and gridSizeY define a number of grid columns and rows for your effect.
From cctypes.h:
typedef struct _ccGridSize
{
NSInteger x;
NSInteger y;
} ccGridSize;
So it's just a couple of ints to state how big every step is of the grid that you are going to animate.
Related
I'm writing test automation in QT. I'am using QTest::qWaitFor to wait until the event loop switches to another tab in UI.
QTest::qWaitFor([tabs, ¤tIdx]() {
currentIdx = tabs->currentIndex();
return currentIdx == 1;
}, 5000);
Each time I'am using such construction following warning appears:
ignoring return value of function declared with 'warn_unused_result' attribute
I spent hours dealing with it but no result. I think the problem is the way functions consume returned values from lambda expressions. Is there any workaround?
Issue is not with lambda, but your usage:
You should use/check return value of qWaitFor (to know if timeout happens):
if (QTest::qWaitFor([tabs, ¤tIdx]() {
currentIdx = tabs->currentIndex();
return currentIdx == 1;
}, 5000)) {
// OK.
// ...
} else {
// timeout.
// ...
}
class CRA_Account {
int tax[4];
double refund[4];
int SIN;
public:
CRA_Account();
}
CRA_Account::CRA_Account() {
SIN = 0;
tax[4] = { 0 };
refund[4] = { 0 };
}
When I create a object in main it'll set the SIN to 0 but won't do the same to the arrays. Can someone help why?
tax[4] = { 0 }; is wrong at many levels..
One way to initlizie your class:
CRA_Account::CRA_Account():
tax{0,0,0,0},
refund{0,0,0,0},
SIN{0}{
}
Online
Try to have a look at std::array
I have a unit test using gtest and gmock.
These are provided, and in my turn I should make them pass.
I have a RentalAdministration Object, which takes (in some methods) a Car object pointer. One of the functions looks like this:
bool RentalAdministration::Add(Car *car){
if(!car){
throw invalid_argument("Car parameter can't be null!");
}
if(FindCar(car->GetLicencePlate()) != NULL){
return false;
}
cars.push_back(car);
return true;
}
One of such tests looks like his:
TEST(RentalAdministrationAdd, test_add_car_to_empty_administration)
{
RentalAdministration admin;
Car *car;
EXPECT_CALL(car, GetLicencePlate()).WillOnce(Return("fh-01-ict"));
EXPECT_TRUE(admin.Add(&car));
}
When I try to make these tests, I get loads of errors, all of which are alike:
g++ -Wall -Werror -pedantic -ggdb -O0 -std=c++98 -Iproduct -Itest test/RentalAdministrationTest.cpp product/RentalAdministration.cpp -lgtest -lgmock -lgmock_main -lpthread -o RentalAdministrationTest
In file included from /usr/include/gmock/gmock-generated-function-mockers.h:43:0,
from /usr/include/gmock/gmock.h:61,
from test/RentalAdministrationTest.cpp:2:
test/RentalAdministrationTest.cpp: In member function ‘virtual void RentalAdministrationAdd_test_add_car_to_empty_administration_Test::TestBody()’:
test/RentalAdministrationTest.cpp:13:5: error: request for member ‘gmock_GetLicencePlate’ in ‘car’, which is of pointer type ‘Car*’ (maybe you meant to use ‘->’ ?)
EXPECT_CALL(car, GetLicencePlate()).WillOnce(Return("fh-01-ict"));
^
In file included from /usr/include/gtest/gtest.h:58:0,
from /usr/include/gmock/internal/gmock-internal-utils.h:47,
from /usr/include/gmock/gmock-actions.h:46,
from /usr/include/gmock/gmock.h:58,
from test/RentalAdministrationTest.cpp:2:
test/RentalAdministrationTest.cpp:14:31: error: no matching function for call to ‘RentalAdministration::Add(Car**)’
EXPECT_TRUE(admin.Add(&car));
^
I wonder what I am doing wrong here. I'm just starting off with C++.
btw: I am compiling in g++ and have version 98.
Thanks.
Edit: excuse me for not posting this, but I have a mock file for Car.h which is in the same folder as the test itself.
#ifndef __CAR_H
#define __CAR_H
#include "gmock/gmock.h"
#include <string>
using namespace std;
class Car
{
public:
MOCK_CONST_METHOD0(GetLicencePlate, string());
MOCK_METHOD0(Rent, bool());
MOCK_METHOD1(Return, double(int kilometers));
MOCK_METHOD0(Clean, void());
};
#endif
Edit1: As suggested I have tried to use the reference (&) of Car*.
This kills the error I've stated above, but leaves me with some other errors:
error: cannot declare field ‘AdminTest::car’ to be of abstract type ‘Car’
Car car;
error: ‘class Car’ has no member named ‘gmock_GetLicencePlate’
car is a pointer to Car. Its type is: Car*. In order to call Car members from a Car*, you must dereference the pointer. This is automatically done when using the car->x syntax, which is equivalent to (*car).x.
I assume that EXPECT_CALL requires a non-pointer argument. Therefore, you can get a reference to car and pass it to the macro:
Car& car_ref = *car;
EXPECT_CALL(car_ref, GetLicencePlate()).WillOnce(Return("fh-01-ict"));
First is the pointer issue, that Vittorio already said but, also, you need to mock Car object to use EXCEPT_CALL:
class MockCar : public Car{
// Here I assume that original method is const
MOCK_CONST_METHOD0(GetLicencePlate);
}
TEST(RentalAdministrationAdd, test_add_car_to_empty_administration)
{
RentalAdministration admin;
MockCar car;
EXPECT_CALL(car, GetLicencePlate()).WillOnce(Return("fh-01-ict"));
EXPECT_TRUE(admin.Add(&car));
}
You can see in my examle that you are not using real car object but a Mock one where you can control access and force return values
I have found the solution.
For anyone wondering: Inside one class (RentalAdministration) I had included the Car.h file from the cars folder. (like #include "cars/Car.h")
However, for the test a different Car.h should be used. Therefore, changing to #include "Car.h" made it work.
I previously asked a question about a delphi and a C/C++ DLL.
I have now another question about a record / struct.
The DLL should be able to dynamically CHANGE the VALUE of the pointer vars from the MainAPP.
My delphi MAINAPP has the following record:
type MyRec = record
MyInteger : Pointer;
MyWideString : pwidechar;
MyString : pchar;
MyBool : Pointer
end;
type
TMyFunc = function ( p : pointer ): pointer; stdcall;
procedure test;
var
MyFunction : TMyFunc;
TheRecord : MyRec;
AnInteger : Integer;
AWideString : WideString;
AString : String;
ABool : Bool;
begin
AnInteger := 1234;
AWideString := 'hello';
AString := 'hello2';
ABool := TRUE;
TheRecord.MyInteger := #AnInteger;
TheRecord.MyWideString := pwidechar(AWideString);
TheRecord.AString := pchar(AString);
TheRecord.ABool := #ABool;
[...]
#MyFunction := GetProcAddress...
[...]
MyFunction (#TheRecord); // now the DLL should be able to change the values dynamically.
MessageBoxW (0, pwidechar(AWideString), '', 0); // Show the results how the DLL changed the String to...
end;
C/C++ Code (just example)
typedef struct _TestStruct{
void *TheInteger; // Pointer to Integer
wchar_t *TheWideString; // Pointer to WideString
char *TheAnsiString; // Pointer to AnsiString
bool *TheBool // Pointer to Bool
}TestStruct;
__declspec(dllexport) PVOID __stdcall MyExportedFunc (TestStruct *PTestStruct)
{
MessageBoxW(0 ,PTestStruct->TheWideString, L"Debug" , 0); // We read the value.
PTestStruct->TheWideString = L"Let me change the value here.";
return 0;
}
For some reasons it crashes etc.
What do I do wrong?
Thanks for help.
This probably isn't the cause of the crash at the point where the C++ code assigns to the TheWideString pointer, but I do see a problem of expectations...
I notice that you're putting the address of the string data that the Delphi AWideString variable points to into the MyWideString field of the record. You pass the record to the C++ function, which assigns a new pointer value to the TheWideString/MyWideString field of the record. When execution returns to the Delphi code, you output the contents of the AWideString variable.
Your comments indicate that you expect the contents of the AWideString variable to be changed by the C++ function, but that's not what will happen.
The C++ function changes the field in the structure. It does nothing to the memory location that the field previously pointed to. The data that AWideString points to will not be affected by the C++ function.
If the C++ code copied data into the address contained in the field, then it would overwrite the string data that AWideString points to. Since AWideString is a Delphi managed string, and the C++ function would be copying more data to that string memory area than the original string had allocated space for, copying data in the C++ function would write past the end of the Delphi allocated string buffer and probably corrupt the Delphi heap. A crash may occur some time later. So it's a good that you're only assigning the pointer to the field, not copying the data! ;>
To see what the C++ function changed, your Delphi code should output the contents of the MyWideString field of the record after the call to the C++ function.
You are mismanaging the string fields. PWideChar and PChar are not the same thing as "pointer to WideString" and "pointer to AnsiString". Delphi has PWideString (WideString*) and PAnsiString (AnsiString*) types for that purpose instead. You should also use Delphi's PInteger (int*) and PBoolean (bool*) types instead of Pointer (void*). Delphi and C++ are both type-safe languages. Stay away from untyped pointers when possible, your code will be better for it.
type
PMyRec = ^MyRec;
MyRec = record
MyInteger : PInteger;
MyWideString : PWideString;
MyAnsiString : PAnsiString;
MyBool : PBoolean;
end;
TMyFunc = function ( p : PMyRec ): Integer; stdcall;
procedure test;
var
MyFunction : TMyFunc;
TheRecord : MyRec;
AnInteger : Integer;
AWideString : WideString;
AAnsiString : AnsiString;
ABool : Bool;
begin
AnInteger := 1234;
AWideString := 'hello';
AAnsiString := 'hello2';
ABool := TRUE;
TheRecord.MyInteger := #AnInteger;
TheRecord.MyWideString := #AWideString;
TheRecord.MyAnsiString := #AAnsiString;
TheRecord.MyBool := #ABool;
[...]
#MyFunction := GetProcAddress...
[...]
MyFunction (#TheRecord);
MessageBoxW (0, PWideChar(AWideString), '', 0);
end;
.
typedef struct _MyRec
{
int *MyInteger; // Pointer to Integer
WideString *MyWideString; // Pointer to WideString
AnsiString *MyAnsiString; // Pointer to AnsiString
bool *MyBool; // Pointer to Bool
} MyRec, *PMyRec;
__declspec(dllexport) int __stdcall MyExportedFunc (PMyRec PRec)
{
MessageBoxW(NULL, PRec->MyWideString->c_bstr(), L"Debug" , 0);
*(PRec->MyWideString) = L"Let me change the value here.";
return 0;
}
With that said, it can be very dangerous to manipulate AnsiString (and UnicodeString) values across a DLL boundary like this, especially if the EXE and DLL are written in different versions of Delphi/C++Builder due to RTL differences, memory manager differences, payload layout differences, etc. WideString is OK to pass around, though, because it's memory and layout are controlled by the OS, not the RTL.
Synchronize fields order in the structures. You can break memory heap using wrong pointers. Also, check alignment both in Delphi and C++.
It seems normally people receive these errors when working with pointers, array, structs, etc. I'm getting it on every integer in a class, which confuses me. I'm sure I'm just missing some small technical detail (I'm a bit new to this).
The exact error is:
First-chance exception at 0x003e6616 in Mine.exe: 0xC0000005:
Access violation reading location 0x00000008.
Unhandled exception at 0x003e6616 in Mine.exe: 0xC0000005:
Access violation reading location 0x00000008.
The code breaks at the first line in this class method:
void Grid::Move(int x, int y)
{
this->offX+=x;
this->offY+=y;
for (int i=0;i<2;i++)
for (int k=0;k<2;k++)
BitmapSetxy(chunks[i][k]->map,this->offX,this->offY);
}
Here is the constructor of Grid:
Grid::Grid()
{
totalW =320*2;
totalH = 320*2;
offX = 0;
offY = 0;
//Fill the chunks array with Maps to be used
for (int i=0;i<2;i++)
for (int k=0;k<2;k++)
chunks[i][k] = new Map(i*320,k*320);
//Everything starts as dirt
for (int x=0;x<(320*2)/20;x++)
for (int y=0;y<(320*2)/20;y++)
blocks[x][y] = bType::Dirt;
}
And the header file:
#ifndef MapDef
#define MapDef
#include "Map.h"
class Grid
{
private:
int totalW, totalH;
int offX, offY;
public:
enum bType
{
Blank,
Dirt,
Copper
};
Map * chunks[2][2];
bType blocks[32][48];
void RemoveBlock(int x, int y);
bType GetBlockAt(int x, int y);
int GetAbsolutePosition20(int);
int GetMapIndex(int);
int GetChunkRelative(int,int);
bType GetBlockBelow(int x, int y);
bType GetBlockAbove(int x, int y);
bType GetBlockSide(int x, int y, bool isRight);
void Move(int x, int y);
Grid();
};
#endif
When looking at the locals view of the current instance of Grid totalW, totalH, offX,offY all show the CXX0030 error, but the two arrays are perfectly fine. What exactly is going on here?
EDIT:
The definition of the grid pointer is stored in a separate little namespace that serves as something of a static class:
namespace Engine
{
static Grid * grid;
static Player * player;
}
It is actually created here in the main cpp file:
//Initialize engine
Engine::grid = new Grid();
Engine::player = new Player(160,240);
Here is the excerpt where it is called, in another class called Player
if (y>392 && y<480 && x>75 && x<152)
{
printf("Right");
Engine::grid->Move(20,0);
}
Edit 2:
I'm sorry, I forgot to remove the "static" keyword from the grid declaration in engine. I believe that was what was causing the problem.
According to the error message, your code is trying to access address 0x00000008, which is very close to 0. This means you probably have a null pointer of type Grid * somewhere and you are calling a function on it.
You should either ensure that the pointer is not null, or check it. For example:
Grid * grid = ...;
if (grid == NULL){ return; }
grid->move(0,1);
Note that NULL is the same as 0.
What is the value of 'this'? Are you trying to dereference a null pointer to an instance of Grid?