How to stop infinite cola layout manually? - cytoscape.js

I had used infinite option in cola layout to draw the nodes and their connections. I was trying to add manual stop function to this when all the nodes in the graph get well settled. But I couldn't find a way to do this.
So, how can I manually stop the cola layout?
I cannot use max simulation time option as the number of nodes in the graph and their connections can vary and so deciding this time is not possible.
As a hack, I am using currently like
var simulationStopTimer = setInterval(function (){
if (simulationStopNow){
options.infinite = false;
adaptor.stop();
clearInterval(simulationStopTimer);
}
}, 10000);
So, i am using a timer every 10 seconds to check whether the user has clicked a button to stop the layout. Is there is any better way?

If you create a layout object, you can call layout.stop() : http://js.cytoscape.org/#layouts/layout-manipulation/layout.stop
For your case, however, that is unnecessary:
Physics layouts automatically stop once they're settled. Make sure to set your force parameters appropriately. And turn the time limit to a high value so the layout doesn't stop prematurely.

Related

Godot - Input.is_action_just_pressed() runs twice

So I have my Q and E set to control a Camera that is fixed in 8 directions. The problem is when I call Input.is_action_just_pressed() it sets true two times, so it does its content twice.
This is what it does with the counter:
0 0 0 0 1 1 2 2 2 2
How can I fix thix?
if Input.is_action_just_pressed("camera_right", true):
if cardinal_count < cardinal_index.size() - 1:
cardinal_count += 1
else:
cardinal_count = 0
emit_signal("cardinal_count_changed", cardinal_count)
On _process or _physics_process
Your code should work correctly - without reporting twice - if it is running in _process or _physics_process.
This is because is_action_just_pressed will return if the action was pressed in the current frame. By default that means graphics frame, but the method actually detect if it is being called in the physics frame or graphic frame, as you can see in its source code. And by design you only get one call of _process per graphics frame, and one call of _physics_process per physics frame.
On _input
However, if you are running the code in _input, remember you will get a call of _input for every input event. And there can be multiple in a single frame. Thus, there can be multiple calls of _input where is_action_just_pressed. That is because they are in the same frame (graphics frame, which is the default).
Now, let us look at the proposed solution (from comments):
if event is InputEventKey:
if Input.is_action_just_pressed("camera_right", true) and not event.is_echo():
# whatever
pass
It is testing if the "camera_right" action was pressed in the current graphics frame. But it could be a different input event that one being currently processed (event).
Thus, you can fool this code. Press the key configured to "camera_right" and something else at the same time (or fast enough to be in the same frame), and the execution will enter there twice. Which is what we are trying to avoid.
To avoid it correctly, you need to check that the current event is the action you are interested in. Which you can do with event.is_action("camera_right"). Now, you have a choice. You can do this:
if event.is_action("camera_right") and event.is_pressed() and not event.is_echo():
# whatever
pass
Which is what I would suggest. It checks that it is the correct action, that it is a press (not a release) event, and it is not an echo (which are form keyboard repetition).
Or you could do this:
if event.is_action("camera_right") and Input.is_action_just_pressed("camera_right", true) and not event.is_echo():
# whatever
pass
Which I'm not suggesting because: first, it is longer; and second, is_action_just_pressed is really not meant to be used in _input. Since is_action_just_pressed is tied to the concept of a frame. The design of is_action_just_pressed is intended to work with _process or _physics_process, NOT _input.
So, apparently theres a built in method for echo detection:
is_echo()
Im closing this.
I've encountered the same issue and in my case it was down to the fact that my scene (the one containing the Input.is_action_just_pressed check) was placed in the scene tree, and was also autoloaded, which meant that the input was picked up from both locations and executed twice.
I took it out as an autoload and Input.is_action_just_pressed is now triggered once per input.

Implementing real time plot with Qt5 charts

I am new to Qt and trying to implement a real time plot using QSplineSeries with Qt 5.7. I need to scroll the x axis as new data comes in every 100ms. It seems the CPU usage reaches 100% if I do not purge the old data which was appended to the series, using graphSeriesX->remove(0). I found two ways of scrolling the x axis.
const uint8_t X_RANGE_COUNT = 50;
const uint8_t X_RANGE_MAX = X_RANGE_COUNT - 1;
qreal y = (axisX->max() - axisX->min()) / axisX->tickCount();
m_x += y;
if (m_x > axisX->max()) {
axisX->setMax(m_x);
axisX->setMin(m_x - 100);
}
if (graphSeries1->count() > X_RANGE_COUNT) {
graphSeries1->remove(0);
graphSeries2->remove(0);
graphSeries3->remove(0);
}
The problem with the above is that m_x is of type qreal and at some time if I keep the demo running continuously, it will reach it's MAX value and the axisX->setMax call will fail making the plot not work anymore. What would be the correct way to fix this use case?
qreal x = plotArea().width() / X_RANGE_MAX;
chart->scroll(x, 0)
if (graphSeries1->count() > X_RANGE_COUNT) {
graphSeries1->remove(0);
graphSeries2->remove(0);
graphSeries3->remove(0);
}
However it's not clear to me how can I use the graphSeriesX->remove(0) call in this scenario. The graph will keep getting wiped out since once the series get appended with X_RANGE_COUNT values, the if block will always be true removing 0th value but the scroll somehow does not work the way manually setting maximum for x axis works and after a while I have no graph. scroll works if I do not call remove but then my CPU usage reaches 100%.
Can someone point me in the right direction on how to use scroll while using remove to keep the CPU usage low?
It seems like the best way to update data for a QChart is through void QXYSeries::replace(QVector<QPointF> points). From the documentation, it's much faster than clearing all the data (and don't forget to use a vector instead of a list). The audio example from the documentation does exactly that. Updating the axes with setMin, setMax and setRange all seem to use a lot of CPU. I'll try to see if there's a way around that.
What do you mean by "does not work the way manually setting maximum for x axis works"? The Second method you have shown works if you define x-axis range to be between 0 and X_RANGE_MAX. Is this not what you are after?
Something like: chart->axisX()->setRange(0, X_RANGE_MAX);

Elm Game of life program becomes unresponsive - is there a way to fail gracefully?

I have a basic implementation of Conway's game of life written in elm running at uminokirin.com.
The source is visible here.
The program let users adjust the size of the toroïdal grid, click on cells to change their status, and randomize the world. It works well for small values (less than 50) on my computer.
However when attempting to use the randomize grid function on bigger grids (the threshold value doesn't seem to be always the same), the program becomes unresponsive without any warning and the only way to recover is to reload the app.
There is zero optimization in the GOL algorithm and using a single svg rectangle for every cell is probably horribly inefficient, but it sill doesn't explain why the program behaves in this way instead of say, slowing down.
Is this the elm runtime giving up? Or some kind of browser safeguard?
More importantly is there a way to prevent this behavior other than arbitrarily capping the maximum size of the grid?
The behavior you are observing is due to a Javascript stack overflow. After pressing the "randomize" button, in the browser console you can see the message "Uncaught RangeError: Maximum call stack size exceeded"
This happens because the randomize function allocates several large temporary variables. In particular, the shuffle function (which is called from the randomize function) appears to allocate two temporary lists that each have one element for every cell in the life grid. Elm may be smart about releasing these on a timely basis but this appears to push it too far.
To fix this you can use a simpler randomize function. The version shown below uses Elm Generators to generate a single list of Dead/Alive values and then initializes the randomized array from that list.
randomize2 : Array Cell -> Int -> Int -> Int -> Array Cell
randomize2 grid gs sd n =
let floatGen = Random.float 0.0 1.0
lifeGen = Random.map (\b -> if (b < toFloat n/100) then Alive else Dead) floatGen
listGen = Random.list (gs*gs) lifeGen
in fst (Random.step listGen (initialSeed sd)) |> fromList
Using this randomize function I was able to resize the grid up to 600x600 and randomize successfully. At that point I stopped testing.

What is the best way to read input from keyboard using SDL?

I'm running an update() method n times per second to "update" the keyboard input from the user so I can read it later in the logic part of the program. So I find two ways of implementing this in the SDL Docs and I'm not sure which one should I use.
1; Loop for all events using SDL_PollEvent searching for key down/up events and saving the key states in a map so I can check for each key state in the logic of the program.
Note: Alternatively, I can also use SDL_PeepEvents instead of SDL_PollEvent to take only the event types that matter; so, it would not "thrown away" the events on the queue.
std::map<int, bool> keyboard; // Saves the state(true=pressed; false=released) of each SDL_Key.
void update()
{
SDL_Event event;
while(SDL_PollEvent(&event))
{
switch(event.type)
{
case SDL_KEYDOWN:
keyboard[event.key.keysym.sym] = false;
break;
case SDL_KEYUP:
keyboard[event.key.keysym.sym] = true;
break;
}
}
}
2; Taking a snapshot from the keyboard each frame so I can read it easily.
Uint8* keyboard;
void update()
{
SDL_PumpEvents();
keyboard = SDL_GetKeyState(NULL);
}
With any of above implementations I can read keyboard just like this:
if (key_map[SDLK_Return]) printf("Return has been pressed.");
Also, is there another way to do so?
I prefer to do a variation of 1, where I fill three arrays, indicating not only the current state, but also which keys just went down and which keys just went up. This allows me to easily check for those events in code (without comparing to the previous snapshot), but, most importantly, it won't miss events that last less than a frame. For example, if your game is running at 10 fps due to a slow machine, the user might press and release an important key between two calls of your update routine, and then your system will never register it. This is extremely frustrating.
SDL also sends key events when the key is held down, which allow you to have multiple key down events for each key up. I find this particularly useful when implementing keyboard scrolling through a list of items, e.g. a keyboard-controlled menu.
You should use solution 2.
Why? As SDL_GetKeyState() docs point out, before using it you are expected to call SDL_PumpEvents() to update the state array.
When you are calling SDL_PollEvent(), it implicitly calls SDL_PumpEvents(). So, it basically updates the array for SDL_GetKeyState() anyway. By parsing these events manually, you just create a second array (well, actually a much slower map) holding the same information which SDL already collected for you.
So, I would dare say that first solution means doing the same thing twice. And if you ever decide to support things such as repeated keystrokes (SDL_EnableKeyRepeat()), you'll be reimplementing even a larger part of SDL.
I realize this question is quite old, but my answer could benefit someone. Personally, I use two arrays with SDL_GetKeyState. I store one array holding the current frame's keyboard state, and one array holding that last frame's keyboard state. (With some memcpy commands, it's really easy to update them.) Along with those two arrays, I have a map that converts strings like "A" to the SDL scancode values, but that is optional.
Then, when you need to check if something is released or pressed, you can combine the two arrays to check. (I made this a function.) For example, if you know that the key is pressed this frame, but wasn't pressed last frame, it was clearly just pressed this frame. if (currentFrame["A"] == true && lastFrame["A"] == false) {/*just pressed*/}
You would then do the opposite for the released. I find that method super easy to implement and use.

Cancelling a setInterval delay while it is running in AS2

Is this possible?
I have a file in which a movie clip is launched when the user roles over another element. To make the user experience more pleasant this happens after a 3 second delay using setInterval. Is there a way of stopping and resetting this time if the user rolls off the element before the 3 seconds is up?
var xTimer = setInterval(wait, 3000);
function wait(){
show('all');
play('all');
clearInterval(xTimer);
}
Above is the code I have used to set the delay, and below is the code I had assumed would interrupt and reset the timer.
invisBtn.onRollOut = function(){
rollover_mc.gotoAndStop(1);
stop();
clearInterval(xTimer());
trace('off');
}
Any help on this would be massively appreciated.
First, the setInterval & clearInterval functions use a Number variable to work.
setInterval() returns a Number variable, and clearInterval() takes that Number in parameter to remove the previous started interval. Here you seem to keep the interval ID inside a function variable instead of a Number one.
Thus, clearInterval(xTimer()); should in reality be clearInterval(xTimer); (without the parenthesis after xTimer).
And secondly, so you can use it in the invisBtn.onRollOut function, just be sure that the xTimer variable is scoped correctly (not inside a function where the invisBtn.onRollOut isn't also), and not on different keyframes of the timeline (timeline keyframes in Flash tends to forget the code you've written on it as soon as the reading head passes onto a new keyframe of the layer which has the code on it).
Feel free to ask more details if you need !