Thank for you reply. But I don't see any solution to my problem.. I'll
explain it a little more.
I want to develop a sort of GUI. The GUI has its own logic and use a
rendering engine to do the work. I want my GUI separate of the rendering
engine.
In the first solution I use a trait that hide the renderer. So I have a
struct that old the renderer that implement the trait. It is created at
the start of ther application and passed to every GUI call. At the end
the trait is casted to the effective renderer to do the work:
trait Renderer{}
struct MyRender{
API_render: ~effectiveRenderer,
}
impl Renderer for MyRender{}
struct MyGUIWidget;
impl MyGUIWidget {
fn draw(&self, renderer: &renderer) { //here I know what type
of renderer to use.
let myrender = render as &MyRender; //error: non-scalar cast:
`&Renderer<no-bounds>` as `&MyRender`
myrender.API_render.render();
}
}
#[main]
fn main() {
let render = MyRender{API_render: ~...}; //init with user choice
renderer
let widget = MyGUIWidget;
widget.draw(render); //draw
}
I didn't find a way to send specific Renderer to an API with a generic
trait and to polymorph it when I know which struct it is.
I can use a singleton or a static variable but static allocation doesn't
seem to be allowed (as I undersdant the documentation).
So I try with closure and I have a sort of example working using a
renderer :
trait Renderer{} //
struct MyRender{
API_render: ~effectiveRenderer,
}
impl Renderer for MyRender{}
trait Container{
fn draw(&self, draw_render: ||);
}
struct MyContainer {
value :~str,
}
impl Container for MyContainer {
fn draw(&self, draw_render: ||) {
draw_render();
}
}
#[main]
fn main() {
let render = MyRender{API_render: ~StringRender}; //init with user
choice renderer
let container = MyContainer{value: ~"value"};
container.draw(|| {
render.API_render.render(container.value);
}); //draw
}
To extend my API I need to use more closure and if I don't what to
construct every thing in the main I have to return closure constructed
by each widget for example.
My last idea is to use a spawned task that hold the renderer and send it
the widget to draw but It seems to me a little complicated.
So I don't see any simple to do it. If anybody can help, it would be
very helpful.
Philippe
Le 20/02/2014 04:14, Jack Moffitt a écrit :
I'am learning the functional programming paradigm with rust and to help me I
decide to translate the pattern of the book "Functional Programming Patterns
in Scala and Clojure" in Rust. In this work I have a problem to return a
closure (or a function) as a return value and I didn't find any solution. I
understand the problem but I can't find a solution. The code is :
Closures in Rust are stack allocated, so you can't return them from a
function since the function's stack will be gone. You can use either a
proc() or a ~Trait object. A proc can only be called once, but a trait
object can be called many times. If you don't need to close over any
state (which it appears you don't from your example), then you can
return bare functions.
Here's a trait object example (untested and incomplete):
trait Comparison {
fn compare(&self, p1: &Person, p2: &Person) -> Ordering;
}
fn make_comparison() -> ~Comparison {
struct ClosedOverState {
...
}
impl Comparison for ClosedOverState {
fn compare(...) -> Ordering {
.... // access state through self.foo
}
}
~ClosedOverState {
foo: 0,
}
}
It can be simplified with macros.
jack.
_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev