if $LedgeDetectorh.is_colliding()&&$LedgeDetectorh.get_collider() is Ledge:
if !$LedgeDetectorv.is_colliding():
isLedgeGrabbed = true
elif !$LedgeDetectorh2.is_colliding():
isLedgeGrabbed = false
if isLedgeGrabbed:
Motion = Vector2.ZERO
applyGravity = false
$LedgeDetectorv.enabled = false
$LedgeDetectorh2.enabled = false
if immediateInputLogic:
onLedgeGrabbedIdle = false
$LedgeTimer.start(5)
else:
onLedgeGrabbedIdle = true
if onLedgeGrabbedIdle:
Motion.y =0
Motion.x = 0
if $LedgeTimer.time_left ==0:
if $LedgeDetectorh2.enabled == true:
self.position.direction_to($LedgeDetectorh2.get_collision_point())* 50
elif $LedgeTimer.time_left > 0:
print("works")
Motion.y = lerp(Motion.y, -400,1)
Motion.x = lerp(Motion.x, 100 * direction,0.2)
elif !$LedgeDetectorh2.is_colliding():
$LedgeDetectorh.enabled = true
$LedgeDetectorv.enabled = true
$LedgeDetectorh2.enabled = true
applyGravity = true
problem is as far as I can tell raycast2ds keep on getting enabled and false all the time made some conditions to only enable them if is not colliding with wall still no luck
I'd say keep your multiple RayCast2D enabled. If your goal is to optimize the code, this is not the way (for that I'd suggest intersect_ray). However, first let us make sure it works correctly.
By the way, you can use is_stopped() instead of time_left.
I'm confused about what approach you are going for. I'm aware of a few approaches to do this:
Two horizontal RayCast2D, both horizontal, and parallel to each other, checking for the wall. One on the bottom and one on the top. If the bottom one detects a wall, but the top one does not, it means it there is a ledge. This is easy to implement, but does not give much information for animation/Inverse kinematics. You know there is a ledge, but not exactly where.
Again two RayCast2D. This time one is horizontal and detects a wall, and the other one is vertical, casting downwards from the top, and it is trying to find the floor where the player would stand if it climbed up the ledge. With the catch that you should position the vertical RayCast2D according to the position where the horizontal collided. Which reminds me, use force_update_transform and force_raycast_update if you moved the RayCast2D from code.
With collaboration from ledge objects. You can add small Area2Ds for each ledge on the designer, and if the player overlaps any of them, then it is on a ledge.
Again with collaboration from ledge objects, but this time they are floor extensions that the player can check with a RayCast2D directly upwards. So an horizontal ReyCast2D finds the wall, and a vertical RayCast2D finds the floor extensions that identifies the ledge. Taking care of collision layers and masks so these floor extensions do not interfere with anything else.
Having these ledge objects is great for animation (in particular in 3D), since you can get very precise positions for that inverse kinematics. But it means that a designer has to make sure they are placed in the world, and in any area without them the player can't climb. Don't tell me, you have seen that in games.
You already have ledge objects, don't you? I think it would be easy to add an Area2D to them and use the third approach I listed above, which does not require RayCast2D at all.
So the Ledge would be or have an Area2D that connects "body_entered" to the Area2D itself. When the signal triggers, the Area2D will get a reference to the object that entered. Make sure it is the player, and call a method on it, letting it know there is a ledge it can grab (it can pass its own position as parameter so the player script can snap to it).
Addendum
Let us go over the third approach as described. There will be an Area2D for each ledge. This Area2D will have a script, and the class name is Ledge:
class_name Ledge extends Area2D
So the Ledge would be or have an Area2D that connects "body_entered" to the Area2D itself. When the signal triggers, the Area2D will get a reference to the object that entered.
I'll do the signal connections from code. As to avoid any mistake in connecting it via the editor.
class_name Ledge extends Area2D
func _ready() -> void:
connect("body_entered", self, "_on_body_entered")
func _on_body_entered(body:Node) -> void:
pass
Here body is the reference of the body that entered.
Make sure it is the player
Hopefully you can use collision masks and layers to narrow the checks. I don't know how you would identify the player, but I'll venture to guess it has a class name Player, so I can check like this:
class_name Ledge extends Area2D
func _ready() -> void:
connect("body_entered", self, "_on_body_entered")
func _on_body_entered(body:Node) -> void:
if body is Player:
pass
and call a method on it, letting it know there is a ledge it can grab (it can pass its own position as parameter so the player script can snap to it).
So you can either have the Area2D pass itself, or pass its global position. In the code below go for the global position. I'll call the method it calls on player on_ledge, which also means we can check for the method with has_method (I'll replace the check for that).
class_name Ledge extends Area2D
func _ready() -> void:
connect("body_entered", self, "_on_body_entered")
func _on_body_entered(body:Node) -> void:
if body.has_method("on_legde"):
body.on_ledge(global_position)
And you would, of course, add that method to the player script:
func on_ledge(ledge_global_position:Vector2) -> void:
print(ledge_global_position)
There you can snap the player position, play an animation or whatever is appropriate.
Perhaps passing the Area2D itself is better, we could do this:
class_name Ledge extends Area2D
func _ready() -> void:
connect("body_entered", self, "_on_body_entered")
func _on_body_entered(body:Node) -> void:
if body.has_method("on_legde"):
body.on_ledge(self)
And then on the player:
var current_ledge:Area2D = null
func on_ledge(ledge:Area2D) -> void:
current_ledge = ledge
func _physics_process(_delta:float) -> void:
if not is_instance_valid(current_ledge) or not current_ledge.overlaps_body(self):
current_ledge = null
if current_ledge != null:
var current_ledge_position = current_ledge.global_position
# do something with the ledge position
Related
I'm new to PureScript. I was searching for sealed classes in Purescript to get an idea of how one would implement this, but I don't think I have the necessary PS jargon yet.
What is the canonical way in PureScript to have a bunch of records that extend a "base" record, but then have one sum type representing a "sealed" collection of those.
Something like in Kotlin,
sealed class Glazing(val name: String, val area: Int) {
class Window(val name: String, val area: Int, val frameMaterial: String): BaseGlazing(name, area)
class Door(val name: String, val area: Int, val isPreHung: Boolean): BaseGlazing(name, area)
}
in TypeScript, you'd probably do something like
interface BaseGlazing { ... }
interface Door extends BaseGlazing { ... }
interface Window extends BaseGlazing { ... }
type Glazing = Door | Window
and then you'd either take `A extends BaseGlazing` or `Glazing` (and use type guards) to do either of those two above functions.
Essentially I want a base class (that is technically abstract), things that extend it, and then a sum type/discriminated union of the extensions so that way I can both write, say, changeName:: Glazing -> Glazing (premised on the base class having a name prop) but also do something like calculateTotalLightPenetration :: Array Glazing -> Number (premised on the discriminated union being one of Door or Window since light penetration will be a different formula for doors vs windows)
The idea of "inheritance" (aka "is-a" relationship) is technically possible to model in PureScript, but it's hard and awkward. And there is a good reason for it: inheritance is almost never (and I am tempted to say "never, period") the most convenient, efficient, or reliable way of modeling the domain. Even OOP apologists tend to recommend aggregation over inheritance these days.
One useful thing to observe is that you don't actually need inheritance. What you need is to solve some specific problem in your domain, and inheritance is just a solution that you naturally reach for, which is probably informed by your past experience.
And this leads us to an insight: the particular way to model whatever it is you're modeling would depend on what the actual problem is. Chances are, PureScript has a different mechanism for modeling that.
But if I base my thinking on the specifics you gave in your question (i.e. the changeName and calculateTotalLightPenetration functions), I would model it via aggregation: the "glazing" would be the surrounding type, and it would have, as one of its parts, the specific kind of glazing. This would look something like this:
type Glazing = { name :: String, area :: Int, kind :: GlazingKind }
data GlazingKind = Window { frameMaterial :: String } | Door { isPreHung :: Boolean }
changeName :: Glazing -> Glazing
changeName g = g { name = "new name" }
calculateTotalLightPenetration :: Array Glazing -> Number
calculateTotalLightPenetration gs = sum $ individualPenetration <$> gs
where
individualPenetration g = case g.kind of
Door _ -> 0.3
Window _ -> 0.5
I'm new to golang and confused by the following,
type TreeNode struct {
Val int
Left *TreeNode
Right *TreeNode
}
func test() []*TreeNode {
return []*TreeNode{}
}
func test1() []*TreeNode {
return []*TreeNode{nil}
}
I'm trying to write a recursion func on TreeNode, however, if I used the test style to represent the leaf node, I will get an empty TreeNode slice from the caller func.
If I use the test1 to represent the leaf node, then the behaviour is what I want.
I feel that for the test1, it's giving me a point to an empty TreeNode, however, the test code, is giving me a point to nil... I'm not sure if I'm getting this right or not. Can you please point me the correct terms or concepts to dig, it will be great.
In addition, if you can let me know more about the underline logic, it would be great.
Thanks in advance.
This returns an empty slice:
return []*TreeNode{}
This returns a slice containing one element, and that element is a nil pointer:
return []*TreeNode{nil}
None of these give you a TreeNode though. The second one gives you a TreeNode pointer that is nil. How you interpret these depends on the rest of the code, but I doubt either is really what you want, since none can have the val field.
I'm currently writing an Android music player application using Scala. I chose Scala for its functional programming capabilities and I want to make the code the most FP compliant possible.
As FP implies immutability, the code should not carry any state and variables should be immutable. But I'm facing some complicate use cases I don't know how to resolve in a pure functional programming way.
The first one is the playlist case. The music player is reading a song in the middle of a playlist. This can be represented with a list of songs and a cursor that indicates the current played song. But when that song ends, then the player has to play the next one, hence, change the value of the cursor.
The same problem happens with the playlist itself: the user must be able to change (add or suppress songs) the playlist. If the playlist itself is immutable, any time the user adds or suppress a song, a new playlist is produced. But that playlist must be affected to a variable that must then be mutable.
Everywhere I look in this application, I see states — is the player paused or not? What is the current song, the current playlist? What is the current state of the settings? Etc. — and I don't know how to solve this in a pure functional programming way, i.e. with immutable variables.
As these use cases seem pretty standard, I suppose there are design patterns to solve them (like monads) but I don't know where to look.
I wrote some libraries that tried to address this, the result was fairly ugly, IMO.
Basically, turned Activity, Fragment, etc. into pure functions that accepted State and returned State.
This in conjunction with IO monads made the interface somewhat pure. An example of this follows (the source to PureActivity can be found at https://github.com/pfn/iota-pure), the 'state' in this case is 'Option[Process]' with Process being present when logcat is running and empty when it is not. No vars:
class LogcatActivity extends AppCompatActivity with PureActivity[Option[Process]] {
val LOG_LINE = """^([A-Z])/(.+?)\( *(\d+)\): (.*?)$""".r
val buffersize = 1024
lazy val toolbar = newToolbar
lazy val recycler = {
val r = new RecyclerView(this)
r.setLayoutManager(new LinearLayoutManager(this))
r.setAdapter(Adapter)
r
}
lazy val layout = l[LinearLayout](
toolbar.! >>= lp(MATCH_PARENT, WRAP_CONTENT),
recycler.! >>= lp(MATCH_PARENT, 0, 1)
) >>= vertical
override def initialState(b: Option[Bundle]) = None
override def applyState[T](s: ActivityState[T]) = s match {
case OnPreCreate(_) => s(IO(
setTheme(if (Settings.get(Settings.DAYNIGHT_MODE)) R.style.SetupTheme_Light else R.style.SetupTheme_Dark)
))
case OnCreate(_) => s(IO {
toolbar.setTitle("Logcat")
toolbar.setNavigationIcon(resolveAttr(R.attr.qicrCloseIcon, _.resourceId))
toolbar.navigationOnClick0(finish())
setContentView(layout.perform())
})
case OnStart(_) => s.applyState(IO {
var buffering = true
val logcat = "logcat" :: "-v" :: "brief" :: Nil
val lineLogger = new ProcessLogger {
override def out(s: => String) = addLine(s)
override def buffer[X](f: => X) = f
override def err(s: => String) = addLine(s)
def addLine(line: String) = line match {
case LOG_LINE(level, tag, pid, msg) =>
if (tag != "ResourceType") UiBus.run {
val c = Adapter.getItemCount // store in case at max items already
Adapter.buffer += LogEntry(tag, level, msg)
Adapter.notifyItemInserted(math.min(buffersize, c + 1))
if (!buffering)
recycler.smoothScrollToPosition(Adapter.getItemCount)
}
case _ =>
}
}
Future {
Thread.sleep(500)
buffering = false
} onSuccessMain { case _ =>
recycler.scrollToPosition(Adapter.getItemCount - 1)
}
logcat.run(lineLogger).?
})
case OnStop(proc) => s.applyState(IO {
proc.foreach(_.destroy())
None
})
case x => defaultApplyState(x)
}
case class LogEntry(tag: String, level: String, msg: String)
case class LogcatHolder(view: TextView) extends RecyclerView.ViewHolder(view) {
def bind(e: LogEntry): Unit = view.setText(" %1 %2: %3" formatSpans (
textColor(MessageAdapter.nickColor(e.level), e.level),
textColor(MessageAdapter.nickColor(e.tag), e.tag), e.msg))
}
object Adapter extends RecyclerView.Adapter[LogcatHolder] {
val buffer = RingBuffer[LogEntry](buffersize)
override def getItemCount = buffer.size
override def onBindViewHolder(vh: LogcatHolder, i: Int) = vh.bind(buffer(i))
override def onCreateViewHolder(viewGroup: ViewGroup, i: Int) = {
val tv = new TextView(LogcatActivity.this)
tv.setTypeface(Typeface.MONOSPACE)
LogcatHolder(tv)
}
}
}
You are talking about the UI. It is stateful in its essence. You cannot and must not work with it without states. There is only one correct way: to divide the code without states from the code with states.
The best concept for that is the FRP - Functional reactive programming. It separates functional parts and immutable boxes with mutable stateful content and connects them by events.
Be careful, many so-named reactive programming technologies on the net are not such really and only declare being reactive. For example, java RX is absolute invalid and lacks two very important features. (hiding listeners and simultaneousity support)
There is a very good book on the subject. It can be found on the net in some actions, too. The authors give opensource base library and swift FRP support library that could be used as a pattern for creation of your own FRP classes for your need.
I'm trying to get a graph clustering algorithm to work in Rust. Part of the code is a WeightedGraph data structure with an adjacency list representation. The core would be represented like this (shown in Python to make it clear what I'm trying to do):
class Edge(object):
def __init__(self, target, weight):
self.target = target
self.weight = weight
class WeightedGraph(object):
def __init__(self, initial_size):
self.adjacency_list = [[] for i in range(initial_size)]
self.size = initial_size
self.edge_count = 0
def add_edge(self, source, target, weight):
self.adjacency_list[source].append(Edge(target, weight))
self.edge_count += 1
So, the adjacency list holds an array of n arrays: one array for each node in the graph. The inner array holds the neighbors of that node, represented as Edge (the target node number and the double weight).
My attempt to translate the whole thing to Rust looks like this:
struct Edge {
target: uint,
weight: f64
}
struct WeightedGraph {
adjacency_list: ~Vec<~Vec<Edge>>,
size: uint,
edge_count: int
}
impl WeightedGraph {
fn new(num_nodes: uint) -> WeightedGraph {
let mut adjacency_list: ~Vec<~Vec<Edge>> = box Vec::from_fn(num_nodes, |idx| box Vec::new());
WeightedGraph {
adjacency_list: adjacency_list,
size: num_nodes,
edge_count: 0
}
}
fn add_edge(mut self, source: uint, target: uint, weight: f64) {
self.adjacency_list.get(source).push(Edge { target: target, weight: weight });
self.edge_count += 1;
}
}
But rustc gives me this error:
weightedgraph.rs:24:9: 24:40 error: cannot borrow immutable dereference of `~`-pointer as mutable
weightedgraph.rs:24 self.adjacency_list.get(source).push(Edge { target: target, weight: weight });
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
So, 2 main questions:
1. How can I get the add_edge method to work?
I'm thinking that WeightedGraph is supposed to own all its inner data (please correct me if I'm wrong). But why can add_edge not modify the graph's own data?
2. Is ~Vec<~Vec<Edge>> the correct way to represent a variable-sized array/list that holds a dynamic list in each element?
The tutorial also mentions ~[int] as vector syntax, so should it be: ~[~[Edge]] instead? Or what is the difference between Vec<Edge> and ~[Edge]? And if I'm supposed to use ~[~[Edge]], how would I construct/initialize the inner lists then? (currently, I tried to use Vec::from_fn)
The WeightedGraph does own all its inner data, but even if you own something you have to opt into mutating it. get gives you a & pointer, to mutate you need a &mut pointer. Vec::get_mut will give you that: self.adjacency_list.get_mut(source).push(...).
Regarding ~Vec<Edge> and ~[Edge]: It used to be (until very recently) that ~[T] denoted a growable vector of T, unlike every other type that's written ~... This special case was removed and ~[T] is now just a unique pointer to a T-slice, i.e. an owning pointer to a bunch of Ts in memory without any growth capability. Vec<T> is now the growable vector type.
Note that it's Vec<T>, not ~Vec<T>; the ~ used to be part of the vector syntax but here it's just an ordinary unique pointer and represents completely unnecessary indirection and allocation. You want adjacency_list: Vec<Vec<Edge>>. A Vec<T> is a fully fledged concrete type (a triple data, length, capacity if that means anything to you), it encapsulates the memory allocation and indirection and you can use it as a value. You gain nothing by boxing it, and lose clarity as well as performance.
You have another (minor) issue: fn add_edge(mut self, ...), like fn add_edge(self, ...), means "take self by value". Since the adjacency_list member is a linear type (it can be dropped, it is moved instead of copied implicitly), your WeightedGraph is also a linear type. The following code will fail because the first add_edge call consumed the graph.
let g = WeightedGraph::new(2);
g.add_edge(1, 0, 2); // moving out of g
g.add_edge(0, 1, 3); // error: use of g after move
You want &mut self: Allow mutation of self but don't take ownership of it/don't move it.
get only returns immutable references, you have to use get_mut if you want to modify the data
You only need Vec<Vec<Edge>>, Vec is the right thing to use, ~[] was for that purpose in the past but now means something else (or will, not sure if that is changed already)
You also have to change the signature of add_edge to take &mut self because now you are moving the ownership of self to add_edge and that is not what you want
I've written a basic Node struct in D, designed to be used as a part of a tree-like structure. The code is as follows:
import std.algorithm: min;
alias Number = size_t;
struct Node {
private {
Node* left, right, parent;
Number val;
}
this(Number n) {val = n;}
this(ref Node u, ref Node v) {
this.left = &u;
this.right = &v;
val = min(u.val, v.val);
u.parent = &this;
v.parent = &this;
}
}
Now, I wrote a simple function which is supposed to give me a Node (meaning a whole tree) with the argument array providing the leaves, as follows.
alias Number = size_t;
Node make_tree (Number[] nums) {
if (nums.length == 1) {
return Node(nums[0]);
} else {
Number half = nums.length/2;
return Node(make_tree(nums[0..half]), make_tree(nums[half..$]));
}
}
Now, when I try to run it through dmd, I get the following error message:
Error: constructor Node.this (ulong n) is not callable using argument types (Node, Node)
This makes no sense to me - why is it trying to call a one-argument constructor when given two arguments?
The problem has nothing to do with constructors. It has to do with passing by ref. The constructor that you're trying to use
this(ref Node u, ref Node v) {...}
accepts its arguments by ref. That means that they must be lvalues (i.e. something that can be on the left-hand side of an assignment). But you're passing it the result of a function call which does not return by ref (so, it's returning a temporary, which is an rvalue - something that can go on the right-hand side of an assignment but not the left). So, what you're trying to do is illegal. Now, the error message isn't great, since it's giving an error with regards to the first constructor rather than the second, but regardless, you don't have a constructor which matches what you're trying to do. At the moment, I can think of 3 options:
Get rid of the ref on the constructor's parameters. If you're only going to be passing it the result of a function call like you're doing now, having it accept ref doesn't help you anyway. The returned value will be moved into the function's parameter, so no copy will take place, and ref isn't buying you anything. Certainly, assigning the return values to local variables so that you can pass them to the constructor as it's currently written would lose you something, since then you'd be making unnecessary copies.
Overload the constructor so that it accepts either ref or non-ref. e.g.
void foo(ref Bar b) { ... }
void foo(Bar b) { foo(b); } //this calls the other foo
In general, this works reasonably well when you have one parameter, but it would be a bit annoying here, because you end up with an exponential explosion of function signatures as you add parameters. So, for your constructor, you'd end up with
this(ref Node u, ref Node v) {...}
this(ref Node u, Node v) { this(u, v); }
this(Node u, ref Node v) { this(u, v); }
this(Node u, Node v) { this(u, v); }
And if you added a 3rd parameter, you'd end up with eight overloads. So, it really doesn't scale beyond a single parameter.
Templatize the constructor and use auto ref. This essentially does what #2 does, but you only have to write the function once:
this()(auto ref Node u, auto ref Node v) {...}
This will then generate a copy of the function to match the arguments given (up to 4 different versions of it with the full function body in each rather than 3 of them just forwarding to the 4th one), but you only had to write it once. And in this particular case, it's probably reasonable to templatize the function, since you're dealing with a struct. If Node were a class though, it might not make sense, since templated functions can't be virtual.
So, if you really want to be able to pass by ref, then in this particular case, you should probably go with #3 and templatize the constructor and use auto ref. However, personally, I wouldn't bother. I'd just go with #1. Your usage pattern here wouldn't get anything from auto ref, since you're always passing it two rvalues, and your Node struct isn't exactly huge anyway, so while you obviously wouldn't want to copy it if you don't need to, copying an lvalue to pass it to the constructor probably wouldn't matter much unless you were doing it a lot. But again, you're only going to end up with a copy if you pass it an lvalue, since an rvalue can be moved rather than copied, and you're only passing it rvalues right now (at least with the code shown here). So, unless you're doing something different with that constructor which would involve passing it lvalues, there's no point in worrying about lvalues - or about the Nodes being copied when they're returned from a function and passed into the constructor (since that's a move, not a copy). As such, just removing the refs would be the best choice.