wxDataViewListCtrl and wxVariant - wxwidgets

I have a simple setup, a wxDataViewListCtrl, the first column uses wxDataViewCustomRenderer and the second column is just text.
class MyCustomRenderer : public wxDataViewCustomRenderer
I add a line to the wxDataViewListCtrl like this:
wxVector<wxVariant> item;
item.push_back(wxVariant(/*a raw pointer of MyClass goes here*/));
item.push_back(wxVariant("some string goes here"));
m_data_view_list_ctrl->AppendItem(item);
item.clear();
And this is MyClass:
class MyClass final : public wxObject
And this is how my SetValue method looks like:
bool MyCustomRenderer::SetValue(const wxVariant& value)
{
MyClass* temp = static_cast<MyClass*>(value.GetWxObjectPtr());
/*Do stuff with temp here...*/
return true;
}
It worked, now it does not. It fails with the following error:
https://www.dropbox.com/s/acxbzthp3ltadny/wxwidgets.png?dl=0
The only thing I changed is that I updated my static libs of wxWidgets from 3.0.4 to 3.1.2.
Why has it stopped working? What am I missing here?
Please help me :-)
Update
Thank you all for answering. The problem was solved here. In short I needed to change this line like this:
MyCustomRenderer::MyCustomRenderer() : wxDataViewCustomRenderer("void*", wxDATAVIEW_CELL_INERT, wxALIGN_CENTER)
And this one like this:
item.push_back(wxVariant(static_cast<void*>(/*Raw pointer to an instance of MyClass*/)));

I'm not sure which change exactly is responsible for this, but the value, returned by your model for the cell being drawn, is null, so your renderer can't just use it blindly and should check if ( !value.IsNull() ) before doing it (and maybe just return in this case or do whatever is appropriate to show the absence of a value in your case).

Related

How to repeat Mono while not empty

I have a method which returns like this!
Mono<Integer> getNumberFromSomewhere();
I need to keep calling this until it has no more items to emit. That is I need to make this as Flux<Integer>.
One option is to add repeat. the point is - I want to stop when the above method emits the first empty signal.
Is there any way to do this? I am looking for a clean way.
A built-in operator that does that (although it is intended for "deeper" nesting) is expand.
expand naturally stops expansion when the returned Publisher completes empty.
You could apply it to your use-case like this:
//this changes each time one subscribes to it
Mono<Integer> monoWithUnderlyingState;
Flux<Integer> repeated = monoWithUnderlyingState
.expand(i -> monoWithUnderlyingState);
I'm not aware of a built-in operator which would do the job straightaway. However, it can be done using a wrapper class and a mix of operators:
Flux<Integer> repeatUntilEmpty() {
return getNumberFromSomewhere()
.map(ResultWrapper::new)
.defaultIfEmpty(ResultWrapper.EMPTY)
.repeat()
.takeWhile(ResultWrapper::isNotEmpty)
}
// helper class, not necessarily needs to be Java record
record ResultWrapper(Integer value) {
public static final ResultWrapper EMPTY = new ResultWrapper(null);
public boolean isNotEmpty() {
return value != null;
}
}

How to extract test name in Google Test's case method?

I've a bunch of test cases in which each case would output a file. I'd like each files would be named after the corresponding case name so the result files won't get in the way with each other. Is there any way to do that by programming?
What I have now (hate to repeat the case name since it could be changed:
TEST_F(Foo, Bar)
{
...
std::ofstream("Bar.bat");
...
}
What I want:
TEST_F(Foo, Bar)
{
...
std::ofstream(magic_method_to_get_case_name() + ".dat");
...
}
The current test's name can be accessed via the UnitTest singleton class.
::testing::UnitTest::GetInstance()->current_test_info()->name();
Because UnitTest is a singleton, this can be called from static/global test utility methods as well.
Just find out how to do that. I'll share it here in case anyone would like to know it.
Looks like GTEST_TEST_ macro would keep the name information in a private static variable:
#define GTEST_TEST_(test_case_name, test_name, parent_class, parent_id)\
class GTEST_TEST_CLASS_NAME_(test_case_name, test_name) : public parent_class {\
public:\
GTEST_TEST_CLASS_NAME_(test_case_name, test_name)() {}\
private:\
virtual void TestBody();\
static ::testing::TestInfo* const test_info_;\
GTEST_DISALLOW_COPY_AND_ASSIGN_(\
GTEST_TEST_CLASS_NAME_(test_case_name, test_name));\
};\
So, the code in any case could get the case name through it:
test_info_->name()
Case name is not the only information that could be fetched -- please check the TestInfo class in gtest.h.

Passing and recieving multi-dimensional primitive (int) arrays in objective-c

I have two objective c methods. One needs to return an int[][] and the other which needs to take int[][] as a parameter. I was originally using an NSMutableArray with NSMutableArrays as values however I was told to redo it like this in order to be compatible with some current code. I can't figure out how to make this work. I'm not sure I'm even googling the right thing. Anyway here is what I have now.
+(int [][consantValue]) getCoefficients
{
int coefficiennts [constantValue2][constantValue1] = { {0,1,2}, {3,4,5}, {6,7,8} };
return coefficients;
}
At the return statement I get the Error "Array initilizer must be an initializer list'
I also have to take the int[][] and rebuild it into an NSMutableArray of NSMutableArrays in another method but I'm hoping if someone can give me a hint on the first part I can work the second part out myself although if anyone has any advice on that I would appreciate it as well. Thanks.
The easy way to do this for fixed size array(s) is to use a struct for storage:
typedef struct {
int at[constantValue2][constantValue1];
} t_mon_coefficients;
And then you'd declare the method which returns by value:
+ (t_mon_coefficients)coefficients;
And passes by value as a parameter:
- (void)setCoefficients:(const t_mon_coefficients)pCoefficients;
If the struct is large, you should pass by reference:
// you'd use this like:
// t_mon_coefficients coef;
// [SomeClass getCoefficients:&coef];
+ (void)getCoefficients:(t_mon_coefficients* const)pOutCoefficients;
- (void)setCoefficients:(const t_mon_coefficients*)pCoefficients;
But there are multiple ways one could accomplish this.

Controller selection

In my title screen, i have a code saying that the first controller using A is the PlayerIndex.one.
Here is the code:
public override void HandleInput(InputState input)
{
for (int anyPlayer = 0; anyPlayer <4; anyPlayer++)
{
if (GamePad.GetState((PlayerIndex)anyPlayer).Buttons.A == ButtonState.Pressed)
{
FirstPlayer = (PlayerIndex)anyPlayer;
this.ExitScreen();
AddScreen(new Background());
}
}
}
My question is: How can i use the "FirstPlayer" in other classes? (without this, there is no interest in this code)
I tried the Get Set thing but i can't make it work. Does i need to put my code in another class? Do you use other code to make this?
Thanks.
You can make a static variable say : SelectedPlayer,
and assign first player to it!
then you can call the first player through this class,
for example
class GameManager
{
public static PlayerIndex SelectedPlayer{get;set;}
..
..
..
}
and right after the loop in your code, you can say:
GameManager.SelectedPlayer = FirstPlayer;
I hope this helps, if your code cold be clearer that would be easier to help :)
Ok, so to do this properly you're going to have to redesign a little.
First off, you should be checking for a new gamepad input (i.e. you should be exiting the screen only when 'A' has been newly pressed). To do this you should be storing previous and current gamepad states:
private GamePadState currentGamePadState;
private GamePadState lastGamePadState;
// in your constructor
currentGamePadState = new GamePadState();
lastGamePadState = new GamePadState();
// in your update
lastGamePadState = currentGamePadState;
currentGamePadState = GamePad.GetState(PlayerIndex.One);
Really what you need to do is modify your class that deals with input. The basic functionality from your HandleInput function should be moved into your input class. Input should have a collection of functions that test for new/current input. For example, for the case you posted:
public Bool IsNewButtonPress(Buttons buton)
{
return (currentGamePadState.IsButtonDown(button) && lastGamePadState.IsButtonUp(button));
}
Then you can write:
public override void HandleInput(InputState input)
{
if (input.IsNewButtonPress(Buttons.A)
{
this.ExitScreen();
AddScreen(new Background());
}
}
Note: this will only work for one controller. To extend the implementation, you'll need to do something like this:
private GamePadState[] currentGamePadStates;
private GamePadState[] lastGamePadStates;
// in your constructor
currentGamePadStates = new GamePadState[4];
currentGamePadStates[0] = new GamePadState(PlayerIndex.One);
currentGamePadStates[1] = new GamePadController(PlayerIndex.Two);
// etc.
lastGamePadStates[0] = new GamePadState(PlayerIndex.One);
// etc.
// in your update
foreach (GamePadState s in currentGamePadStates)
{
// update all of this as before...
}
// etc.
Now, you want to test every controller for input, so you'll need to generalise by writing a function that returns a Bool after checking each GamePadState in the arrays for a button press.
Check out the MSDN Game State Management Sample for a well developed implementation. I can't remember if it supports multiple controllers, but the structure is clear and can easily be adapted if not.

store in a variable only the first or only the second class of an element

I'm using this bit of jQ to add a class to two different elements based on the class of another (parent/grandparent, etc) element:
$(document).ready(function(){
var containerClass = $('#main-content').attr('class');
$('#nav-primary li#'+containerClass).addClass('active');
$('#aux-left div[id$='+containerClass+']').addClass('active');
});
Brilliant, but I have two problems with it:
First, when there's no class at all in <div id="main-content">, the 'active' class is added to all the #nav-primary LIs, and also to all the #aux-left DIVs; how can I modify this so that in the absence of any class on #main-content, do nothing?
Second, how can I target only the first or second of multiple classes to store in the 'containerClass' variable, e.g., <div id="main-content" class="apples bananas">?
Very much appreciated! svs
For 1: do an if-clause after your first line, e.g. like this:
if(containerClass.length > 1) {
//your addClass code
}
//EDIT: The above would be placed after you define containerClass in your script. It just checks if the container has a class or not, by measuring the content of the variable (.length). If containerClass = "", this if-condition will be false, and the contained code will not execute. Hence it should prevent your first problem from happening: that the "active" class is added to all its children, regardless of #main-content having a class or not
For 2:
classes = containerClass.split(' '); //split by space
if(classes[1]) { //if there is a 2nd class
//do something if there are multiple classes
//access the 1st class with classes[0], etc.
} else {
//do something if #main-content only has 1 class
}
//EDIT: in the above, the first line splits whatever the variable containerClass contains by an empty space. You can compare that with php's explode function: Say your container has 2 classes (class="aplles bananas"), what you'll end up with after splitting that by empty space is an array that contains both of these classes like this:
classes[0] = 'apples';
classes[1] = 'bananas';
So now you have your 1st and 2nd classes, if they exist.
The next line in my code would then do something if #main-content has a 2nd class (here: "bananas"), but you could also check against the first class with
if(classes[0]) { ...
The "else" part in my code would trigger if #main-content doesn't have a 2nd class. You could expand the above if-else-condition by first checking if a 1st class exists, then checking if a 2nd class exists, and then doing something else (or nothing) if #main-content doesn't have any classes at all. I hope this makes it clearer.
Hope this helps. On an unrelated note, you might want to add "jquery" to the tags of this post so that more people can find it :)
Still not quite there ... I'll try again, hoping this is of use to others:
Here's where I'm at (having temporarily set aside the need to check that there's at least one class):
$(document).ready(function(){
contentClasses = $('#main-content').attr('class');
contentClass = contentClasses.split(' '); // split by space
$('#nav-primary li#'+contentClass).addClass('active');
$('#aux-left div[id$='+contentClass+']').addClass('active');
}); // close doc.ready
... but this is not working as intended if there's more than one class on <div id="main-content">. Oddly, the 'active' class IS being added to the appropriately to #nav-primary LI but not to #aux-left div. The console reports the following: "Warning: Expected ']' to terminate attribute selector but found ','."
Any clarification would be greatly appreciated. svs