I just made the first command plugin for the webserver fdoc processor,
to handle the new slideshow feature. I used the Java like object stuff
to do it so I thought I'd display it here. Slideshows have three commands:

@slideshow
emits the javascript to run a slideshow

@slide
starts a slide

@section
starts a section of a slide

Sections of a slide are displayed on a timer until the slide is complete,
then the next slide shows. You can put anything in a slide you can
put in an fdoc, including Felix code, C++ code, etc.

First we need an interface:

///////////////////////////////////////
// src/tools/slideshow-interface.flx
interface slideshow_t {
  whatami : 1 -> string;
  check-slide-commands : string -> bool;
  finalise-slideshow : 1 -> 0;
}
///////////////////////////////////////

Now here's the actual plugin, with some of the Javascript removed
for clarity:

///////////////////////////////////////////
// src/tools/fdoc-slideshow.flx
val slideshow_js = """
<button id="start" onclick="start_slides()">Start</button>
......
""";

include "./slideshow-interface";

fun setup(config_data:string) = {
  println$ "Setup fdoc-slideshow " + config_data;
  return 0;
}


object slideshow-maker (var write_string: string -> 0) implements slideshow_t = 
{
  method fun whatami () => "Slideshow object";
  var slide_count = 0;
  var slide_section_count = 0;

  proc end_slide_section() { write_string("\n</div>"); }
  proc end_slide() {
    write_string("</div>\n<script>\nslides["+str slide_count+"]=" + str 
slide_section_count + ";\n</script>\n");
  }
  proc start_slide() {
    write_string('\n<div class="slide" id="slide-'+str slide_count+'">\n');
  }
  proc start_slide_section() {
    write_string('\n<div class="slide-section" id="slide-section-'+
      str slide_count+","+str slide_section_count+'" style="display:none">\n');
  }

  method fun check-slide-commands (b:string) : bool =
  {
    if b == "slideshow" do
      write_string (slideshow_js);
      slide_count = 0;
      slide_section_count = 0;
      return true;
    elif b == "slide" do
      if slide_count != 0 do 
        end_slide_section(); 
        end_slide(); 
      done
      slide_count = slide_count + 1;
      slide_section_count = 1;
      start_slide();
      start_slide_section();
      //s = doc;
      return true;
    elif b == "section" do
      if slide_section_count != 0 do 
        end_slide_section(); 
      done
      slide_section_count = slide_section_count + 1; 
      start_slide_section();
      //s = doc;
      return true;
    else
      return false;
    done
  }

  method proc finalise-slideshow () =
  {
    if slide_count > 0 do
      end_slide_section();
      end_slide();
      write_string("\n<script>nslides = " + str slide_count + ";</script>\n");
    done
  }
};

export fun setup of (string) as "setup";
export fun slideshow-maker of (string->0) as "create_slideshow_manager";
///////////////////////////////////

Now in src/tools/fdoc2html.flx we also include the interface and create
a variable to hold the slideshow constructor:

////////////////////////////
include "./slideshow-interface";
var slideshow-maker : (string->0) -> slideshow_t;
/////////////////////////////

In the setup section we initialise the library and that variable:

////////////////////////////////
  linst = Dynlink::init_lib("fdoc-slideshow"+ dll_extn);
  sresult = Dynlink::func1[int,string] (linst, "setup") ("HELLO SLIDESHOW");
  C_hack::ignore(sresult);
  slideshow-maker = Dynlink::func1[slideshow_t,string->0] (linst, 
"create_slideshow_manager");
///////////////////////////////

Finally to actually use it, for each page when xlat_fdoc is called,
we create a slideshow object using the constructor we loaded
from the library, passing it the write_string function local to this invocation
of xlat_fdoc so it can actually output stuff:

/////////////////////////////
fun xlat_fdoc(t:string, filename:string): bool * string =
{
  var slideshow = slideshow-maker write_string of (string);
  println$ "FDOC make slidehow .. " + #(slideshow.whatami);
....
....
        elif b=="note" do ep; pstate=true; write_string("<p class='bug'> 
<em>Note: </em>"); s=doc;
        elif b=="bug" do ep; pstate=true; write_string("<p class='bug'> 
<em>Bug: </em>"); s=doc;
        elif b=="fixed" do ep; pstate=true; write_string("<p class='fixed'> 
<em>Fixed: </em>"); s=doc;
        elif b=="done" do ep; pstate=true; write_string("<p class='done'> 
<em>Done: </em>"); s=doc;
        elif prefix(b,"h1") do h(1,b.[3 to]); 
        elif prefix(b,"h2") do h(2,b.[3 to]); 
....
....
        elif slideshow.check-slide-commands b do
          s = doc;
        else ....
...
   slideshow.finalise-slideshow;
....
////////////////////////////////

and that's it. It worked FIRST TIME. I was shocked! First time I've used objects
for anything serious. The actual slideshow code was already working,
I just moved it into a plugin and bundled the code up into an object,
still its pretty amazing that after the code finally compiled it just ran.


--
john skaller
skal...@users.sourceforge.net
http://felix-lang.org




------------------------------------------------------------------------------
Live Security Virtual Conference
Exclusive live event will cover all the ways today's security and 
threat landscape has changed and how IT managers can respond. Discussions 
will include endpoint security, mobile security and the latest in malware 
threats. http://www.accelacomm.com/jaw/sfrnl04242012/114/50122263/
_______________________________________________
Felix-language mailing list
Felix-language@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/felix-language

Reply via email to