Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Initial implementation of timers #70

Open
wants to merge 11 commits into
base: development
Choose a base branch
from
Open

Conversation

Jacob-Mango
Copy link
Collaborator

No description provided.

Copy link
Owner

@Arkensor Arkensor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Alright, lots of thoughts on this. The docs need some more general and easier examples, also there is no real guideline to tell when to choose CF_Timer and CF_TimerBase. I still don't understand the split after having read all of the code.

What I understood is that CF_Timer is essentially CF_TimerBase but you pass in the wrapper instance, function to call on each tick and the tick interval. And you can pass some data in there that is stored and passed into the tick invoke each time. That is all useful, but I don't quite get any anyone would want to NOT use that and JUST use CF_TimerBase.

Memory management is handled all for you. To create a timer you run `CF_Timer.Create` with the arguments you specify. Note that an interval of `0.0` means the timer will tick every frame.

```csharp
class TestClass : Managed
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does managed matter here? If not I would remove it, otherwise it implies that timers only work on managed wrappers.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CF_Timer does only work on Managed classes

Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why would it matter where a CF_Timer is contained in? I refer to TestClass

{
Widget widget = ...
float timeToFade = ...
CF_Timer.Create(this, "FadeIn", 0.0, new CF_TimerParam1<Widget, float>(widget, timeToFade));
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The parameters should be explained by showing the function prototype with their default values in the text above when referring to CF_Timer.Create

Also are you sure it's "FadeIn" and not "TimerFunction"? Because otherwise, I do not understand the connection between the function and the timer at all.

Comment on lines 17 to 27
void TimerFunction(CF_Timer timer, float deltaTime, Widget widget, float timeToFade)
{
if (timer.GetTime() > timeToFade * 1000.0)
{
timer.Stop();
return;
}

float alpha = timer.GetTime() / (1000.0 * timeToFade);
widget.SetAlpha(Easing.EaseInCubic(alpha));
}
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That example is way too much. You want to explain the basic functionality of a timer, so please put in the most basic possible way to setting up and using a timer ... with something like Print("Tick") or whatever in the function body. You can add some advanced examples further into the docs with some tips and tricks if you think people would miss out on something otherwise.

@Jacob-Mango
Copy link
Collaborator Author

but I don't quite get any anyone would want to NOT use that and JUST use CF_TimerBase.

There would be minimal use-cases when one would choose CF_Timer over CF_TimerBase, yes. When I asked other modders, what I got in reply was that it is a good substitute for ScriptCallQueue::CallLater since that function degrades after 6 hours of server up-time.

Copy link
Owner

@Arkensor Arkensor left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not understand the concept of what an "Instance Timer" is supposed to be. If this is about the managed vs class problem or if you mean something like a pre-built timer that can be instantiated multiple times with different params or something ... Read through the comments and whatever it is, make sure it's explained better in the docs.

@@ -0,0 +1,69 @@
class CF_DelayCall : CF_TimerBase
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. I am not sure what the vision is for DelayCall ... the name suggests delaying ONE function call to a later time ... aka the same that ScriptCallQueue already does.
    Do you maybe mean RepatedCall/ReapeatableCall since we need to store the result of CF_DelayCall::Create() somewhere already?
    If it was just for a one-time call the storage should be static and the return value void - e.g.
void main()
{
	CF_DelayCall.Create(inst, "SomeFunc", 0.5, ...)
}
  1. If the "delay" bit stays: CF_DelayedCall or CF_DelayCall since we will interact with this class only via Create .. and it sounds nicer to create a delayed call instead of a delay call IMO.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure what the vision is for DelayCall ... the name suggests delaying ONE function call to a later time ... aka the same that ScriptCallQueue already does.

Yeah. According to the source that I've outlined in private messages to you, ScriptCallQueue has issues when a large wait time has been inputted.

Do you maybe mean RepatedCall/ReapeatableCall since we need to store the result of CF_DelayCall::Create() somewhere already?

FYI, that's what CF_Timer is doing already

*
* @note The function passed must have a signature that starts with 'CF_TimerBase,float` and then continues with the matching 'params'.
*/
static CF_TimerBase Create(Managed instance, string function, int delay, CF_TimerParam params = null)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Does it need managed here? Same discussion we had about normal timers - if we are responsible to handle the case when the instance that we should invoke becomes invalid.
    Changing it to class would allow this to be used with existing custom classes that use inheritance.

  2. Change the delay param to be float to fit the rest of the timer functions.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it need managed here? Same discussion we had about normal timers - if we are responsible to handle the case when the instance that we should invoke becomes invalid.
Changing it to class would allow this to be used with existing custom classes that use inheritance.

My mistake in forgetting about CF_DelayedCall

Change the delay param to be float to fit the rest of the timer functions.

Safer to use an int, since CF_DelayedCall is designed to operate over a very long time. CF_Timer uses a float because the interval between each call is expected to be within a safe range for floating-point errors it is fine. CF_DelayedCall is expected to only call the function once over minutes or hours later, this can have floating-point errors if a modder wanted a precise time.

CF_Timer.Create(this, "FadeIn", 0.0, new CF_TimerParam1<Widget, float>(GetLayoutRoot(), FADE_TIME));
}

void FadeIn(CF_TimerBase timer, float deltaTime, Widget widget, float timeToFade)
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looking at this example I think it would be nicer to combine the invoke info into one small struct

class CF_TimerInfo
{
	CF_TimerBase timer;
	float deltaTime;
}

So that the timer only gets

void FadeIn(CF_TimerInfo info, Widget widget, float timeToFade)

### Basic Example

```csharp
class SomeClass : Managed
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

you want to use the timer outside of a Managed class

And the example you show uses a Managed class? Copy-paste mistake maybe?

{
Print("Timer has ran for " + m_TimerElapsed + " seconds and the owner is " + m_SomeClass + ".");

// Experiment removing the `Managed` class from `SomeClass` inheritance.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is this comment about?


### Advanced Example

Comparing to the advanced example from `Instance Timers`, this is how the new code will be created and ran.
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I do not understand the difference to the other example. Whatever you mean with "Instance Timers" is not self-explanatory from the example below.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants