Hi,

Nice adaptation of playlist.once()! Let me comment it.

2009/10/11 Аркадий Левин <[email protected]>:
> def dynamic(process)
>  x = string.ref("0")
>  get = fst(x)
>  set = snd(x)

The variable "x" is going to be the current position in the playlist.
Precisely, "x" consists of two functions that work on an underlying
reference. A reference is a mutable cell. Like all variables in
liquidsoap, "x" will always be the same thing: the same two function,
the same reference. But the content of the reference can change over
time. The extra level of indirection through the mutable cell is
important here. I'm insisting here because this is the reason of the
problem, we'll see that below.

>  files = get_process_lines(process)
>  length = list.length(files)

Here you get the length of your playlist, which is created by one call
to your process. You store the result in files, which is an
_immutable_ list of strings. It can never be changed.

>  def next()
>    state = int_of_string(get())
>    if state < length then
>      set(string_of(state + 1))
>      request.create(audio=true,list.nth(files,state))
>    else
>      set(string_of(1))
>      log("playlist end! request new")
>      files = get_process_lines(process)
>      length = list.length(files)

This is the mistake. Here you are only giving new _local_ definitions
of "files" and "length". They have nothing to do with the ones above
-- except that they mask them until the end of the else block.

How to fix this problem? You need to use another reference for "files"
(and also for "length", but this is easy and secondary, you can always
compute the length from the list everytime you need it). The problem
is that you need a reference to a string of list, and we don't have
this -- I'll propose a solution below. As you might have noticed, the
"mutable" business in liquidsoap is currently ugly, it's just a hack
on top of the clean part of the language. This will change soon, in a
branch that I'm working on. But it will come with other changes that
will take some time to stabilize.

Anyways, here's an idea for simulating string list references. Note
that it could also be used for int, float and strings. Use the
settings mechanism. You already know the function set which sets a
configuration setting: set("log.stdout",false). Well you can also set
something that is not a configuration key (you might get a warning in
the logs though): set("playlist_files",get_process_lines(command)).
You can also get them using the function get(), which requires a
parameter telling what to return when the setting is undefined:
get(default=[],"playlist_files") -- the parameter is really necessary
even if you're sure that the setting is defined; it is needed to know
if get() should look for a string, int, float, bool or string list
configuration key.

The downside of using configuration settings is that you need to use a
global name for your "reference", which doesn't help modular
programming. But it should be fine until we have real references in
the language.

>      request.create(audio=true,list.nth(files,0))
>    end
>  end
>  request.dynamic(next)
> end

> if playlist is end, in log write "playlist end! request new" but
> playing old requested playlist, why?

This was because the variables "files" and "length" (their first
occurrence) never get changed. Precisely, you should be hearing one
file from the new playlist (the request.create() from the else block)
and then the old playlist again.

Cheers,
-- 
David

------------------------------------------------------------------------------
Come build with us! The BlackBerry(R) Developer Conference in SF, CA
is the only developer event you need to attend this year. Jumpstart your
developing skills, take BlackBerry mobile applications to market and stay 
ahead of the curve. Join us from November 9 - 12, 2009. Register now!
http://p.sf.net/sfu/devconference
_______________________________________________
Savonet-users mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/savonet-users

Reply via email to