WxTextCtrl unable to load large texts - c++

I've read about the solutuon written here on a post a year ago
wx.TextCtrl.LoadFile()
Now I have a windows application that will generate color frequency statistics that are saved in 3D arrays. Here is a part of my code as you will see on the code below the printing of the statistics is dependent on a slider which specifies the threshold.
void Project1Frm::WxButton2Click(wxCommandEvent& event)
{
char stat[32] ="";
int ***report = pGLCanvas->GetPixel();
float max = pGLCanvas->GetMaxval();
float dist = WxSlider5->GetValue();
WxRichTextCtrl1->Clear();
WxRichTextCtrl1->SetMaxLength(100);
if(dist>0)
{
WxRichTextCtrl1->AppendText(wxT("Statistics\nR\tG\tB\t\n"));
for(int m=0; m<256; m++){
for(int n=0; n<256; n++){
for(int o=0; o<256; o++){
if((report[m][n][o]/max)>=(dist/100.0))
{
sprintf(stat,"%d\t%d\t%d\t%3.6f%%\n",m,n,o,report[m][n][o]/max*100.0);
WxRichTextCtrl1->AppendText(wxT(stat));
}
}
}
}
}
else if(dist==0) WxRichTextCtrl1->LoadFile("histodata.txt");
}
The solution I've tried so far is that when I am to print all the statistics I'll get it from a text file rather than going through the 3D array... I would like to ask if the Python implementation of the segmenting can be ported to C++ or are there better ways to deal with this problem. Thank you.
EDIT:
Another reason why I used a text file instead is that I observed that whenever I do sprintf only [with the line WxRichTextCtrl1->AppendText(wxT(stat)); was commented out] the computer starts to slow down.
-Ric

Disclaimer: My answer is more of an alternative than a solution.
I don't believe that there's any situation in which a user of this application is going to find it useful to have a scrolled text window containing ~16 million lines of numbers. It would be impossible to scroll to one specific location in the list that the user might need to see easily. This is all assuming that every single number you output here has some significance to the user of course (you are showing them on the screen for a reason). Providing the user with controls to look up specific, fixed (reasonable) ranges of those numbers would be a better solution, not only in regards to a better user experience, but also in helping to resolve your issue here.
On the other hand, if you still insist on one single window containing all 64 million numbers, you seem to have a very rigid data structure here, which means you can (and should) take advantage of using a virtual grid control (wxGrid), which is intended to work smoothly even with incredibly large data sets like this. The user will likely find this control easier to read and find the section of data they are looking for.

Related

QProcess How to deal with too much input?

I'm using 3 command line tools via QProcesses to play music on my Linux (Mint) desktop via the Jack server. It's all working very well, but the input from one of the tools 'jack_showtime' arrives at about 12,000 lines per second.
I only need to see one line every 0.1 seconds, but the only way I've found to get a full recent line is like:
j_s->readAll(); // j_s is the jack_showtime QProcess
waitAbit(20); // a 20 mS delay
QString aShowtimeLine = j_s->readLine();
aShowtimeLine = j_s->readLine();
What would be a better way to deal with so much unwanted input? It seems that; without the readAll, a line will be much too old. Without the delay, I get a blank line and without the two readLines I get part of a line.
I'd also be interested in a Bash script that could absorb most of the input, or similar.
I suggest something like this, such that no matter how fast or how slow you get input from the child process, you always use the only most recent value, every 100mS:
// at startup or in your class constructor or wherever
connect(j_s, SIGNAL(readyRead()), this, SLOT(ReadDataFromJack()));
connect(&_myQTimer, SIGNAL(timeout()), this, SLOT(UseOneLine()));
_myQTimer.start(100);
void MyClass :: ReadDataFromJack()
{
while(j_s->canReadLine())
{
char buf[1024];
qint64 bytesRead = j_s->readLine(buf, sizeof(buf));
if ((bytes > 0)&&(CanParseText(buf))
{
this->_mostRecentResult = ParseText(buf);
}
}
}
void MyClass :: UseOneLine()
{
printf("100mS have elapsed, time to use _mostRecentResult=%i for something!\n", this->_mostRecentResult)
}
(Note that CanParseText(buf) and ParseText(buf) above are imaginary placeholders for whatever code you use to parse ASCII text coming from your child process into data to be used by your program)
Bulls eye! Thank you. You seem to know what I already had, so it was easy to add the bits I didn't have. Mainly the limited size buffer and, as I've never seen a line longer than 79 characters, I reduced it to 100. I may have been on the right track, while looking for a script solution, when I tried to use 'stdbuf', but dealing with it all in my program is much better.
Lines received are easy to parse. I only want the first number (which can be as low as zero) from something like this:
frame = 293532731 frame_time = 114978548 usecs = 2421437949 state: Rolling
I use the following, which seems reasonably minimal:
QString recentLine = QString::fromLocal8Bit(buf);
recentLine.remove(0,8);
recentLine.chop(recentLine.length() - recentLine.indexOf(" "));
int numSamples = recentLine.toInt();
I put a counter in the ReadDataFromJack() class and see between 2,000 and 3,000 visits per 100mS!
The number represents the position of the 'play head' in samples (at 48k per second) and wont exceed the integer range in Qt, but I see you use a qint64 (long long) in your example. Should I do the same for my number?
Sorry it's an answer (and a further question), but it's too long for a comment.

If I were to take an old Windows 95 .EXE written in C++, and I wanted to convert 8bit Integers to 16bit Integers, would it be difficult?

If I had an old PC game that has certain variables that cannot exceed 255 without crashing, would it be possible to convert ALL 8bit integers into 16bit integers by modifying the Windows 95 executable?
The game I'm talking about is Total Annihilation from 1997. And although the game itself was way ahead of it's time and had the capabilities to be modded into epic experiences, (Hell, the game was so ahead of it's time, the data files use JSON-like syntax... The game also supports 4K and looks amazing still.) there is unfortunately a limit to the total number of weapons in the game. All weapons have IDs, and the max ID of a weapon is 255 as can be seen below:
[NUCLEAR_MISSILE]
{
ID=122;
name=Nuclear Missile;
rendertype=1;
lineofsight=1;
vlaunch=1;
model=ballmiss;
range=32000;
reloadtime=180;
noautorange=1;
weapontimer=5;
flighttime=400;
weaponvelocity=350;
weaponacceleration=50;
turnrate=32768;
areaofeffect=512;
edgeeffectiveness=0.25;
energypershot=180000;
metalpershot=2000;
stockpile=1;
targetable=1;
commandfire=1;
cruise=1;
soundstart=misicbm1;
soundhit=xplomed4;
firestarter=100;
smokedelay=.1;
selfprop=1;
smoketrail=1;
propeller=1;
twophase=1;
guidance=1;
tolerance=4000;
shakemagnitude=24;
shakeduration=1.5;
explosiongaf=commboom;
explosionart=commboom;
waterexplosiongaf=fx;
waterexplosionart=h2oboom2;
lavaexplosiongaf=fx;
lavaexplosionart=lavasplashlg;
startsmoke=1;
[DAMAGE]
{
default=5500;
ARMCOM=2900;
CORCOM=2900;
}
}
Would this be worth it at all to attempt? I'm not very familiar with Assembly language, but I've heard that with C++ you sometimes have to write your own assembly language in certain instances back in the day.
All I want to do is just bump up all 8bit Ints to 16bit by editing the .EXE, how difficult would this be to pull off?
All I want to do is just bump up all 8bit Ints to 16bit by editing the .EXE, how difficult would this be to pull off?
Essentially impossible without access to the source code. Replacing an 8-bit integer with a 16-bit one would change the size and layout of the data structure which contained it. Any code which "touched" those objects, or any objects which contained them, would need to be updated. Identifying that code would be an extensive project -- in all probability, it'd require most of the game to be manually decompiled to C source code.

How does a program interact with another program?

Alright, I'm a little bit (honestly way too) confused about how the heck I can make a program interact with another program.
For example, let's say a game, a shooter, when you run an external program and you make your character not able to die, or immediately shoot when detects an enemy, etc...
I was reading a little bit about it, and they say you have to know how the "target" is composed. But I still don't get it.
For example, let's say we've got a simple code like this:
#include <iostream>
#include <windows.h>
int main() {
for(int h = 0; ; h++) {
std::cout << "The H's value is: " << h << std::endl;
Sleep(1000);
}
return 0;
}
Then, how do I create another program where I can change the H's value to zero everytime I press any key?
Don't get me wrong, I ain't trying to hack anyone or anything, I'm just curious about how those programs work.
(Sorry if I've got some grammar issues, English isn't my native language).
Specific to your program in the exapmle if we take that the program is already compiled and you are not allowed to make any changes to the source code the solution would be to build a program which will run with high enough privileges to examine this process's memory and directly change the in-memory value of h, which should be on the top of the stack(or almost).
Speaking of some more "legal" ways to do so you should check you should read about inter process communication which can be done with multiple methods. Read this.
However most "Bots" and programs which help cheaters in games are in many cases graphics based and are able to analyse the image and thus help aim. On the other hand some "recoil reducers" simply move your mouse in the opposite direction of the recoil of the gun in game. So there is a ton of approaches to your question and for every particular case the answer might be different.

Arduino substring doesn't work

I have a static method that searches (and returns) into String msg the value between a TAG
this is the code function:
static String genericCutterMessage(String TAG, String msg){
Serial.print("a-----");
Serial.println(msg);
Serial.print("b-----");
Serial.println(TAG);
if(msg.indexOf(TAG) >= 0){
Serial.print("msg ");
Serial.println(msg);
int startTx = msg.indexOf(TAG)+3;
int endTx = msg.indexOf(TAG,startTx)-2;
Serial.print("startTx ");
Serial.println(startTx);
Serial.print("endTx ");
Serial.println(endTx);
String newMsg = msg.substring(startTx,endTx);
Serial.print("d-----");
Serial.println(newMsg);
Serial.println("END");
Serial.println(newMsg.length());
return newMsg;
} else {
Serial.println("d-----TAG NOT FOUND");
return "";
}
}
and this is output
a-----[HS][TS]5132[/TS][TO]5000[/TO][/HS]
b-----HS
msg [HS][TS]5132[/TS][TO]5000[/TO][/HS]
startTx 4
endTx 30
d-----
END
0
fake -_-'....go on! <-- print out of genericCutterMessage
in that case I want return the string between HS tag, so my expected output is
[TS]5132[/TS][TO]5000[/TO]
but I don't know why I receive a void string.
to understand how substring works I just followed tutorial on official Arduino site
http://www.arduino.cc/en/Tutorial/StringSubstring
I'm not an expert in C++ and Arduino but this looks like a flushing or buffering problem, isn't it?
Any idea?
Your code is correct, this should not happen. Which forces you to consider the unexpected ways that this could possibly fail. There is really only one candidate mishap I can think of, your Arduino is running out of RAM. It has very little, the Uno only has 2 kilobytes for example. It doesn't take a lot of string munching to fill that up.
This is not reported in a smooth way. All I can do is point you to the relevant company page. Quoting:
If you run out of SRAM, your program may fail in unexpected ways; it will appear to upload successfully, but not run, or run strangely. To check if this is happening, you can try commenting out or shortening the strings or other data structures in your sketch (without changing the code). If it then runs successfully, you're probably running out of SRAM. There are a few things you can do to address this problem:
If your sketch talks to a program running on a (desktop/laptop) computer, you can try shifting data or calculations to the computer, reducing the load on the Arduino.
If you have lookup tables or other large arrays, use the smallest data type necessary to store the values you need; for example, an int takes up two bytes, while a byte uses only one (but can store a smaller range of values).
If you don't need to modify the strings or data while your sketch is running, you can store them in flash (program) memory instead of SRAM; to do this, use the PROGMEM keyword.
That's not very helpful in your specific case, you'll have to look at the rest of the program for candidates. Or upgrade your hardware, StackExchange has a dedicated site for Arduino enthusiasts, surely the best place to get advice.

Callgrind: Profile a specific part of my code

I'm trying to profile (with Callgrind) a specific part of my code by removing noise and computation that I don't care about.
Here is an example of what I want to do:
for (int i=0; i<maxSample; ++i) {
//Prepare data to be processed...
//Method to be profiled with these data
//Post operation on the data
}
My use-case is a regression test, I want to make sure that the method in question is still fast enough (something like less than 10% extra instructions since the last implementation).
This is why I'd like to have the cleaner output form Callgrind.
(I need a for loop in order to have a significant amount of data processed in order to have a good estimation of the behavior of the method I want to profile)
My first try was to change the code to:
for (int i=0; i<maxSample; ++i) {
//Prepare data to be processed...
CALLGRIND_START_INSTRUMENTATION;
//Method to be profiled with these data
CALLGRIND_STOP_INSTRUMENTATION;
//Post operation on the data
}
CALLGRIND_DUMP_STATS;
Adding the Callgrind macros to control the instrumentation. I also added the --instr-atstart=no options to be sure that I profile only the part of the code I want...
Unfortunately with this configuration when I start to launch my executable with callgrind, it never ends... It is not a question of slowness, because a full instrumentation run last less than one minute.
I also tried
for (int i=0; i<maxSample; ++i) {
//Prepare data to be processed...
CALLGRIND_TOGGLE_COLLECT;
//Method to be profiled with these data
CALLGRIND_TOGGLE_COLLECT;
//Post operation on the data
}
CALLGRIND_DUMP_STATS;
(or the --toggle-collect="myMethod" option)
But Callgrind returned me a log without any call (KCachegrind is white as snow :( and says zero instructions...)
Did I use the macros/options correctly? Any idea of what I need to change in order to get the expected result?
I finally managed to solve this issue... This was a config issue:
I kept the code
for (int i=0; i<maxSample; ++i) {
//Prepare data to be processed...
CALLGRIND_TOGGLE_COLLECT;
//Method to be profiled with these data
CALLGRIND_TOGGLE_COLLECT;
//Post operation on the data
}
CALLGRIND_DUMP_STATS;
But ran the callgrind with --collect-atstart=no (and without the --instr-atstart=no!!!) and it worked perfectly, in a reasonable time (~1min).
The issue with START/STOP instrumentation was that callgrind dumps a file (callgrind.out.#number) at each iteration (each STOP) thus it was really really slow... (after 5min I had only 5000 runs for a 300 000 iterations benchmark... unsuitable for a regression test).
The toggle-collect option is very picky in how you specify the method to use as trigger. You actually need to specify its argument list as well, and even the whitespace needs to match! Use the method name exactly as it appears in the callgrind output. For instance, I am using this invokation:
$ valgrind
--tool=callgrind
--collect-atstart=no
"--toggle-collect=ctrl_simulate(float, int)"
./swaag
Please observe:
The double quotes around the option.
The argument list including parentheses.
The whitespace after the comma character.