The dilemma I have is I want to create a timer (also called an "alarm", using Game Maker terminology) that can call ANY function after its time expires. Not just have it call a specific function pointer based on a specific signature.
So, simple question: Is this possible?
You can use C++11's std::function and std::bind to wrap whatever function you want to call after the timer expires.
Q&A with the Question poster
I have a function that takes in an Egg and a Cheese and returns an Omelet. I hand my function to your timer. When the timer's alarm goes off, with what Egg and what Cheese will you call my function? - Robert Cooper
#RobertCooper with the Egg and Cheese you gave me when you handed me the function of course! – nightcracker
#nightcracker: So when I set an alarm, I need to give the timer a function, an Egg, and a Cheese. Then again, if my callback instead takes in a Bacon, a HomeFries, Sausage, and an Oatmeal, I need to give the alarm a function, a Bacon, a HomeFries, Sausage, and an Oatmeal. For any number and combination of types, the alarm must be able to remember and store members of those types for later use on the callback function.
Recommendation
I wouldn't recommend building an alarm capable of storing any combination of cooking supplies. Keep the type signature of the alarm constant and simple. If a client want to make the alarm to make breakfast or start a band or launch a rocket-ship, make the client wrap whatever functions and variables they need into a simple functor or lambda function: one that remembers all the variables it needs and only one way to set it off (operator (), called with no arguments).
Related
Since Lambda charges me per invocation, wouldn't it be more cost efficient if I define all functions within a single file?
Or do they charge per function invocations regardless of the .py files?
Lambda charges are based on the number of invocations of your function and the time it takes for your function to run.
Whenever your lambda function is called, it will be charged for the invocation and its duration.
Case 1 (Single purpose design):
You want to implement 3 functions,
For example - ADD(),SUBTRACT(),DIVIDE()
you created a lambda function for each function.
Whenever any of your functions are called,you will be charged for that invocation.
If you called ADD()[Lambda function] then SUBTRACT()[Lambda function] then DIVIDE()[Lambda function], you will be charged once for each lambda function means total of 3.
Case 2 (Monolithic design):
You want to implement 3 functions, you wrote all three functions into different .py files but into a single Lambda function because AWS Lambda allows only single handler per Lambda function and these functions will be invoked according to the condition.
Whenever you are going to call any of the function, same Lambda function will be invoked everytime.
If you call ADD() function then SUBTRACT() function then DIVIDE() function, you will be charged for same Lambda function call every time means total of 3.
So, whether you write a separate lambda function for each function or single Lambda function for all functions, you will be charged for the number of calls and duration.
It is better to create separate Lambda functions for each function
because debugging will be easy in this case.
To know more about AWS Lambda pricing - https://aws.amazon.com/lambda/pricing/
For pricing, you get charged at the millisecond level, so the quicker and tighet each function is the better.
To keep with the idea and design of "Microservices" and follow the "S" in SOLID principles, you usually want a lambda function to do one thing.
The minute you start having lambda functions do two or more things, you're now tying those lambdas and logic together. Ideally a lambda function shouldn't need to know about another lambda function.
You can have one lambda invoke another, but you typically want some sort of eventing orchestration in place to do that for you like Eventbridge or SNS or Step Functions.
So I would avoid putting 3 sets of functionality into one lambda function because now you're vastly limited that functions ability to be reused by other parts of the application potentially.
I am currently creating my own GUI-Library based on SFML.
At the moment i am working on a Button. So when creating a button you also have to specify a callback which is a function, executed on the button click.
Now, I'm answering me what the disadvantages are of using just a pointer to a function as a button-callback, because I don't know any popular GUI-Library doing it so simply, too.
If the callback function is a long process, I would execute it in a new thread, but i'm not sure about that in the moment.
So, what would be reasons, not to use such simple solution and especially, what would be a better way?
It's a tricky problem!
Function pointers are simple to implement on the sender side, but they are difficult to use on the receiver side because they they don't have any context.
One issue is that a function pointer cannot point to a member function. That's why you often see (C-style) frameworks pass an arbitrary void *userData to their callbacks, so you can cast your this pointer and retrieve it in that way. This still needs you to write a static wrapper function to cast the pointer back and call the member function.
A more modern solution would be to use std::function. This can contain a regular function pointer, a member function pointer, but also a lambda or a functor.
However, when you add context like this (or in some other way), you quickly run into difficulties with lifetimes. When the receiving class is destroyed before the sender, what is supposed to happen? If you don't do anything, this situation will result in undefined behaviour. A solution is to track on the receiver side to which events the receiver is subscribed, and unbind them before the receiver is destroyed. And this needs to be done in both directions: when the sender is destroyed, it also needs to notify the receiver that it should forget about the sender, otherwise the receiver would later try to unbind an event that no longer exists.
And I haven't even begun to think about multithreading yet...
There are libraries that solve these problems in various ways, for example eventpp (just found through a web search, this is not an endorsement).
Another one to mention would be the Qt toolkit, which went so far as to write their own small signals and slots extension to the C++ language (implemented as a code generator and a pile of macros) to solve this problem in a very ergonomical way.
what the disadvantages are of using just a pointer to a function as a button-callback
Passing some context argument to that function would come handy.
I mean, the UI may have a lot of buttons performing the same action on various objects. Think maybe of "send message" button next to each nick in a friend list.
So you may want your buttom to pass some context arguments to the call.
But since we're talking C++, this'd better be abstracted as
struct IButtonAction
{
virtual void OnAttached() = 0;
virtual void OnDetached() = 0;
virtual void OnClick() = 0;
};
And let the client code implement this interface storing whichever Arg1, Arg2, etc in each instance object.
The button class would call OnAttached/OnDetached when it begins/ends using the pointer to an instance of this callback interface. These calls must be paired. Client implementation of these methods may perform lifetime management and synchronization with OnClick, if required.
OnClick method performs the action.
I don't think the button should bother with threads. It's the responsibility of the client code to decide whether to spawn a thread for a lengthy action.
If I call one lambda function with one request, but within that function, there are three calls made to different functions then would this count as 4 calls or is it just one call since its based on one request?
So if the count is 4 then (from economic stand point) wouldnt it be better if one writes one long function instead of many small functions, despite it being ill advised from design pattern stand point?
Every invocation of a Lambda function counts. It doesn't matter whether you call it from the console, from a CLI, from an event source, or from another Lambda function it will count as invocation.
Personally, I would focus on writing my Lambda functions in a way that makes sense and allowed me to use them effectively. If you find your costs are a factor later, you can always adjust then.
This is a followup to Clojure: Compile time insertion of pre/post functions
My goal is to call a debug function instead of throwing an exception. I am looking for the best way to store a list of stack frames, function calls and their arguments, to accomplish this.
I want to have a function (my-uber-debug), so that when I call it (instead of throwing an exception), the following things happen:
a new Java window pops up
there is a record of the current clojure stack frame
for each stack frame, there is a record of the argument passed to the function
This is so that I can move up/down the stack frames, and examine the arguments passed to get to this current point. [If somehow, magically, we can get the variables defined in "let" environments, that'd be awesome too.]
Current Idea
I'm going to have a thread local variable uber-debug, which has type:
List of StackFrames
where StackFrame = function + arguments
At each function call, it's going to push (cons the current function + arguments to uber-debug), then at the end of a function call, it's going to remove the first element from uber-debug
Then, when I call (my-uber-debug), it just pops up a new java window, and lets me interact with uber-debug
Question
The ideas I've had so far are probably not ideal for setting this up. What is the right way to solve this problem?
Edit:
The question is NOT about the Swing/GUI part. It's about how to store the stack frames.
Thanks!
Your answer may depend on a lot of factors, so I am going to answer this by giving you my thoughts.
If you merely want to store function calls and their parameters when an exception occurs, then either write a macro or function as a wrapper to accomplish this. You would then have to pass all functions to be called to this wrapper. The wrapper would perform the try catch operation and whatever else you need.
You might also want to look into Clojure meta data in addition to writing the wrapper, because your running code could look at its meta-data and make some decisions based on that as well. I have never used meta data, but the information at the link looks promising.
As a final thought, it might be helpful for you to further delineate what you want to accomplish by doing this by editing your original post and putting the information there.
For example, are these stack traces for a library or a main program?
As to storing all this information, are multiple threads going to need it, or just one?
Can you get by storing the information in a let binding at the highest level of your program, or do you need something like a ref?
In a unix pthreads based app I'm working on, I have objects of a particular class (call it class foo) being created in multiple threads. I need a specific public method of class foo invoked at or after 60s of the object coming into existence (it is not imperative that it happens at precisely 60s, just that it happens at either 60s or very shortly thereafter).
Any ideas on what timers are available that could I use to achieve this? Looking for either something that I could just drop right in to my class foo or which I could derive from.
The only real requirement is that it be thread-safe.
There are various platform specific mechanisms which will allow you to force an interruption of a thread at a given time, depending on various platform specific preconditions relating to the state of the thread. These are a bad idea unless you really need them and know why.
The correct solution, given the information in your question, would be to simply check elapsed time. Presumably these threads do some work in some sort of loop. As part of this loop, you should call e.g. foo::tick() and then let tick check to see if 60s has elapsed.
Rather than using timer, why not define a static member within the class that is incremented in the constructor (with proper protection of course)? When the static member reaches 60, either invoke the member or flag that the condition has occurred and invoke elsewhere.