Hey everyone so I have an array private var aFishArray:Array; that is setup with the timer inside my constructor.
tFishTimer = new Timer(800);
//Listen for timer intervals/ticks
tFishTimer.addEventListener(TimerEvent.TIMER, addMainFish,false,0,true);
//Start timer object
tFishTimer.start();
then in the end game Condition I removed the timers tFishTimer.removeEventListener(TimerEvent.TIMER, addMainFish);
tFishTimer.stop();
Now this works perfectly but the problem is when I make a new timer of the same instance inside a separate function like so
private function checkFishPowerHitBucket():void
{
for (var j:int = 0; j < aFishPowerUpArray.length; j++)
{
//get current fish in j loop
var currentfPower:mcMoreFishPowerUp = aFishPowerUpArray[j];
//test if current fish is hitting bucket
if (currentfPower.hitTestObject(bucket))
{
//If we want timer to only run a certain amount of times then new Timer(1000, ??)
tFishTimer = new Timer(100, 30);
//Listen for timer intervals/ticks
tFishTimer.addEventListener(TimerEvent.TIMER, addMainFish, false, 0, true);
//Start timer object
tFishTimer.start();
}
}
}
and then in my end game condition try to remove the timer and the movie clips from entering the screen anymore it no longer happens. The fish just keep appearing on the screen. Is there anything that i can do to remove all instances of these timers when the game is over. Im thinking that by creating a new timer with the same array it cancels the command to delete it when it starts a new timer? any help would be appreciated thanks.
also here is the addMainFish(); Function
private function addMainFish(e:Event):void
{
//Create new fish object
var newFish = new mcMainFish();
//Add fish object to stage
stage.addChild(newFish);
//Add fish to fish Array
aFishArray.push(newFish);
//trace(aFishArray.length);
}
It doesn't really 'delete' the old timer, but what has happened is that when you create the new timer and store it in the same variable, you've lost the reference to the old one, so it just resides somewhere in memory, forever running (or until it hits it's limit, if it has one).
A way to solve this particular problem is to keep a reference to the old timer(s) such as in an array, then when you make a new timer, move the old one to an Timer array first so that you have access to it still.
I do not recommend this.
Having multiple timers like this will cost you in performance and possibly a fair amount of unpredictability. Also, it can lead to some tough debugging down the road as you may have trouble tracing which timer caused which thing to fail, strange instances of objects trying to access the same data, having to deal with so many objects in itself, etc.
What you could do is just have a single dedicated timer and within that timer do All of the processing on each of your objects that need it. You could also avoid a timer altogether and just use your game loop to do this logic.
This post illustrates a similar problem and the answer there is similar to what I've mentioned here.
Related
We are reading from Kinesis and writing to parquet and we use StateSpec<ValueState<Boolean>> to avoid duplicated processing of records after gracefully stopping and relaunching our pipeline from the last savepoint.
We saw that some records were duplicated because they end up falling on a different task manager on subsequent relaunches, and we use StateSpec<ValueState<Boolean>> to store stateful information about the processed records and avoid duplicates.
We are dealing with how to clear the state every certain time without the risk of losing the most recent processed records if they are needed in an upcoming stop. (i.e, we need a something like a TTL on that class).
We thought about a timer that clears the state every certain time but that doesn't meet our requirements because we need to keep the most recent processed records.
We read here that using event time processing automatically clears State information after a window expires and we would like to know if that fits with our requirement using the StateSpec class.
Otherwise, is there a class to store state that has a kind of TTL to implement this feature?
What we have right now is this piece of code that checks if the element has already processed and a method that clears the state every certain time
#StateId("keyPreserved")
private final StateSpec<ValueState<Boolean>> keyPreserved = StateSpecs.value(BooleanCoder.of());
#TimerId("resetStateTimer")
private final TimerSpec resetStateTimer = TimerSpecs.timer(TimeDomain.PROCESSING_TIME);
public void processElement(ProcessContext context,
#TimerId("resetStateTimer") Timer resetStateTimer,
#StateId("keyPreserved") ValueState<Boolean> keyPreservedState) {
if (!firstNonNull(keyPreservedState.read(), false)) {
T message = context.element().getValue();
//Process element here
keyPreservedState.write(true);
}
}
#OnTimer("resetStateTimer")
public void onResetStateTimer(OnTimerContext context,
#StateId("keyPreserved") ValueState<Boolean> keyPreservedState) {
keyPreservedState.clear();
}
Setting the timer every time we call keyPreservedState.write(true); was enough. When the timer expires keyPreservedState.clear(); only clears the element in the contexts, not the whole state.
I'm using ASF4 API hal_timer for a ARM Cortex M4. I'm using the timer driver to timing a data sequence.
Why does no reset function exist? I'm using the timer on a TIMER_TASK_ONE_SHOT mode and want to reset it when ever I need to.
I thought a simple
timer_start(&TIMER_0);
timer_stop(&TIMER_0);
would do the trick but does not seem to work.
Is it necessary to re-initialize the timer for each timing event?
I'm probably missing something obvious. Am I approaching this problem incorrectly reason being why the method timer_reset() doesn't exist?
I have no experience of this API, but looking at the documentation it is apparent that a single timer can have multiple tasks on different periods, so resetting TIMER_0 makes little semantic sense; rather you need to reset the individual timer task attached to the timer - of which there may be more than one.
From the documentation (which is poor and contains errors), and the source code which is more reliable:
timer_task_instance.time_label = TIMER_0.time ;
where the timer_task_instance is the struct timer_task instance you want to reset. This sets the start time to the current time.
Probably best to wrap that in a function:
// Restart current interval, return interval.
uint32_t timer_restart( struct timer_descriptor* desc, struct timer_task* tsk )
{
tsk->time_label = desc->time
return tsk->interval ;
}
Then:
timer_restart( &TIMER_0, &timer_task_instance ) ;
Assuming you're using the (edited) example from the ASF4 Reference Manual:
/* TIMER_0 example */
static struct timer_task TIMER_0_task;
static void TIMER_0_task_cb(const struct timer_task *const timer_task)
{
// task you want to delay using non-existent reset function.
}
void TIMER_0_example(void)
{
TIMER_0_task.interval = 100;
TIMER_0_task.cb = TIMER_0_task_cb;
TIMER_0_task.mode = TIMER_TASK_ONE_SHOT;
timer_add_task(&TIMER_0, &TIMER_0_task);
timer_start(&TIMER_0);
}
Instead of resetting, which isn't supported by the API, you could use:
timer_remove_task(&TIMER_0, &TIMER_0_task);
timer_add_task(&TIMER_0, &TIMER_0_task);
which will effectively restart the delay associated with TIMER_0_task.
Under the hood, timer tasks are maintained as an ordered list, in order of when each task will expire, and using the functions provided by the API maintains the list order.
I can't for the life of my work out why this is happening. I have in a class derived from CCLayer. I am scheduling a method call like so when initialising the class
//create an update method for keeping track of how long its been since an animation has played
[self schedule:#selector(playIdleAnimation:)];
And the method is
//an update method that will play an idle animation after a random period of idleness
-(void) playIdleAnimation:(ccTime) dt {
//if the user isn't playing an animation, increment the time since last animation variable
if ([bodySprite numberOfRunningActions] == 0) {
timeSinceLastAnimation += (float)dt;
//now check to see if we have surpassed the time set to cause an idle animation
if (timeSinceLastAnimation > (arc4random() %14) + 8) {
//reset the cooldown timer
timeSinceLastAnimation = 0;
[bodySprite stopAllActions];
//play the idle animation
//[bodySprite runAction:[CCAnimate actionWithAnimation:waitAnimation restoreOriginalFrame:NO]];
NSLog(#"PLAYING IDLE ANIMATION");
}
}
//player is currently playing animation so reset the time since last animation
else
timeSinceLastAnimation = 0;
}
But yet, when I go to run the program the console statements show the condition is being passed twice each cooldown
012-06-29 09:52:57.667 Test Game[5193:707] PLAYING IDLE ANIMATION
2012-06-29 09:52:57.701 Test Game[5193:707] PLAYING IDLE ANIMATION
2012-06-29 09:53:05.750 Test Game[5193:707] PLAYING IDLE ANIMATION
2012-06-29 09:53:05.851 Test Game[5193:707] PLAYING IDLE ANIMATION
I am trying to fix a bug where the game crashes when I finish playing the idle animation, and I'm certain this has something to do with it.
I don't see where you are unscheduling the selector. I bet that it's normal behavior to be called ever frame kicks in, and you see it being triggered twice because it takes a frame for the layer to be deallocated.
If you want a one-time method call, do this:
-(void) playIdleAnimation:(ccTime) dt {
[self unschedule:_cmd];
// rest of the code here
}
Cocos2d 2.0 has a scheduleOnce method that you can use instead.
I'm working on a project in c, where I'm going to make some heavy physics calculations, and I want the ability to see the results when I'm finished. The way it works now is that I run GLUT on the main thread, and use a seperate thread (pthread) to do input (from terminal) and calculations. I currently use glutTimerFunc to do the animation, but the problem is that that function will fire every given time intervall no matter what. I can stop the animation by using an if statement in the animation function, stopping the variables from being updatet, but this uses a lot of unnecessary resources (I think).
To fix this problem I was thinking that I could use an extra thread with a custom timer function that I could controll myself (without glutMainLoop messing things up). Currently this is my test function to check if this would work (meaning that the function itself is in no way finished). It runs in a seperate thread createt just before glutMainLoop:
void *threadAnimation() {
while (1) {
if (animationRun) {
rotate = rotate+0.00001;
if (rotate>360) {
rotate = rotate-360;
}
glutSetWindow(window);
glutPostRedisplay();
}
}
}
The specific problem I have is that the animation just runs for a couple of seconds, and then stops. Does anybody know how I can fix this? I am planning to use timers and so on later, but what I'm looking for is a way to ensure that glutPostRedisplay will be sent the right place. I tought glutSetWindow(window) was the solution, but apparently not. If I remove glutSetWindow(window) the animation still works, just not for as long, but runs much faster (so maybe glutSetWindow(window) takes a lot of resources?)
btw the variable "window" is created like this:
glutInit(&argc, argv);
glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB);
glutInitWindowSize(854, 540);
glutInitWindowPosition(100, 100);
window = glutCreateWindow("Animation View");
init();
glutDisplayFunc(display);
glutReshapeFunc(reshape);
timerInt = pthread_create(&timerThread, NULL, &threadAnimation, NULL);
glutMainLoop();
I don't acctually know if this is correct, but it compiles just fine. Any help is greatly appriciated!
Here's a little idea, create class that will contain all dynamic settings:
class DynamicInfo {
public int vertexCount;
public float *vertexes;
...
DynamicInfo &operator=( const DynamicInfo &origin);
};
And than main application will contain those:
DynamicInfo buffers[2];
int activeBuffer = 0;
In animation thread just draw (maybe use some threads locks for one variable):
DynamicInfo *current = buffers + activeBuffer; // Or rather use reference
In calculations:
// Store currently used buffer as current (for future manipulation)
DynamicInfo *current = buffers + activeBuffer;
// We finished calculations on activeBuffer[1] so we may propagate it to application
activeBuffer = (activeBuffer + 1)%2;
// Let actual data propagate to current buffer
(*current) = buffers[activeBuffer];
Again it's locking one variable.
Because I have a tool that needs to do a lot of work at one point, I want to show a window with some text and a progressbar while doing the work.
My problem is, that because of the huge load of the work, the window never gets drawn or updated.
I know that I usually should use an extra thread for the work, but I have to use 2 collections and the database service from the current thread.
The current code is something like
StatusWindow SW = new StatusWindow();
StatusViewModel SVM = new StatusViewModel();
SVM.MaxNum = BigNumber;
SW.Show();
for (int i=0; i<BigNumber; i++)
{
List<AType> ItemsToCreate = Func1();
List<AType> ItemsToDelete = Func2();
foreach (AType cItem in ItemsToCreate)
DB.CreateItem(cItem);
foreach (AType cItem in ItemsToDelete)
DB:DeleteItem(cItem);
SVM.CurrentNum = i;
}
SW.Close();
I also read about the Dispatcher, but i don't think it is very usable in this scenario, since there would be too much access to the main thread.
Any suggestions?
Thanks
I recommend reading the article (Build More Responsive Apps With The Dispatcher) from MSDN magazine that describes how WPF works with the Dispatcher when using BackgroundWorker.
You can pass the two collections and whatever else you'd like to worker threads as long as the objects you are accessing can be accessed from different threads.
int[] arrayofInt = new int[10]
ThreadPool.QueueUserWorkItem(s =>
{
//access the array in the worker thread
arrayofInt[0] = 10;
});
When finished with the work, you need to send a message to the dialog that it should be closed now. Do that by firing an event in your thread that is handled by your dialog.