GODOT - Signal not connecting when using connect(). Function is not getting executed - godot

Here is the link to the files:
signal_test.gd
extends Node2D
signal do
func _ready() -> void:
print('signal_ready!')
emit_signal('do')
pass
test.gd
extends Node2D
onready var signal_test = preload('res://signal_test.tscn')
func _ready() -> void:
print('test ready')
func _process(delta: float) -> void:
if Input.is_action_just_pressed("jump"):
var h = signal_test.instance()
add_child(h)
h.connect('do', self, 'do')
print(h.is_connected('do', self, 'do'))
func do():
print('DONE CONNECTING!!')
The test.gd file creates an instance of a node and connect it to it's function using the connect() method. But the function is not getting executed. It only says true when I use is_connected() on the test.tscn, but false on the instance of the node. Anyone know why?

The signal will be emitted in _ready, which will execute after the node is added as child, before the next line:
var h = signal_test.instance()
add_child(h)
# <-- signal emitted here, it is NOT connected
h.connect('do', self, 'do')
Solution: connect the signal before adding the node as child:
var h = signal_test.instance()
h.connect('do', self, 'do')
add_child(h)
# <-- signal emitted here, it is connected

Related

Godot Onready var not working and getting error Unexpected "Identifier" in class body

trying to use onready var to start a raycast to play a animation for a npc but even though the ray works it wont play the animation
code:
extends Node3D
enum
{
Attack1,
Death1,
Idle,
Pose,
Walk
}
var state = Idle
onready var raycast = $RayCast3D
onready var ap = $"maxdamage_zombie-low-poly"
func _ready():
pass # Replace with function body.
# Called every frame. 'delta' is the elapsed time since the previous frame.
func _process(delta):
if raycast.is_colliding():
state = Attack1
else:
state = Idle
match state:
Attack1:
ap.play("Attack1")
Death1:
ap.play("Death1")
Idle:
ap.play("Idle")
Pose:
ap.play("Pose")
Walk:
ap.play("Walk")
Explanation/Alternative simple answer on how to fix the code in a beginner/intermediate level explanationyour text

Definition of goto out of main and print threads

I have two questions about Go code. This is my program.
This program controls the presence of a nickname in a "database".
package main
import "fmt"
func rcv(){
if r := recover() ; r != nil {
fmt.Println("retry.")
main()
}
}
func main(){
defer rcv()
INSERT:
fmt.Println("Insert a nickname: ")
var s string
fmt.Scanln(&s)
switch {
case len(s) <= 0 :
fmt.Println(fmt.Errorf("error empty"))
goto INSERT
case s=="mark"||s=="andrea":
fmt.Println("Accept, the nickname is",s)
default :
fmt.Println("ATTENTION, nickname not found")
panic("Error.")
}
}
My questions are:
Using the recover function ( rcv () ), at the end of it, the recalled of main() is sent running like another thread? The principal main() function ends when the second is executed or whenever the panic is raised, the recover function create another process? (example: if the input nickname is wrong 5 times, 5 more main functions are started, so 6 Main running functions?) If create multiple executions of the main(), is there a way to print threads/process id or something like that?
I used the INSERT label and the goto construct. Can I use goto outside the main function (example: at the end of the rcv() function to return to the top of the main function)?
I could use goto instead of calling the main() function at the end of the rcv()
1. About defer
defer statement execute function BEFORE exiting scope. So stack of caller-func is remaining while executing defer-func.
func foo() (err error) {
defer func() {
err = io.EOF
}()
}
It will crash with stackoverflow
2. About goto
See documentation
A "goto" statement transfers control to the statement with the corresponding label within the same function.
So you can't label outside func.
3. About question
How do I get back to the beginning of the main () function?
package main
func Main() {
// do your main
}
func main() {
for {
Main()
}
}

Simulation of Thread Pool for a web-server implemented by Erlang doesn't work

The code is as follows:
-module(rudy).
-export([init/1,handler/1,request/1,reply/1, start/1, stop/0]).
start(Port) ->
register(rudy, spawn(fun() ->
init(Port) end)).
stop() ->
exit(whereis(rudy), "time to die").
init(Port) ->
Opt = [list, {active, false}, {reuseaddr, true}],
case gen_tcp:listen(Port, Opt) of % opens a listening socket
{ok, Listen} ->
spawn_many(3,Listen),
%% handler(Listen),
ok;
{error, _Error} -> error
end.
handler(Listen) ->
case gen_tcp:accept(Listen) of % listen to the socket
{ok, Client} ->
request(Client),
gen_tcp:close(Client),
handler(Listen);
{error, _Error} -> error
end.
%% gen_tcp:close(Listen). % close the socket
request(Client) ->
Recv = gen_tcp:recv(Client, 0),
case Recv of
{ok, Str} ->
Request = http:parse_request(Str),
Response = reply(Request),
gen_tcp:send(Client, Response);
{error, Error} ->
io:format("rudy: error: ~w~n", [Error])
end,
gen_tcp:close(Client).
reply({{get, URI, _}, _, _}) ->
timer:sleep(40),
http:ok(URI).
spawn_many(0, _Listen)-> ok;
spawn_many(N, Listen)->
spawn(rudy,handler,[Listen]),
spawn_many(N - 1, Listen).
I intend to create 3 listening socket for client to connect to, but this code doesn't work when executing rudy:start(8027). and then accessing http://localhost:8027/ from web browser.
Where's the culprit? Many thanks.
One thing to know about Erlang sockets is that a process that opens one controls it; when that process dies, the runtime closes the socket.
Consider your start/1 function:
start(Port) ->
register(rudy, spawn(fun() ->
init(Port) end)).
It spawns the init/1 function, registers a name for it, and then returns. This means init/1 is running in a new process, so let's look at init/1:
init(Port) ->
Opt = [list, {active, false}, {reuseaddr, true}],
case gen_tcp:listen(Port, Opt) of % opens a listening socket
{ok, Listen} ->
spawn_many(3,Listen),
%% handler(Listen),
ok;
{error, _Error} -> error
end.
The newly-spawned process running init/1 first calls gen_tcp:listen/2. If it succeeds, it calls spawn_many/2 to set up some acceptors; if it fails, it essentially ignores the error. But here's the key to your problem: regardless of success or failure, init/1 ends, and therefore so does the process in which it was spawned, and because this process, the controlling process of the listen socket, dies, the listen socket is closed. Any acceptors trying to use that socket fail because of that, which you would see if you were to print out the error condition in the handler/1 function.
The way to fix this is to make the init/1 process wait until all processes using the listen socket die off.
One way to do this is to make init/1 pass its pid to spawn_many (thus changing it from spawn_many/2 to spawn_many/3), have init/1 wait for 3 messages before exiting, and change handler/1 to handler/2, taking the pid as an additional argument and sending a message there when it's finished. Th easiest way to have init/1 wait for all the messages is to have it call a recursive function like the one below:
init(Port) ->
Opt = [list, {active, false}, {reuseaddr, true}],
case gen_tcp:listen(Port, Opt) of % opens a listening socket
{ok, Listen} ->
Count = 3,
spawn_many(Count,Listen,self()),
wait_for_threads(Count);
%% handler(Listen),
{error, _Error} ->
error
end.
wait_for_threads(0) ->
ok;
wait_for_threads(Count) ->
receive
handler_done ->
wait_for_threads(Count-1)
end.
Then change handler/1 to handler/2 and have it send the message:
handler(Listen, Pid) ->
case gen_tcp:accept(Listen) of % listen to the socket
{ok, Client} ->
request(Client),
gen_tcp:close(Client),
handler(Listen, Pid);
{error, _Error} ->
error
end,
Pid ! handler_done.
Don't forget to accept the additional pid argument to spawn_many/3:
spawn_many(0, _Listen, _Pid)-> ok;
spawn_many(N, Listen, Pid)->
spawn(rudy,handler,[Listen, Pid]),
spawn_many(N - 1, Listen, Pid).
All this is enough to keep the listen socket alive for all the spawned acceptors.

A simple web-server is not working after switching to multithread in Erlang

Here's the code for rudy.erl:
-module(rudy).
-export([init/1,handler/1,request/1,reply/2, start/1, stop/0]).
start(Port) ->
register(rudy, spawn(fun() ->
init(Port) end)).
stop() ->
exit(whereis(rudy), "time to die").
init(Port) ->
Opt = [list, {active, false}, {reuseaddr, true}],
case gen_tcp:listen(Port, Opt) of % opens a listening socket
{ok, Listen} ->
handler(Listen),
gen_tcp:close(Listen), % close the socket
ok;
{error, _Error} -> error
end.
handler(Listen) ->
case gen_tcp:accept(Listen) of % listen to the socket
{ok, Client} ->
request(Client),
gen_tcp:close(Client),
handler(Listen);
{error, _Error} -> error
end.
request(Client) ->
Recv = gen_tcp:recv(Client, 0),
case Recv of
{ok, Str} ->
Request = http:parse_request(Str),
%% spawn(rudy, reply, [Client, Request]);
reply(Client, Request);
{error, Error} ->
io:format("rudy: error: ~w~n", [Error])
end.
reply(Client, {{get, URI, _}, _, _}) ->
timer:sleep(40),
Response = http:ok(URI),
gen_tcp:send(Client, Response),
gen_tcp:close(Client).
If I execute rudy:start(8027), it will work normally via accessing http://localhost:8027/, but if I convert reply(Client, Request); to spawn(rudy, reply, [Client, Request]);, the preceding URL could not be accessed with no error output to command line.
What's the possible problem here? Thanks in advance.
This is due to a race condition where the socket gets closed before the spawned process can reply. The handler/1 function calls request/1, and that's where the spawn occurs to send the reply. Once spawn starts the new process to call reply/2, it returns immediately and request/1 then returns to handler/1, which immediately closes the socket while reply/2 is executing in the new process and still trying to use the socket.
You can just remove the gen_tcp:close/1 call from handler/1 since the reply/2 function calls it after replying.
If you want to see an example of a small HTTP server in Erlang, see my simple web server.

why won't redis commands work from within my mocha test for coffee script files?

class ThingWithRedis
constructor: (#config) ->
#redis = require('redis').createClient()
push: (key, object) ->
#redis.set(key, object)
fetch: (key, amount) ->
#redis.get key, (err, replies) ->
console.log "|#{replies}|"
module.exports = ThingWithRedis
#if you uncomment these lines and run this file, redis works
#twr = new ThingWithRedis('some config value')
#twr.push('key1', 'hello2')
#twr.fetch('key1', 1)
#twr.redis.quit()
but from the test:
ThingWithRedis = require '../thing_with_redis'
assert = require('assert')
describe 'ThingWithRedis', ->
it 'should return the state pushed on', ->
twr = new ThingWithRedis('config')
twr.push('key1', 'hello1')
twr.fetch('key1', 1)
assert.equal(1, 1)
you never see 'hello1' be printed.
but when I run coffee thing_with_redis.coffee directly with the bottom lines un-commented you do see 'hello2' printed.
it's when I run:
mocha --compilers coffee:coffee-script
redis seems to just stop working. Any ideas?
It is possible that the Redis connection has not yet been established. Try waiting for the 'ready' event before running your tests.
describe 'ThingWithRedis', ->
it 'should return the state pushed on', ->
twr = new ThingWithRedis('config')
twr.redis.on 'ready', ->
twr.push('key1', 'hello1')
twr.fetch('key1', 1)
It is important to note that node_redis adds commands called before the 'ready' event to a queue and then processes them when the connection is established. It is possible that mocha is exiting before redis is 'ready'.
https://github.com/mranney/node_redis#ready

Resources