delphi how to create and assign a stack - oop

I am really struggling with this and can't find anything online about it - or I might not be understand what is written online. I am trying to create a stack and use ibut I can't even create it.
I am creating it in a procedure and I want the stack to contain integers. I have tried to following and I just get the red line underneath (both are in the var section of the procedure):
genericstack:TObjectStack;
as well as
genericstack:TStack;
and neither have worked in setting the stack. I just get an red line underneath.

you may check example code in official site:
Generics Collections TObjectStack
useful one:
How to store a String in a TObjectStack
and also
FlowPanel example
and a snippet may fit as your answer:
{
This example demonstrates the usage of the generic TObjectStack class.
}
type
{ Declare a new object type }
TNewObject = class
private
FName: String;
public
constructor Create(const AName: String);
destructor Destroy(); override;
end;
{ TNewObject }
constructor TNewObject.Create(const AName: String);
begin
FName := AName;
end;
destructor TNewObject.Destroy;
begin
{ Show a message whenever an object is destroyed }
MessageDlg('Object "' + FName + '" was destroyed!', mtInformation, [mbOK], 0);
inherited;
end;
procedure TForm3.Button1Click(Sender: TObject);
var
Stack: TObjectStack<TNewObject>;
Button: TButton;
begin
{ Create a new stack }
Stack := TObjectStack<TNewObject>.Create();
{ Set the OwnsObjects to true - the stack will free them automatically }
Stack.OwnsObjects := true;
{ Push some items up the stack }
Stack.Push(TNewObject.Create('One'));
Stack.Push(TNewObject.Create('Two'));
Stack.Push(TNewObject.Create('Three'));
{
Pop an instance of TNewObject class. Destructor
show be called because we have set the OwnsObjects
to true!
}
Stack.Pop();
{ Destroy the stack completely - more messageboxes will be shown }
Stack.Free;
end;

Related

How to get response string from Indy udp server?

I'm trying to create a simple text exchange between Indy UDP client and server in C++ Builder 10.3.1. This is the code I use:
void __fastcall TForm1::Button1Click(TObject *Sender)
{
IdUDPClient1->Send("Hello");
UnicodeString resp = IdUDPClient1->ReceiveString();
ShowMessage(resp);
}
void __fastcall TForm1::IdUDPServer1UDPRead(TIdUDPListenerThread *AThread,
const TIdBytes AData, TIdSocketHandle *ABinding)
{
UnicodeString req = BytesToString(AData);
if(req == "Hello"){
// why this don't work?
ABinding->Send("Hello 2");
// the following works if ThreadedEvent = true
// AThread->Server->Send(ABinding->PeerIP, ABinding->PeerPort, "Hello 2");
}
}
I am unable to get the response from the server on the client side. What am I doing wrong?
On the server side, the provided TIdSocketHandle in the OnUDPRead event is not "connected" (from the OS's perspective) to the peer that sent the received data, so by default callingABinding->Send() requires specifying the target IP/Port to send to. That is why ABinding->Send(ABinding->PeerIP, ABinding->PeerPort, "Hello 2"); works and ABinding->Send("Hello 2"); does not.
Calling ABinding->Send() is not dependant on the server's ThreadedEvent property in any way. That property merely controls whether the server's OnUDPRead event is triggered in the context in the main UI thread or not. It has no effect on how the server allocates and manages its sockets.
However, if the server's ThreadedEvent property is false, and the client and server are running in the same app process, the server won't be able to fire its OnUDPRead event while your Button1Click() is running. You will need to set ThreadedEvent to true in that situation so the OnUDPRead event is triggered in the context of a worker thread instead, not waiting on the main UI thread.
Otherwise, move the client to its own worker thread instead.
Hope you can accept an answer in Delphi. I can not translate it just now.
With a pair of projects, VclIdUDPServer and VclIdUDPClient, as follows, I get the two to communicate. Tested on same machine as well as on two machines. Note, that this is minimal code to get the two to chat.
VclIdUDPServer
procedure TForm1.FormCreate(Sender: TObject);
var
Binding: TIdSocketHandle;
begin
Binding := IdUDPServer1.Bindings.Add;
Binding.IP := '192.168.2.109';
Binding.Port:= 49000;
IdUDPServer1.OnUDPRead:= IdUDPServer1UDPRead;
IdUDPServer1.Active:=True;
end;
procedure TForm1.IdUDPServer1UDPRead(AThread: TIdUDPListenerThread;
const AData: TIdBytes; ABinding: TIdSocketHandle);
var
req: string;
begin
req := BytesToString(AData);
Memo2.Lines.Add(req);
if req = 'Hello' then
ABinding.SendTo(ABinding.PeerIP, ABinding.PeerPort, 'Yes sir!', ABinding.IPVersion);
end;
end;
VclIdUDPClient
procedure TForm2.FormCreate(Sender: TObject);
begin
IdUDPClient1.Host:='192.168.x.xxx'; // set to your ip
IdUDPClient1.Port:=49000;
IdUDPClient1.Active:=True;
end;
procedure TForm2.Button1Click(Sender: TObject);
var
rep: string;
begin
IdUdpClient1.Send('Hello');
rep := IdUdpClient1.ReceiveString();
Memo1.Lines.Add(rep);
end;

Delphi FMX: How to add an Event into an object (just like TEdit.OnChange)

Assume I have created a new FMX project with nothing more than a TButton and a TProgressBar on it.
Now I added a 'Countertest.pas' file using [Shift] + [F11]. (see code below)
Now I have implemented a procedure into 'Unit1.pas' (the main app) to be triggered by a procedure inside the 'Countertest.pas' file to change the Value of the TProgressBar.
Inside 'Unit1.pas' I wrote this to be called from inside the 'Countertest.pas' file:
procedure TForm1.SomethingChanged(newPercentage:Integer);
begin
ProgressBar1.Value:=newPercentage;
showmessage('Congratulations, you have just reached '+IntToStr(newPercentage)+' Percent ;)');
end;
To simplify my problem, this is my stripped down 'Countertest.pas' file:
unit Countertest;
interface
uses FMX.Memo; // Will be used later
type
TCountertest = Class
private
zahl: Integer;
published
constructor Create();
destructor Destroy();
procedure Counter();
property Percentage: Integer read zahl;
end;
implementation
constructor TCountertest.Create();
begin
end;
destructor TCountertest.Destroy();
begin
end;
procedure TCountertest.Counter();
begin
for i := 0 to 1337 do
Percentage:=0;
begin
zahl:=i;
if Percentage<>round(i / 100) then
begin
// Here I want to call a Procedure inside 'Unit1.pas' to change a Value of the TProgressBar (and some other components like TLabel.Text)
end;
Percentage:=round(i / 100);
end;
end;
end.
As far as I know there is the possibility to use something like procedure(Sender: TObject) of object; and it seems to be the thing a want to use, however I don't have any idea of how to use this.
My Intention is to write something similar to an OnChange Event used in a TEdit Control.
Of Course I could add 'Unit1.pas' into the Uses section of 'Countertest.pas' and then call the procedure directly, but as have to handle multiple Instances of TCountertest, I want to have it more like this:
procedure InstanceOfTCountertest.SomethingChanged(newPercentage:Integer);
begin
ProgressBar1.Value:=newPercentage;
showmessage('Congratulations, you have just reached a new Percent ;)');
end;
In the final app there are multiple Instances of TCountertest, so I have multiple Progressbars as well (and other GUI components such as TLabels).
Maybe there are other ways to do this, so feel free to suggest anything, that could fit the purpose to show the Progress of those Instances.
Usually, components (like TButton for example) expose events as properties (eg.: TButton.OnCLick) and it's up to the parent or sibling components (the parent TForm in this case) to set the event handler. Let's say we want to change the Button1.OnClick event handler:
// Setting the handler:
procedure TForm1.Create(AOwner: TComponent);
begin
Button1.OnClick := Self.MyCustomClickHandler;
end;
// And the handler implementation:
procedure TForm1.MyCustomClickHandler(Sender: TObject);
begin
// ...
end;
So, I imagine you want to have an event for your TCountertest like TCountertest.OnCount so that other components / forms can set a handler and act in response to a change in your counter's progress. Let's describe how to do it the Delphi way (untested code):
First, your component should implement and expose the event:
unit Countertest;
interface
type
// Custom type for your event handler
TCountEvent = procedure(Sender: TObject; Percentage: Integer) of object;
TCountertest = Class
private
FPercentage: Integer;
// Variable that holds the event handler set by the user
FOnCount: TCountEvent;
// Internal event trigger
procedure DoCount();
public
constructor Create();
destructor Destroy();
procedure Counter();
published
property Percentage: Integer read FPercentage;
// This is the property for your event handler assignment
property OnCount: TCountEvent read FOnCount write FOnCount;
end;
implementation
constructor TCountertest.Create();
begin
// Initialize event handler to nil
FOnCount := nil;
end;
destructor TCountertest.Destroy();
begin
end;
// Event trigger
procedure TCounterTest.DoCount();
begin
// Check that the user assigned an event handler
if Assigned(FOnCount) then
FOnCount(Self, FPercentage);
end;
procedure TCountertest.Counter();
begin
// Your code (update FPercentage in your code)...
// When you need to trigger the event:
DoCount();
// Rest of your code...
end;
end.
Now we are ready to create and set event handlers to your instances of TCountertest:
unit Unit1;
// ...
type
TForm1 = class
private
// ...
// Declare the handler
procedure CounterCount(Sender: TObject; Percentage: Integer);
public
// ...
end;
implementation
// ...
// Implement the handler
procedure TForm1.CounterCount(Sender: TObject; Percentage: Integer);
begin
ProgressBar1.Value := Percentage;
end;
// Set the event handlers for your counters
procedure TForm1.Create(AOwner: TComponent);
var
Counter1, Counter2: TCountertest;
begin
// Create the counters
Counter1 := TCountertest.Create();
Counter2 := TCountertest.Create();
// Set the event handlers
Counter1.OnCount := Self.CounterCount;
Counter2.OnCount := Self.CounterCount;
end;
end.
I hope it helps. Feel free to ask if not.

Variable init in Go

I see following code (I simplified it a bit).
func getEndpoints(db *sqlx.DB) s.Endpoints {
var endpoints s.Endpoints
{
repository := acl.NewRepository(db)
service := stat.NewService(repository)
endpoints = s.Endpoints{
GetEndpoint: s.MakeEndpoint(service),
}
}
return endpoints
}
If I understand this code correctly, code inside var endpoints s.Endpoints{...} is executed line by line and endpoints = s.Endpoints ... line initialises var endpoints variable declared above.
I suppose that it's correct to rewrite it like this (correct me if I'm wrong):
func getEndpoints(db *sqlx.DB) s.Endpoints {
repository := acl.NewRepository(db)
service := stat.NewService(repository)
endpoints := s.Endpoints{
GetEndpoint: s.MakeEndpoint(service),
}
return endpoints
}
So can somebody explain me why initialisation is written inside var endpoints s.Endpoints{...}. Is there any idea to do it like this? Am I missing something?
Adding a new block will create a new variable scope, and variables declared in that block will not be available outside of it:
var endpoints s.Endpoints
{
repository := acl.NewRepository(db)
service := stat.NewService(repository)
endpoints = s.Endpoints{
GetEndpoint: s.MakeEndpoint(service),
}
}
// service and repository variables are not defined here!
In your specific simplified example it makes little sense, but if you have other blocks with the same variables it makes more sense. For example:
var endpoints s.Endpoints
{
repository := acl.NewRepository(db)
service := stat.NewService(repository)
endpoints = s.Endpoints{
GetEndpoint: s.MakeEndpoint(service),
}
}
// Get another repository
{
repository := otherRepo.NewRepository(db)
repository.DoSomething()
}
Some people consider this "good hygiene". Personally, I don't think it's worth the decrease in readability.
They are equivalent.
The {...} block has nothing to do with the variable declaration with the var keyword. It just happens to be written one after the other.
The {...} is a simple block, nothing else. The var declaration does not require that block, and even if there is one, it is not related to the variable declaration. You can insert a block wherever you would insert a statement.
The rare case when an explicit block is used (when there isn't required one) is to group statements, and to control the scope of the variables and other identifiers declared inside them, because the scope of the variables end at the end of the innermost containing block (Spec: Declarations and Scope).

Intellisense JSDoc for Mixins and/or Factory Functions

My Problem
I'm currently using Visual Code Studio, the lastest version. I'm trying to get the intellisense to show up for the methods on the instance created by a factory function. The methods are going to be applied via object composition (so added directly as properties on the object).
so the function that acts as a constructore basically returns:
function makeWrappedObj() {
var obj = { /* random data */ }; // Then add methods to obj
Object.keys(methods).forEach(key => a[key] = methods[key]; );
return obj;
}
var methods = {
/**
* Yay documentation
* #returns {Object}
*/
method1: function() { return null; }
};
var instance = makeWrappedObj();
instance.method1( // What documentation to show up here
instance. // and here
Is the basic idea. Here's someone doing something similar. I'll address that in the third possible solution.
Solutions I've tried
1) #class on makeWrappedObj I think only works if you attach methods on to makeWrappedObj.prototype which is not what I'm doing so that doesn't work. Unless I'm misunderstanding something.
2) #namespace solution
/* #namespace ClassName */
/* #returns {ClassName}
function createWrappedObj() {
var obj = { /* random data */ }; // Then add methods to obj
Object.keys(methods).forEach(key => a[key] = methods[key]; );
return obj;
}
var methods = {
/**
* Currently the soultion I'm using
* #memberof ClassName
* #param {number} a
**/
method1: function (a) {}
};
var instance = makeWrapperObj();
instance.method1( // Only shows documentation here
So this sort of works. The two problems are that:
methods on instances only get documentation when you type out the full instance.method( and not in the instance. case--not really a big deal
if you have a method name that is the same as an in-built function, eg. toString, instance.toString( will block any documentation you have from showing and show the native toString default documentation instaed.
3) #typedef like the link above.
/** Can be placed anywhere
* #typedef {ClassName}
* #property {function} method1
* dunno how to document arguments with this method
* but it gets the intellisense menu to pop up for "instance." after dot
*/
/* #returns {ClassName} */
function createdWrappedObject() {
var obj = { /* random data */ }; // Then add methods to obj
Object.keys(methods).forEach(key => a[key] = methods[key]; );
return obj;
}
var methods = {
method1: function (a) {}
};
var instance = makeWrappedObj();
instance. // Yay
instance.method1( // Doesn't work
Has the benefit of showing up when one types instance. however has a few disadvantages
Do not know how to specify arguments passed to method1. Maybe it's not possible.
#typedef requires all documentations to be specified in its own comment block. So I have to be redundant between specific documentation on the methods and the typedef
loses the docummentation once you write out the entire method up until the open paren. Sort of workable...
Note: I am willing to just assign all the methods manually one by one instead of doing a foreach on all the keys of the methods mixin.
Also I do not know how to specify the parameters for a function passed as a. This should be possible since Array.map( specifies three arguments for its function call.
The goal is to get documentation when someone imports this as a library with require, or just includes it as a library in browser side script.

Non-declaration statement outside function body in Go

I'm building a Go library for an API that offers JSON or XML formatted data.
This API requires me to request a session_id every 15 minutes or so, and use that in calls. For example:
foo.com/api/[my-application-id]/getuserprofilejson/[username]/[session-id]
foo.com/api/[my-application-id]/getuserprofilexml/[username]/[session-id]
In my Go library, I'm trying to create a variable outside of the main() func and intend to ping it for a value for every API call. If that value is nil or empty, request a new session id and so on.
package apitest
import (
"fmt"
)
test := "This is a test."
func main() {
fmt.Println(test)
test = "Another value"
fmt.Println(test)
}
What is the idiomatic Go way to declare a globally-accessible variable, but not necesarilly a constant?
My test variable needs to:
Be accessible from anywhere within it's own package.
Be changeable
You need
var test = "This is a test"
:= only works in functions and the lower case 't' is so that it is only visible to the package (unexported).
A more thorough explanation
test1.go
package main
import "fmt"
// the variable takes the type of the initializer
var test = "testing"
// you could do:
// var test string = "testing"
// but that is not idiomatic GO
// Both types of instantiation shown above are supported in
// and outside of functions and function receivers
func main() {
// Inside a function you can declare the type and then assign the value
var newVal string
newVal = "Something Else"
// just infer the type
str := "Type can be inferred"
// To change the value of package level variables
fmt.Println(test)
changeTest(newVal)
fmt.Println(test)
changeTest(str)
fmt.Println(test)
}
test2.go
package main
func changeTest(newTest string) {
test = newTest
}
output
testing
Something Else
Type can be inferred
Alternatively, for more complex package initializations or to set up whatever state is required by the package GO provides an init function.
package main
import (
"fmt"
)
var test map[string]int
func init() {
test = make(map[string]int)
test["foo"] = 0
test["bar"] = 1
}
func main() {
fmt.Println(test) // prints map[foo:0 bar:1]
}
Init will be called before main is run.
If you accidentally use "Func" or "function" or "Function" instead of "func" you will also get:
non-declaration statement outside of function body
Posting this because I initially ended up here on my search to figure out what was wrong.
Short variable declarations i.e. :=, can ONLY be used within functions.
e.g.
func main() {
test := "this is a test"
// or
age := 35
}
Declarations outside a function you must make use of keywords like var, func, const e.t.c depending on what you want (in this case we're using var).
Declaring a variable outside a function makes it accessible within its package.
package apitest
import (
"fmt"
)
// note the value can be changed
var test string = "this is a test"
func main() {
fmt.Println(test)
test = "Another value"
fmt.Println(test)
}
Extra info
If you want the variable to be accessible both within and outside its package, the variable has to be capitalized e.g.
var Test string = "this is a test"
this will make it accessible from any package.
We can declare variables as below:
package main
import (
"fmt"
"time"
)
var test = "testing"
var currtime = "15:04:05"
var date = "02/01/2006"
func main() {
t := time.Now()
date := t.Format("02/01/2006")
currtime := t.Format("15:04:05")
fmt.Println(test) //Output: testing
fmt.Println(currtime)//Output: 16:44:53
fmt.Println(date) // Output: 29/08/2018
}
Outside a function, every statement begins with a keyword (var, func, and so on) and so the := construct is not available.
You can read more information here: https://tour.golang.org/basics/10
I got this error when I was trying to run Go app with function definition like this:
(u *UserService) func GetAllUsers() (string, error) {...} //Error code
The correct way of defining a function (receiver function) was:
func (u *UserService) GetAllUsers() (string, error) {...} //Working code