differences between bound and unbound delegates in CLI/C++ - delegates

Whats the difference between bound and unbound delegates?
heres how you create delegates of both types:
// bound delegate declaration
public delegate void Handler(int value);
// create a bound delegate
Handler^ handler = gcnew Handler(HandlerClass::Fun1);
// unbound delegate declaration
public delegate void UBHandler(ThisClass^, int value);
// create an unbound delegate
UBHandler^ ubh = gcnew UBHandler(&ThisClass::Sum);
these are nearly the same. then, you can create constructors for bound delegates that consist of two parameters:
HandlerClass^ obj = gcnew HandlerClass;
Handler^ handler2 = gcnew Handler (obj, & HandlerClass::Fun3);
it means that you can use this particular delegate to invoke a function that is not static (is an instance). but then you can do the same with unbound delegates. Here’s how you might call the ubh delegate:
ThisClass^ obj = gcnew ThisClass(99.0);
ubh(obj, 5);
so whats the point of having both types?
// code for HandlerClass
public ref class HandlerClass
{
public:
static void Fun1(int m)
{ Console::WriteLine(L”Function1 called with value {0}”, m); }
static void Fun2(int m)
{ Console::WriteLine(L”Function2 called with value {0}”, m); }
void Fun3(int m)
{ Console::WriteLine(L”Function3 called with value {0}”, m+value); }
void Fun4(int m)
{ Console::WriteLine(L”Function4 called with value {0}”, m+value); }
HandlerClass():value(1){}
HandlerClass(int m):value(m){}
protected:
int value;
};

The difference is the exact time the target object value is generated. With a bound delegate it is generated when you create the delegate object and it is forever unchanging after that. An unbound delegate doesn't store the object reference, it is generated at the time the delegate is invoked. The same delegate can then be used to invoke the target method with different objects.
Unbound delegates are a match with the syntax of C++ member function pointers. There is no direct equivalent for bound delegates in C++.

Related

Winforms: Change background colour of an element depending on value of a variable

I have a small project here in visual studio 2022, a Winforms c++/CLR project.
It is a pretty simple project and form, but I have an issue with the following:
In the Winforms app I use a small panel to display the status of some input that I get.
I want to change the background colour of the panel depending on the status of that variable.
So for example if the variable is 0, the background colour should be red, if the value of the variable is 1, it should be green.
I can easily make this work, when this is coupled to a trigger event from the user, such as mouseclick, mousehover, ....
But how do I make this work dynamically during runtime, such that even while the variable changes during runtime, the backgroundcolour of the panel changes with it too, without the need of a user input event such as a mouseclick, ... ?
What kind of class need to be made in order to make this work?
An example that shows how to bind the Property of a Control to the Property of a managed class object, implementing the INotifyPropertyChanged interface, used to trigger value change notifications.
In the ColorTrigger class, when the value of an int Property is changed, this also changes the value returned by a Property of Type Color and triggers a PropertyChanged notification.
This causes all Controls bound to the class object to read again the value of the Property specified in the binding:
somePanel->DataBindings->Add(
"BackColor", trigger, "ColorValue", false, DataSourceUpdateMode::OnPropertyChanged
);
Here, DataBindings.Add() binds the BackColor Property of a Panel Control to the ColorValue Property of the ColorTrigger class.
#pragma once
#include "ColorTrigger.h"
public ref class SomeForm : public System::Windows::Forms::Form
{
// Initialize with default values
private: ColorTrigger^ trigger = gcnew ColorTrigger();
public: SomeForm(void) {
InitializeComponent();
somePanel->DataBindings->Add("BackColor", trigger, "ColorValue", false, DataSourceUpdateMode::OnPropertyChanged);
}
Or pass different Colors to the Constructor of the ColorTrigger class:
// [...]
private: ColorTrigger^ trigger;
public: SomeForm(void) {
InitializeComponent();
trigger = gcnew ColorTrigger(gcnew array<Color> {
Color::Magenta, Color::Cyan, Color::Orange
});
somePanel->DataBindings->Add("BackColor", trigger, "ColorValue", false, DataSourceUpdateMode::OnPropertyChanged);
}
Now, when you assign a new value to the Value Property of the ColorTrigger class, the Color returned by the ColorValue Property changes accordingly and a notification is sent, causing the Binding to update and with it the Property of Controls that share the binding.
ColorTrigger managed class:
Note that this line in the Property setter:
colorIdx = Math::Max(Math::Min(value, colors->Length - 1), 0);
trims the value set in the range (0, [ColorArray].Length - 1).
You may want to throw instead, if value is outside the bounds of the array.
#pragma once
using namespace System;
using namespace System::ComponentModel;
using namespace System::Drawing;
#define nameof(_propname) #_propname
public ref class ColorTrigger : INotifyPropertyChanged
{
public:
virtual event PropertyChangedEventHandler^ PropertyChanged;
private:
array<Color>^ colors;
int colorIdx = 0;
public:
ColorTrigger(void) {
this->ColorTrigger::ColorTrigger(
gcnew array<Color> {Color::Green, Color::Orange, Color::Red}
);
}
ColorTrigger(array<Color>^ colorArr) {colors = colorArr;}
public :
property int Value {
int get() { return colorIdx; }
void set(int value) {
if (value != colorIdx) {
colorIdx = Math::Max(Math::Min(value, colors->Length - 1), 0);
ColorValue = colors[colorIdx];
}
}
}
property Color ColorValue {
Color get() { return colors[colorIdx]; }
private : void set(Color value) {
OnPropertyChanged(nameof(ColorValue));
}
}
void OnPropertyChanged(String^ prop) {
PropertyChanged(this, gcnew PropertyChangedEventArgs(prop));
}
};

How do you assign a default value to a <functional> object?

I pass a function pointer to a function using functional, and use a constructor initialization to save it in a local variable for later use. How do I assign a default value to the parameter.
Example:
function<void()> BEGINFILE;
somefunct(function<void()> BEGINFILE): BEGINFILE(BEGINFILE) {}
But I can't seem to do:
void nullfunct() {}
function<void()> BEGINFILE;
void somefunct(function<void()> BEGINFILE = nullfunct): BEGINFILE(BEGINFILE) {}
or:
void nullfunct() {}
function<void()> BEGINFILE;
somefunct(function<void()> BEGINFILE) {
BEGINFILE = BEGINFILE;
}
I've also read that functional is deprecated/removed in C++17. I've tried to find what C++17 does without success.
I suppose that somefunct is a class (or a struct) and that with
void somefunct(function<void()> BEGINFILE): BEGINfILE(BEGINFILE) {}
do you mean a constructor of somefunct.
First (secondary) problem: constructors doesn't return values, so remove the initial void.
For the main problem I suppose that you have the problem when the default function (nullfunct()) is a non static member function.
I mean, in this case
struct somefunct
{
void nullfunct() {}
std::function<void()> bf;
somefunct (std::function<void()> bf0 = nullfunct) : bf{bf0}
{ }
};
Unfortunately, a non-static member function is something strange, very different from a regular function, and you can't assign it to a std::function.
I see three ways to solve this problem.
transform it in a static one
A static member function doesn't depend from an instance of the class so is the same type of object of a regular function and can be assigned to a std::function, so if you can transform nullfunct() in a static member, you can write
struct somefunct
{
static void nullfunct() {}
std::function<void()> bf;
somefunct (std::function<void()> bf0 = nullfunct) : bf{bf0}
{ }
};
make nullfunct() an regular function.
If you can make nullfunct() a regular (not member of a class or struct) function, it becomes compatible with std::function, so
void nullfunct() {}
struct somefunct
{
std::function<void()> bf;
somefunct (std::function<void()> bf0 = nullfunct) : bf{bf0}
{ }
};
initialize with an empty function and set with a wrapping lambda
If you can't transform somefunct() in a static member function (way 1) or in regular function (way 2), you can wrap the call of somefunct() in a lambda function that you can assign to your std::function.
Unfortunately, this lambda function has to capture the this pointer and can't do it if is defined as a default value for the argument of the constructor so the way I see is initialize the std::function with an empty std::function and, in the body of the constructor, if the member contains an empty function, assign the lambda.
I mean
struct somefunct
{
void nullfunct() {}
std::function<void()> bf;
somefunct (std::function<void()> bf0 = {}) : bf{bf0}
{ if ( not bf ) bf = [this]{ this->nullfunct(); }; }
};

why singleton design pattern allowing copy of object even copy constructor and assignment operator are private?

I have created below singleton class and defined copy constructor and assignment operator as a private. When I invoke copy constructor or assignment operator, it does not call copy constructor and assignment operator(Maybe due to statically object creation). So my question is why singleton design pattern allows creating copy of object or assigning new object(which violates basic requirement of creating single instantiation of a class) form previously created object even they are declared private in a class?
Consider below code for details:-
#include <iostream>
#include "conio.h"
class singleton
{
static singleton *s;
int i;
singleton()
{
};
singleton(int x):i(x)
{ cout<<"\n Calling one argument constructor";
};
singleton(const singleton&)
{
cout<<"\n Private copy constructor";
}
singleton &operator=(singleton&)
{
cout<<"\n Private Assignment Operator";
}
public:
static singleton *getInstance()
{
if(!s)
{
cout<<"\n New Object Created\n ";
s=new singleton();
return s;
}
else
{
cout<<"\n Using Old Object \n ";
return s;
}
}
int getValue()
{
cout<<"i = "<<i<<"\n";
return i;
}
int setValue(int n)
{
i=n;
}
};
singleton* singleton::s=0;
int main()
{
// Creating first object
singleton *s1= singleton::getInstance();
s1->getValue();
singleton *s4=s1; // Calling copy constructor-not invoking copy ctor
singleton *s5;
s5=s1; // calling assignment operator-not invoking assign ope
//Creating second object
singleton *s2=singleton::getInstance();
s2->setValue(32);
s2->getValue();
//Creating third object
singleton *s3=singleton::getInstance();
s3->setValue(42);
s3->getValue();
getch();
return 0;
}
Am I missing something or my understanding is wrong.
Please help in this.
Thanks in advance.
It is always the same object. You are using pointers to access that singleton here!
It is like having 3 egg boxes, but only one egg, that "over time" placed in the different boxes. That comparison isn't perfect, but hopefully close enough.

Class method callbacks in D to C functions

I'm writing a simple, lightweight engine in D. For the input calls I use GLFW3. The library in question uses callbacks to send input events to the program.
What I would like is to use a method from a class as the callback function, rather than a function. This is proving difficult (just as it is in C++). I believe there is an elegant way to do it, but this is how I got it right now.
public void initialise(string logPath) {
[...]
m_Window = new RenderWindow();
m_Window.create();
// Lets set up the input loop.
GLFWkeyfun keyCB = function(GLFWwindow* win, int key, int scancode, int action, int mods) {
printf("Got key event: %d:%d:%d:%d\n");
RenderWindow rw = Root().getRenderWindow();
switch (key) {
case KeyboardKeyID.Q:
glfwSetWindowShouldClose(win, true);
break;
case KeyboardKeyID.H:
if (rw.hidden) {
rw.show();
} else {
rw.hide();
}
break;
default:
break;
}
};
glfwSetKeyCallback(m_Window.window, keyCB);
}
Here is the definition of the callback setting function and type:
extern (C) {
alias GLFWkeyfun = void function(GLFWwindow*, int, int, int, int);
GLFWkeyfun glfwSetKeyCallback(GLFWwindow*, GLFWkeyfun);
}
What I would like to do instead, is create a method that is part of the class. Is there any way to do this?
A solution I tried was a static method wrapped around in extern (C), this worked for calling it, but then I could (obviously) not access this or any other methods, which defeats the point of the exercise.
Thanks in advance.
The way I'd do it is to have a static map of the pointers to the class, so like:
static YourWindowClass[GLFWwindow*] mappings;
Then, in the constructor, once you get a GLFWwindow pointer, add it right in:
mappings[m_Window.window] = this;
Now, make the static extern(C) function to use as the callback. When it gets a pointer from C, look up your class reference in that mappings array and then go ahead and call the member function through that, forwarding the arguments.
So a bit of an extra step, but since it doesn't look like the callback lets you pass user-defined data to it (BTW, attention all lib writers: user-defined void* to the callbacks is sooooo useful, you should do it whenever possible!), but since it doesn't do that the associative array is the next best thing.
Well, I have figured it out my own. The solution I went with was a Singleton class InputManager. Instances of RenderWindow attach themselves to it with the following function. The InputManager then creates an anonymous function() for the RenderWindow that receives events, which then calls a function that handles the actual event.
The idea is then that listeners attach themselves to the InputManager and receive keyboard events for the RenderWindow they requested.
class InputManager {
private static InputManager m_Instance;
private RenderWindow[] m_Watched;
private KeyboardListener[][RenderWindow] m_KeyListeners;
public void recvKeyEvent(GLFWwindow* w, int k, int c, int a, int m) {
writeln("Received key: ", k);
}
public void watch(RenderWindow win) {
if (!isWatched(win)) {
// Relay the key callbacks onto the InputManager.
GLFWkeyfun keyCB = function(GLFWwindow* w, int k, int c, int a, int m) {
InputManager().recvKeyEvent(w, k, c, a, m);
};
glfwSetKeyCallback(win.window, keyCB);
}
}
private bool isWatched(RenderWindow win) {
foreach(RenderWindow w; m_Watched) {
if (win == w) {
return true;
}
}
return false;
}
public static InputManager opCall() {
if (m_Instance is null) {
m_Instance = new InputManager();
}
return m_Instance;
}
private this() {
// nothing
}
}
Works like a charm, now to figure out how to properly attach listeners elegantly.
For those curious, the full source code with how this is set up can be found at https://github.com/Adel92/Mage2D. I hope it helps someone else in a similar position with callbacks.

Proper way of raising events from C++/CLI?

I was wondering what's the proper way of raising events from C++/CLI. In C# one should first make a copy of the handler, check if it's not null, and then call it. Is there a similar practice for C++/CLI?
This isn't the whole story! You don't usually have to worry about null event handlers in C++/CLI. The code for these checks is generated for you. Consider the following trivial C++/CLI class.
public ref class MyClass
{
public:
event System::EventHandler ^ MyEvent;
};
If you compile this class, and disassemble it using Reflector, you get the following c# code.
public class MyClass
{
// Fields
private EventHandler <backing_store>MyEvent;
// Events
public event EventHandler MyEvent
{
[MethodImpl(MethodImplOptions.Synchronized)] add
{
this.<backing_store>MyEvent = (EventHandler) Delegate.Combine(this.<backing_store>MyEvent, value);
}
[MethodImpl(MethodImplOptions.Synchronized)] remove
{
this.<backing_store>MyEvent = (EventHandler) Delegate.Remove(this.<backing_store>MyEvent, value);
}
raise
{
EventHandler <tmp> = null;
<tmp> = this.<backing_store>MyEvent;
if (<tmp> != null)
{
<tmp>(value0, value1);
}
}
}
}
The usual checks are being done in the raise method. Unless you really want custom behavior, you should feel comfortable declaring your event as in the above class, and raising it without fear of a null handler.
C++/CLI allows you to override raise in custom event handlers so you don't have to test for null or copy when raising the event. Of course, inside your custom raise you still have to do this.
Example, adapted from the MSDN for correctness:
public delegate void f(int);
public ref struct E {
f ^ _E;
public:
void handler(int i) {
System::Console::WriteLine(i);
}
E() {
_E = nullptr;
}
event f^ Event {
void add(f ^ d) {
_E += d;
}
void remove(f ^ d) {
_E -= d;
}
void raise(int i) {
f^ tmp = _E;
if (tmp) {
tmp->Invoke(i);
}
}
}
static void Go() {
E^ pE = gcnew E;
pE->Event += gcnew f(pE, &E::handler);
pE->Event(17);
}
};
int main() {
E::Go();
}
If your issue is that raise isn't private, then explicitly implement it like the docs say:
http://msdn.microsoft.com/en-us/library/5f3csfsa.aspx
In summary:
If you just use the event keyword, you create a "trivial" event. The compiler generates add/remove/raise and the delegate member for you. The generated raise function (as the docs say) checks for nullptr. Trivial events are documented here:
http://msdn.microsoft.com/en-us/library/4b612y2s.aspx
If you want "more control", for example to make raise private, then you have to explicitly implement the members as shown in the link. You must explicitly declare a data member for the delegate type. Then you use the event keyword to declare the event-related members, as in the Microsoft example:
// event keyword introduces the scope wherein I'm defining the required methods
// "f" is my delegate type
// "Event" is the unrealistic name of the event itself
event f^ Event
{
// add is public (because the event block is public)
// "_E" is the private delegate data member of type "f"
void add(f ^ d) { _E += d; }
// making remove private
private:
void remove(f ^ d) { _E -= d; }
// making raise protected
protected:
void raise(int i)
{
// check for nullptr
if (_E)
{
_E->Invoke(i);
}
}
}// end event block
Wordy, but there it is.
-reilly.

Resources