Notifying a control that another control has a state change - notifications

I am using C++Builder Enterprise and need some ideas.
I have a Form with a bunch of TButton and TSpeedButton controls on it. What I want to have happen is that, when a given button is pressed, I want to disable it and several others, while enabling several other buttons, i.e. state changes.
The issue is that I am duplicating the enable/disable code in a bunch of places. I've thought about somehow using the TNotifyEvent delegation to alert the buttons of a state change, but I don't think that delegation technique will work in this situation. I want to avoid creating a bunch of sub-classes of TButton/TSpeedButton.
I also would like to try to use techniques that are available from the VCL, as in each component carries an observer list and wonder if I could leverage that somehow.

My 2 cents worth..
I have done a proof of concept for your problem, would need a lot more work but I think it is doable and should do what you want.
I will do more work on it and post if there is interest.
To find all controls of a class type on a form
--- TControlAgent->FindTControl(this, "TButton");
I added 4 buttons on a form, added code bellow to button1 click event,
TControlAgent->SetControlProperty("Enabled", "TButton", false, true, "Button3");
in this case, want controls with Enabled property whose class name is TButton, state = true or false, execute the action but but exclude control named TButton3
There result was all TButtons on the form were set to disable except for button 3
(note: the exclude option would be a lookup list of controls to be excluded from any action or be able to set a state that is not the state eg Enabled = !true or !false )
In the click event of button3 I placed the following code;
TControlAgent->SetControlProperty("Enabled", "TButton", true, true, "");
The result of this is to re-enable all the controls, this is just an idea but with with the extra work it could be possible to execute any action on any control from a single parent form for any form in a collection of forms.
I also think it could be possible to fire events, just a crazy idea...
.h file using berlin 10.1
//---------------------------------------------------------------------------
#ifndef TControlAgentH
#define TControlAgentH
//---------------------------------------------------------------------------
#include <System.SysUtils.hpp>
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <System.TypInfo.hpp>
#include <vector>
#include <algorithm>
//---------------------------------------------------------------------------
class PACKAGE TControlAgent : public TComponent
{
private:
std::vector<TControl*> FControls;
protected:
public:
std::vector<UnicodeString> excludeControlNames;
__fastcall TControlAgent(TComponent* Owner);
TControl * __fastcall GetControl(TControl* ctrl, UnicodeString property);
void __fastcall FindTControl(TForm *f, UnicodeString className);
TControl* __fastcall SetControlProperty(UnicodeString property, UnicodeString className, bool state, bool exec, UnicodeString excludeControlName );
__published:
};
//---------------------------------------------------------------------------
#endif
.cpp file
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "TControlAgent.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//
//---------------------------------------------------------------------------
// component to act as agent for other components derived from TControl
//
// Components have properties and events, is it possible to get all TControls into a vector
// then be able to get a property of a component then fire an event or carry out an action
// on the component!!!!
//---------------------------------------------------------------------------
static inline void ValidCtrCheck(TControlAgent *)
{
new TControlAgent(NULL);
}
//---------------------------------------------------------------------------
__fastcall TControlAgent::TControlAgent(TComponent* Owner)
: TComponent(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TControlAgent::FindTControl(TForm *f, UnicodeString className)
{
FControls.clear();
for(int i = 0; i < f->ControlCount; i++)
{
if(f->Controls[i]->ClassName() == className) //control classes that to set as a group
FControls.push_back(f->Controls[i]);
}
//note: could have a function that appends other class names
}
//---------------------------------------------------------------------------
TControl* __fastcall TControlAgent::SetControlProperty(UnicodeString property, UnicodeString className, bool state, bool exec, UnicodeString excludeControlName )
{
PPropInfo propinfo;
for(int i = 0; i < FControls.size(); i++)
{
if(FControls[i]->ClassName() == className)
{
propinfo = GetPropInfo(FControls[i], property);
if (!propinfo)
continue;
if(exec && FControls[i]->Name != excludeControlName )
{
if(property == "Enabled")
FControls[i]->Enabled = state;
}
}
}
}
//---------------------------------------------------------------------------
namespace Tcontrolagent
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TControlAgent)};
RegisterComponents(L"SQLite", classes, 0);
}
}
//---------------------------------------------------------------------------

**** UPDATED *****
Progress of TControlAgent
Obviously still work in progress but this code works, create a form with a TPanel, to this add 6 TButtons
Add a TControl Agent, set the OnButtonClick event as per Form code bellow
TControlAgent code
.h
//---------------------------------------------------------------------------
#ifndef TControlAgentH
#define TControlAgentH
//---------------------------------------------------------------------------
#include <System.SysUtils.hpp>
#include <System.Classes.hpp>
#include <Vcl.Controls.hpp>
#include <System.TypInfo.hpp>
#include <vector>
#include <algorithm>
class TControls;
class TControlGroup;
typedef void __fastcall (__closure *TControlAgentOnClick)(System::TObject *Sender, TControls *ctrl);
typedef void __fastcall (__closure *TButtonClickEvent)(System::TObject *Sender);
enum action {aEnabled, aOnClick, aChange};
enum tcontrols {tbutton, tedit, tcombo, tcheckbox};
//---------------------------------------------------------------------------
class PACKAGE TControlAgent : public TComponent
{
private:
std::vector<TControls*> FControls;
std::vector<TControlGroup*> FControlGroups;
TControlAgentOnClick FClickSupliment;
TButtonClickEvent FOnButtonClick;
bool FButtonClickRedirect;
protected:
public:
std::vector<UnicodeString> excludeControlNames; // not implemented yet
std::vector<TControlGroup*> __fastcall Groups();
std::vector<TControls*> __fastcall Controls(int GroupIndex);
__fastcall TControlAgent(TComponent* Owner);
TControl * __fastcall GetControl(TControl* ctrl, UnicodeString property);
void __fastcall FindTControl(TForm *f, UnicodeString className);
void __fastcall FindTControl(TPanel *p, UnicodeString GroupName, bool ClearIfControlsExists);
void __fastcall SetControlProperty(TControl *ctrl, bool state, int Action);
int __fastcall GetGroup(String name);
void __fastcall SetControlClickEvent(String ClassName, String GroupName, String ExcludeGroup, int tControlType);
void __fastcall SetButtonPropValue(TButton* b, String Property, String Value, bool v);
int __fastcall AddTControl(TControl* c, String Group);
void __fastcall SetButtonPropValue(String Group, String ExcludeGroup,int TControlType,String Property,String GroupValue,bool GroupV,String excludeGroupValue,bool excludeGroupV);
__published:
__property bool TButtonClick = {read = FButtonClickRedirect, write = FButtonClickRedirect };
__property TControlAgentOnClick OnClickSuppliment={read=FClickSupliment, write=FClickSupliment};
__property TButtonClickEvent OnButtonClick = {read = FOnButtonClick, write = FOnButtonClick };
};
//---------------------------------------------------------------------------
class TControlGroup
{
public:
UnicodeString GroupName;
std::vector<TControls*> GroupControls;
__fastcall TControlGroup();
};
//---------------------------------------------------------------------------
class TControls
{
public:
TControl* ctrl;
bool WantButtonOnClick;
bool WantControlOnChange;
bool FireStateChange;
bool WantOnClickSupliment;
bool state;
__fastcall TControls();
};
#endif
.cpp
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "TControlAgent.h"
#pragma package(smart_init)
//---------------------------------------------------------------------------
// ValidCtrCheck is used to assure that the components created do not have
// any pure virtual functions.
//
//---------------------------------------------------------------------------
// component to act as agent for other components derived from TControl
//
// Components have properties and events, is it possible to get all TControls into a vector
// then be able to get a property of a component then fire an event or carry out an action
// on the component!!!!
//---------------------------------------------------------------------------
struct IsCtrlGroup {
String _name;
IsCtrlGroup(String name) : _name(name)
{
}
bool operator()(const TControlGroup * item) const
{
return (item->GroupName == _name);
}
};
//---------------------------------------------------------------------------
struct IsClassName {
String _name;
IsClassName(String name) : _name(name)
{
}
bool operator()(const TControl * item) const
{
return (item->ClassName() == _name);
}
};
//---------------------------------------------------------------------------
struct IsCtrl {
TControl* _ctrl;
IsCtrl(TControl* ctrl) : _ctrl(ctrl) {
}
bool operator()(const TControls * item) const {
return (item->ctrl->Name == _ctrl->Name);
}
};
//---------------------------------------------------------------------------
static inline void ValidCtrCheck(TControlAgent *)
{
new TControlAgent(NULL);
}
//---------------------------------------------------------------------------
__fastcall TControlAgent::TControlAgent(TComponent* Owner)
: TComponent(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TControlAgent::FindTControl(TForm *f, UnicodeString className)
{
FControls.clear();
TControls* ctrl;
for(int i = 0; i < f->ControlCount; i++)
{
if(f->Controls[i]->ClassName() == className) //control classes that to set as a group
{
TControls* ctrl = new TControls();
ctrl->ctrl = f->Controls[i];
ctrl->FireStateChange = false;
ctrl->WantOnClickSupliment = false;
FControls.push_back(ctrl);
}
}
//note: could have a function that appends other class names
}
//---------------------------------------------------------------------------
void __fastcall TControlAgent::FindTControl(TPanel *p, UnicodeString GroupName, bool ClearIfControlsExists)
{
/*
group vector[]
--> controlsindex vector[index]
*/
TControlGroup* g;
TControls* ctrl;
int i = -1;
int group_index = -1, controls_index = -1;
// check if group name exists in group vector
group_index = GetGroup(GroupName);
//clear controls vector if exists, controls will not exist if group does not exist...
if(ClearIfControlsExists && group_index > 0)
FControlGroups[group_index]->GroupControls.clear();
// if group does not exist, push new group onto vector
if(group_index == -1)
{
g = new TControlGroup();
g->GroupName = GroupName;
FControlGroups.push_back(g);
group_index = GetGroup(GroupName);
}
//group must bnow exist
for(i = 0; i < p->ControlCount; i++)
{
TControls* ctrl = new TControls();
ctrl->ctrl = p->Controls[i];
FControlGroups[group_index]->GroupControls.push_back(ctrl);
controls_index = FControlGroups[group_index]->GroupControls.size() -1;
FControlGroups[group_index]->GroupControls[controls_index]->ctrl = p->Controls[i];
}
}
//---------------------------------------------------------------------------
int __fastcall TControlAgent::AddTControl(TControl* c, String Group)
{
int index;
TControlGroup* g;
int group_index = GetGroup(Group);
if(group_index == -1)
{
g = new TControlGroup();
g->GroupName = Group;
FControlGroups.push_back(g);
group_index = GetGroup(Group);
}
TControls* ctrl = new TControls();
ctrl->ctrl = c;
FControlGroups[group_index]->GroupControls.push_back(ctrl);
index = FControlGroups[group_index]->GroupControls.size()-1;
return(index);
}
//---------------------------------------------------------------------------
void __fastcall TControlAgent::SetControlClickEvent(String ClassName, String GroupName, String ExcludeGroup, int tControlType)
{
int group_index = GetGroup(GroupName);
for(int i = 0; i < FControlGroups[group_index]->GroupControls.size(); i++)
{
if(FControlGroups[group_index]->GroupControls[i]->ctrl->ClassName() == ClassName)
{
switch(tControlType)
{
case tbutton:
dynamic_cast<TButton*>(FControlGroups[group_index]->GroupControls[i]->ctrl)->OnClick = FOnButtonClick;
break;
case tedit:
break;
case tcombo:
break;
case tcheckbox:
break;
}
}
}
}
//---------------------------------------------------------------------------
std::vector<TControlGroup*> __fastcall TControlAgent::Groups()
{
return(FControlGroups);
}
//---------------------------------------------------------------------------
std::vector<TControls*> __fastcall TControlAgent::Controls(int GroupIndex)
{
return(FControlGroups[GroupIndex]->GroupControls);
}
//---------------------------------------------------------------------------
int __fastcall TControlAgent::GetGroup(String name)
{
int group_index =-1;
std::vector<TControlGroup*>::iterator found = std::find_if(FControlGroups.begin(), FControlGroups.end(), IsCtrlGroup(name));
if(found != FControlGroups.end())
group_index = std::distance(FControlGroups.begin(), found);
return(group_index);
}
//---------------------------------------------------------------------------
void __fastcall TControlAgent::SetButtonPropValue(TButton* b, String Property, String Value, bool v)
{
PPropInfo propinfo;
propinfo = GetPropInfo(b, Property);
if (!propinfo)
return;
if(Value.IsEmpty())
SetPropValue(b, propinfo, v);
else
SetPropValue(b, propinfo, Value);
}
//---------------------------------------------------------------------------
void __fastcall TControlAgent::SetButtonPropValue(String Group,
String ExcludeGroup,
int TControlType,
String Property,
String GroupValue,
bool GroupV,
String excludeGroupValue,
bool excludeGroupV)
{
// Group can hold all TControls on a form
// ExcludeGroup contains TControls that will be excluded from an action on the Group controls
// Group is an existing group of TControls found on a container
// ExcludGroup is a group that can be found on a container or added to a Group
// then parsed to this method in ExcludeGroup param
int i;
PPropInfo propinfo;
TControl *c;
int group_index = GetGroup(Group);
int exclude_Group_index = GetGroup(ExcludeGroup);
TControl* ctrl;
for(i = 0; i < FControlGroups[group_index]->GroupControls.size(); i++)
{
c = FControlGroups[group_index]->GroupControls[i]->ctrl;
//check if TControl is to be excluded
std::vector<TControls*>::iterator found = std::find_if(FControlGroups[exclude_Group_index]->GroupControls.begin(),
FControlGroups[exclude_Group_index]->GroupControls.end(),
IsCtrl(c));
// if found, control is in the exclude list so continue, do not apply
// property value change
if(found != FControlGroups[exclude_Group_index]->GroupControls.end())
{
c = (*found)->ctrl;
//set property value for exclude group controls
propinfo = GetPropInfo(c, Property);
if(propinfo)
{
if(excludeGroupValue.IsEmpty())
SetPropValue(c, propinfo, excludeGroupV);
else
SetPropValue(c, propinfo, excludeGroupValue);
}
continue;
}
//if it gets here, c is not in exclude list
propinfo = GetPropInfo(c, Property);
if (!propinfo)
return;
if(GroupValue.IsEmpty())
SetPropValue(c, propinfo, GroupV);
else
SetPropValue(c, propinfo, GroupValue);
}
}
//---------------------------------------------------------------------------
namespace Tcontrolagent
{
void __fastcall PACKAGE Register()
{
TComponentClass classes[1] = {__classid(TControlAgent)};
RegisterComponents(L"SQLite", classes, 0);
}
}
//---------------------------------------------------------------------------
__fastcall TControls::TControls(){}
//---------------------------------------------------------------------------
__fastcall TControlGroup::TControlGroup(){}
Form Code
.cpp
Form has a TPanel with 6 TButtons placed on it
#run time TButton3 is disabled
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "frmTControlTest.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma link "TControlAgent"
#pragma resource "*.dfm"
TForm3 *Form3;
//---------------------------------------------------------------------------
__fastcall TForm3::TForm3(TComponent* Owner)
: TForm(Owner)
{
int i;
std::vector<TControls*> group_controls;
//get ALL controls on a container
ControlAgent1->FindTControl(p, "Group1", true);
//create the exclude (for want of a better name) groups
/*
add
edit
save
delete
cancel
exit
*/
ControlAgent1->AddTControl(bnSave, "Group2");
ControlAgent1->AddTControl(bnCancel, "Group2");
ControlAgent1->AddTControl(bnAdd, "Group3");
ControlAgent1->AddTControl(bnEdit, "Group3");
ControlAgent1->AddTControl(bnDelete, "Group3");
ControlAgent1->AddTControl(bnExit, "Group3");
i = ControlAgent1->GetGroup("Group1");
group_controls = ControlAgent1->Controls(i);
ControlAgent1->SetControlClickEvent("TButton", "Group1", "", tbutton);
}
//---------------------------------------------------------------------------
void __fastcall TForm3::ControlAgent1ButtonClick(TObject *Sender)
{
TButton* b;
if((b = dynamic_cast<TButton*>(Sender)) == bnAdd )
ControlAgent1->SetButtonPropValue("Group1", "Group2", tbutton, "Enabled", "", false, "", true);
if((b = dynamic_cast<TButton*>(Sender)) == bnCancel )
ControlAgent1->SetButtonPropValue("Group1", "Group3", tbutton, "Enabled", "", false, "", true);
if((b = dynamic_cast<TButton*>(Sender)) == bnSave )
{
ControlAgent1->SetButtonPropValue("Group1", "Group3", tbutton, "Enabled", "", false, "", true);
//Do Stuff
}
}
//---------------------------------------------------------------------------

Related

Arduino - passing values by reference from lamda to singleton

Hello i am bigginer in programing and i have specific problem.
I have been learning a new ways to write a code in small Arduino project.
that project have multiple objects like distance measuring Senzor, led diods , temperature senzor, etc. And all this objects have its own menu where you can, for example, start a calibration or just get values.
What i need is singleton class that has a function enter_esc() that need a int (*funct)() parameter basically function pointer.
That enter_esc(int (*funct)()) function just looping function until you press escape pin which is defined.
function Calibration() have inside some private: object data types like value or cali_value.
so i tried to insert function Calibration() right into enter_esc(Calibration) but it won't compile becouse i didnt pass that vlaues by reference or copy.
but what i found is lambda.
i made a lamda similar to a Calibration() function and i passed values by reference &{//domething;}
but i had to use enter_esc(std::function<int()>& funct) whitch is only int C++ standard library and not in Arduino C/C++ so my qestion is:
[is there some way how to pass values by reference by using lambda to a singleton class in Arduino ?]
(i konw it can be done differently but like i said i want to learn some new ways to program, also if you have some different way to make it i will by very happy to see it)
10Q for your time :)
//Class.h
#pragma once
class events {
private:
static events e_instance;
int p_menu, p_enter, p_esc, p_up, p_down;
int menuValue;
events();
public:
events(const events&) = delete;
static events& Get();
int ArrowUpDown(int maxVal);
int ArrowUpDown(int p_up, int p_down, int maxVal);
int enter_esc(const std::function<int()>& funct);
};
events events::e_instance;
class deviceBase : public Printables
{
public:
const char* a_pin;
int d_pin;
String type;
String deviceName;
bool inUse;
int actualCount;
public:
String getType() override;
int getActualCount() override;
String getName() override;
String getInUse() override;
};
class senzor : public deviceBase
{
private:
int Value;
int triggValue;
public:
int p_triggValue = 10;
static int allSenzors;
friend events;
senzor();
~senzor();
public:
int getValue();
int Calibration();
void changeTriggVal(int x);
void Reset();
void nullCalibration();
void Menu(int x);
void setName(String deviceName);
void setInUse(bool x);
int getPin();
};
int senzor::allSenzors = 0;
if you have some good advice to my code writing i will be also very glad
//Class.cpp
#include <iostream>
#include <string>
#include <functional>
#define LOG(x) std::cout << x << std::endl;
#define PINMENU 12
#define PINENTER 8
#define PINESC 9
#define PINUP 11
#define PINDOWN 13
using String = std::string;
struct Printables
{
virtual String getType() = 0;
virtual int getActualCount() = 0; ;
virtual String getName() = 0;
virtual String getInUse() = 0;
};
#include "Class.h"
events& events::Get() {
return e_instance;
}
int events::ArrowUpDown(int maxVal) {
if (maxVal) {
menuValue = menuValue < maxVal ? menuValue++ : menuValue;
}
if (maxVal) {
menuValue = menuValue > 0 ? menuValue-- : menuValue;
}
return menuValue;
}
int events::enter_esc(const std::function<int()>&funct) {
if (1) {
while (!p_esc) {
auto f = funct;
}
}
return 1;
}
int events::ArrowUpDown(int p_up, int p_down, int maxVal) { return 666; }
events::events() {};
String deviceBase::getType() { return type; }
int deviceBase::getActualCount() { return actualCount; }
String deviceBase::getName() { return deviceName; }
String deviceBase::getInUse() {
String Status;
Status = inUse == 1 ? "Active" : "Deactive";
return Status;
}
senzor::senzor() : Value(0), triggValue(1) {
a_pin = "xx";
type = "[SENZOR]";
deviceName = "[UNKNOWN]";
inUse = 0;
allSenzors++;
actualCount = allSenzors;
a_pin = 0;
}
senzor::~senzor() {
allSenzors = 0;
}
int senzor::getValue() {
Value = 4;
return Value;
}
int senzor::Calibration() {
triggValue = triggValue < getValue() ? getValue() : triggValue;
p_triggValue = triggValue;
return p_triggValue;
}
void senzor::changeTriggVal(int x) {
p_triggValue = x;
}
void senzor::Reset() {
p_triggValue = triggValue;
}
void senzor::nullCalibration() {
triggValue = 1;
}
void senzor::setName(String deviceName) {
this->deviceName = deviceName;
}
void senzor::setInUse(bool x) {
inUse = x;
}
int senzor::getPin() {
return 4;
}
int printsss() {
return 1;
}
////////////////////////////////this what i was writing about//////////////////////////////
void senzor::Menu(int x) {
events::Get().enter_esc([&]() { triggValue = triggValue < getValue() ? getValue() : triggValue;
p_triggValue = triggValue;
return p_triggValue; });
}
but if i use lambda in arduino with enter_esc(int (*funct)()) i get this kind of error
no matching function for call to 'events::enter_esc(senzor::Menu(int)::<lambda()>)'

Connection between two Indy UDP Servers

I'm using RAD Studio 10.2 with two instances of TIdUDPServer from Indy 10.
I run my program on Windows 10 and check the counters of sent and received packages, but there are no packages received. At the same time, I see through Wireshark that they come to the PC, but the second TIdUDPServer does not receive the packages. Why?
Here is my code:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
typedef struct {
char Data[10000];
} struct_Buffer;
int i = 0;
int n = 0;
int k = 0;
int TxSize = 1400;
char TxData;
struct_Buffer TxBuffer;
AnsiString ServerIP1 = "192.168.10.1";
AnsiString ServerIP2 = "192.168.10.2";
TBytes Buffer;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
class TMyQueueProc1 : public TCppInterfacedObject<TThreadProcedure>
{
private:
int m_counter;
TIdBytes m_bytes;
public:
TMyQueueProc1(int ACounter, const TIdBytes &AData) : m_counter(ACounter), m_bytes(AData) {}
INTFOBJECT_IMPL_IUNKNOWN(TInterfacedObject);
void __fastcall Invoke()
{
Form1->Label1->Caption = "Rx " + IntToStr(m_counter);
}
};
void __fastcall TForm1::FormCreate(TObject *Sender)
{
try {
TIdSocketHandle *SocketHandle_Server = Form1->IdUDPServer1->Bindings->Add();
SocketHandle_Server->IP = ServerIP1;
SocketHandle_Server->Port = 4004;
Form1->IdUDPServer1->Active = true;
}
catch(Exception *ex) {
ShowMessage("IdUDPServer1 start error!");
}
try {
TIdSocketHandle *SocketHandle_Echo = Form1->IdUDPServer2->Bindings->Add();
SocketHandle_Echo->IP = ServerIP2;
SocketHandle_Echo->Port = 4004;
Form1->IdUDPServer2->Active = true;
}
catch(Exception *ex) {
ShowMessage("IdUDPServer2 start error!");
}
Timer1->Interval = 100;
Timer1->Enabled = true;
Label3->Caption = "IdUPDServer1: " + ServerIP1;
Label4->Caption = "IdUDPServer2: " + ServerIP2;
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Timer1Timer(TObject *Sender)
{
TxData++;
if (TxData == 255) TxData = 0;
for (k = 0; k < TxSize; k++) TxBuffer.Data[k] = TxData;
Buffer = RawToBytes(&TxBuffer.Data[0], TxSize);
Form1->IdUDPServer1->SendBuffer(ServerIP2, 4004, Buffer);
n++;
Label2->Caption = "Tx " + IntToStr(n);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::IdUDPServer2UDPRead(TIdUDPListenerThread *AThread, const TIdBytes AData,
TIdSocketHandle *ABinding)
{
i++;
TThread::Queue(NULL, _di_TThreadProcedure(new TMyQueueProc1(i, AData)));
}
//---------------------------------------------------------------------------

Getting error c2280 at my Update function (at if (Game::vector.at(i).alivez()) specifically)

I'm having an error doing the Update when checking if(Game::vector.at(i).alivez()), the error is C2280.
The error says: "Enemy &Enemy::operator =(const Enemy &)': attempting to reference a deleted function. Project: Avoidance Game File:xutility
Game.cpp:
void Game::Init()
{
int i = 0;
while(i< Game::Enemies)
{
srand(time(NULL));
Game::vector.push_back(Enemy(0, (rand()% (int)Console::WindowWidth), (rand() % (int)Console::WindowHeight), rand()%1500/1000.0f));
i++;
}
GameOver = false;
Paused = false;
}
void Game::GameMenu()
{
cout << "1. Start Game\n2. Instructions\n3. Close Game\nChoose an option:";
}
void Game::Instructions()
{
Console::Clear();
cout << "Left arrow = left (duh)\nRight arrow = right (surprise)\nSpace Bar = Shoot\nEsc = Close Game\nP Key = Pause\n ";
system("pause");
}
void Game::fire(Player a)
{
a.mX;
}
void Game::Run()
{
while (!GameOver)
{
if (GetAsyncKeyState(VK_ESCAPE))
{
GameOver = true;
}
else if (GetAsyncKeyState((int)'P'))
{
Paused = !Paused;
}
}
}
void Game::Update()
{
if (!Paused)
{
mPlayer.Update();
for (int i = 0; i < Game::Enemies; i++)
{
Game::vector.at(i).Update();
if (Game::vector.at(i).alivez())
{
Game::vector.erase(Game::vector.begin() + i);
i--;
Game::Enemies--;
}
}
}
}
Game.h:
#pragma once
#include "stdafx.h"
#include "targetver.h"
#include <vector>
class Enemy;
class Game
{
int Enemies = 30;
bool Paused;
bool GameOver;
int Score;
Player mPlayer = Player();
std::vector<Enemy> vector;
public:
void Init();
void GameMenu();
void Instructions();
void fire(Player a);
void Run();
void Update();
};
Enemy.h:
class Enemy
{
enum Enemy_type {NormalEnemy};
Game game;
float mX;
float mY;
float speed;
Enemy_type type;
public:
bool alive;
Enemy(int type, int x, int y, float _speed)
{
switch (type)
{
case 0:
type = Enemy_type::NormalEnemy;
break;
}
mX = (float)x;
mY = (float)y;
speed = _speed;
alive = true;
}
float GetX() { return mX; }
float GetY() { return mY; }
bool alivez() { return alive; }
void Kill() { alive = false; }
void Update();
void Draw();
};

How to notify ListView that DataModel has changed

I created a ListView and I want to use it with a custom DataModel. However, I have a problem: at the moment the view gets created, I don't have the data loaded into the model. The model data is set after the view is created and when I set the data onto the model, the view doesn't update and doesn't read again the model data. This is my ListView:
ListViewCountainer.qml
Container {
// countryModelData is set after ListViewCountainer gets created
// when countryModelData gets set, the model is populated with data
property variant countryModelData
leftPadding: 20.0
rightPadding: 20.0
topPadding: 20.0
bottomPadding: 20.0
CountryDetailsListView {
id: countryDetailsListView
dataModel: CountryDataModel {
countryData: countryModelData
}
}
}
And here is my model:
countrydatamodel.h
#ifndef COUNTRYDATAMODEL_H_
#define COUNTRYDATAMODEL_H_
#include <QtCore/QAbstractListModel>
#include <QtCore/QList>
#include <QObject>
#include <QtCore/QVariant>
#include <bb/cascades/DataModel>
#include <bb/data/JsonDataAccess>
class CountryDataModel : public bb::cascades::DataModel
{
Q_OBJECT
Q_PROPERTY(QVariant countryData READ getCountryData WRITE setCountryData)
public:
CountryDataModel(QObject* parent = 0);
virtual ~CountryDataModel();
Q_INVOKABLE int childCount(const QVariantList& indexPath);
Q_INVOKABLE QVariant data(const QVariantList& indexPath);
Q_INVOKABLE bool hasChildren(const QVariantList& indexPath);
Q_INVOKABLE QString itemType(const QVariantList& indexPath);
Q_INVOKABLE void removeItem(const QVariantList& indexPath);
Q_INVOKABLE QVariant getCountryData();
Q_INVOKABLE void setCountryData(QVariant data);
private:
QVariantList m_elements;
};
#endif /* COUNTRYDATAMODEL_H_ */
countrydatamodel.cpp
#include <src/countrydatamodel.h>
#include <QtCore/QtAlgorithms>
#include <QtCore/QDebug>
#include <bb/cascades/DataModel>
#include <bb/data/JsonDataAccess>
CountryDataModel::CountryDataModel(QObject* parent) : bb::cascades::DataModel(parent)
{
}
CountryDataModel::~CountryDataModel()
{
}
bool CountryDataModel::hasChildren(const QVariantList &indexPath)
{
qDebug() << "==== CountryDataModel::hasChildren" << indexPath;
if ((indexPath.size() == 0))
{
return true;
}
else
{
return false;
}
}
int CountryDataModel::childCount(const QVariantList &indexPath)
{
qDebug() << "==== CountryDataModel::childCount" << indexPath;
if (indexPath.size() == 0)
{
qDebug() << "CountryDataModel::childCount" << m_elements.size();
return m_elements.size();
}
qDebug() << "==== CountryDataModel::childCount" << 0;
return 0;
}
QVariant CountryDataModel::data(const QVariantList &indexPath)
{
qDebug() << "==== CountryDataModel::data" << indexPath;
if (indexPath.size() == 1) {
return m_elements.at(indexPath.at(0).toInt());
}
QVariant v;
return v;
}
QString CountryDataModel::itemType(const QVariantList &indexPath)
{
Q_UNUSED(indexPath);
return "";
}
void CountryDataModel::removeItem(const QVariantList& indexPath)
{
if(indexPath.size() == 1) {
m_elements.removeAt(indexPath.at(0).toInt());
}
emit itemRemoved(indexPath);
}
QVariant CountryDataModel::getCountryData()
{
return QVariant(m_elements);
}
void CountryDataModel::setCountryData(QVariant data)
{
m_elements = data.toList();
qDebug() << "================== CountryDataModel: " << m_elements;
}
I put some debug messages in the childCount function for example and it gets called only once, which means that the ListView asks the model for the data just once, when the model is created.
Is it possible to force ListView to read again the data from the model after the model gets populated with data? Or how could I make this approach work and load the data in the view?
Thanks!
In order for the model to be updated, the setCountryData member function needs to be updated like so:
void CountryDataModel::setCountryData(QVariant data)
{
m_elements = data.toList();
emit itemsChanged(bb::cascades::DataModelChangeType::AddRemove, QSharedPointer< bb::cascades::DataModel::IndexMapper >(0));
}
FML...
You need to declare a signal for the property you want to update in backend.
Q_PROPERTY(QVariant countryData READ getCountryData WRITE setCountryData NOTIFY contryDataChanged)
add its declaration as well.
Then you say -
emit contryDataChanged();
wherever you feel like list should re-read contents. (normally setter methods).

How do I setup Using Systems::IO::Ports in DLL so that it can be called from a loadlibrary function

Using vc2012 express c++
I am a little confused on how a runtime library works, but I had needed to create one for a driver from some hardware I have so that it can be used in a SDK.
My source code is as follows
#include "PhantomAdapter.h"
#include <stdexcept>
int ready()
{
//return Comms::SerialPort::check();
return 1;
}
int open()
{
int flag=0;
//flag=Comms::SerialPort::openPort();
return flag;
}
int close()
{
Comms::SerialPort::closePort();
return 1;
}
int angle(double& angle)
{
angle = Comms::SerialPort::read();
return 0;
}
int torque(double torque)
{
Comms::SerialPort::send((Byte)torque);
return 1;
}
namespace Comms
{
//static p1 = gcnew System::IO::Ports::SerialPort();
int SerialPort::openPort()
{
bool check=0;
p1 = gcnew System::IO::Ports::SerialPort();
p1->BaudRate = 57600;
p1->PortName = "COM3";
if(p1->IsOpen)
return 0;
else {
p1->Open();
return 1;
}
}
int SerialPort::check()
{
array<String^>^ serialPorts = nullptr;
bool flag = true;
serialPorts = p1->GetPortNames();
for each(String^ port in serialPorts)
{
if(port=="COM3")
flag= true;
}
return flag;
}
void SerialPort::closePort()
{
p1->Close();
}
void SerialPort::send(Byte data)
{
array<unsigned char>^ buffer = gcnew array<Byte>(1);
buffer[0] = (char)data;
p1->Write(buffer,0,1);
}
double SerialPort::read()
{
double data;
data = p1->ReadByte();
return data;
}
}
header
#define PHANTOMADAPTER_API __declspec(dllexport)
#else
#define PHANTOMADAPTER_API __declspec(dllexport)
#endif
#using <mscorlib.dll>
#using <system.dll>
using namespace System;
using namespace System::IO::Ports;
using namespace System::Threading;
extern "C" {
PHANTOMADAPTER_API int ready();
PHANTOMADAPTER_API int open();
PHANTOMADAPTER_API int close();
PHANTOMADAPTER_API int angle(double& angle);
PHANTOMADAPTER_API int torque(double torque);
}
namespace Comms
{
public ref class SerialPort
{
private:
static System::IO::Ports::SerialPort^ p1;
public:
static int openPort();
static void closePort();
static double read();
static void send(Byte data);
static int check();
};
}
I am getting the following error when I call the angle DLL function or any function that requires the Comms namespace.
System.NullReferenceException: Object reference not set to an instance of an object.
at System.IO.Ports.SerialPort.get_IsOpen()
at System.IO.Ports.SerialPort.ReadByte()
at angle(Double* angle)
can someone please point me in the right direction, I feel as if the serialPort class can't be open from runtime library unless I import it somehow