PreviousUpNext

15.4.1415  src/lib/x-kit/widget/edit/millgraph-mill.pkg

## millgraph-mill.pkg
#
# Extension of textmill for interactive editing of the Mythryl millgraph.
#
# See also:
#     src/lib/x-kit/widget/edit/textpane.pkg
#     src/lib/x-kit/widget/edit/millboss-imp.pkg
#     src/lib/x-kit/widget/edit/textmill.pkg
#     src/lib/x-kit/widget/edit/fundamental-mode.pkg

# Compiled by:
#     src/lib/x-kit/widget/xkit-widget.sublib


stipulate
    include package   threadkit;                                # threadkit                     is from   src/lib/src/lib/thread-kit/src/core-thread-kit/threadkit.pkg
    #
#   package ap  =  client_to_atom;                              # client_to_atom                is from   src/lib/x-kit/xclient/src/iccc/client-to-atom.pkg
#   package au  =  authentication;                              # authentication                is from   src/lib/x-kit/xclient/src/stuff/authentication.pkg
#   package cpm =  cs_pixmap;                                   # cs_pixmap                     is from   src/lib/x-kit/xclient/src/window/cs-pixmap.pkg
#   package cpt =  cs_pixmat;                                   # cs_pixmat                     is from   src/lib/x-kit/xclient/src/window/cs-pixmat.pkg
#   package dy  =  display;                                     # display                       is from   src/lib/x-kit/xclient/src/wire/display.pkg
#   package fil =  file__premicrothread;                        # file__premicrothread          is from   src/lib/std/src/posix/file--premicrothread.pkg
#   package fti =  font_index;                                  # font_index                    is from   src/lib/x-kit/xclient/src/window/font-index.pkg
#   package r2k =  xevent_router_to_keymap;                     # xevent_router_to_keymap       is from   src/lib/x-kit/xclient/src/window/xevent-router-to-keymap.pkg
#   package mtx =  rw_matrix;                                   # rw_matrix                     is from   src/lib/std/src/rw-matrix.pkg
#   package rop =  ro_pixmap;                                   # ro_pixmap                     is from   src/lib/x-kit/xclient/src/window/ro-pixmap.pkg
#   package rw  =  root_window;                                 # root_window                   is from   src/lib/x-kit/widget/lib/root-window.pkg
#   package rwv =  rw_vector;                                   # rw_vector                     is from   src/lib/std/src/rw-vector.pkg
#   package sep =  client_to_selection;                         # client_to_selection           is from   src/lib/x-kit/xclient/src/window/client-to-selection.pkg
#   package shp =  shade;                                       # shade                         is from   src/lib/x-kit/widget/lib/shade.pkg
#   package sj  =  socket_junk;                                 # socket_junk                   is from   src/lib/internet/socket-junk.pkg
#   package x2s =  xclient_to_sequencer;                        # xclient_to_sequencer          is from   src/lib/x-kit/xclient/src/wire/xclient-to-sequencer.pkg
#   package tr  =  logger;                                      # logger                        is from   src/lib/src/lib/thread-kit/src/lib/logger.pkg
#   package tsr =  thread_scheduler_is_running;                 # thread_scheduler_is_running   is from   src/lib/src/lib/thread-kit/src/core-thread-kit/thread-scheduler-is-running.pkg
#   package u1  =  one_byte_unt;                                # one_byte_unt                  is from   src/lib/std/one-byte-unt.pkg
#   package v1u =  vector_of_one_byte_unts;                     # vector_of_one_byte_unts       is from   src/lib/std/src/vector-of-one-byte-unts.pkg
#   package v2w =  value_to_wire;                               # value_to_wire                 is from   src/lib/x-kit/xclient/src/wire/value-to-wire.pkg
#   package wg  =  widget;                                      # widget                        is from   src/lib/x-kit/widget/old/basic/widget.pkg
#   package wi  =  window;                                      # window                        is from   src/lib/x-kit/xclient/src/window/window.pkg
#   package wme =  window_map_event_sink;                       # window_map_event_sink         is from   src/lib/x-kit/xclient/src/window/window-map-event-sink.pkg
#   package wpp =  client_to_window_watcher;                    # client_to_window_watcher      is from   src/lib/x-kit/xclient/src/window/client-to-window-watcher.pkg
#   package wy  =  widget_style;                                # widget_style                  is from   src/lib/x-kit/widget/lib/widget-style.pkg
#   package xc  =  xclient;                                     # xclient                       is from   src/lib/x-kit/xclient/xclient.pkg
#   package xj  =  xsession_junk;                               # xsession_junk                 is from   src/lib/x-kit/xclient/src/window/xsession-junk.pkg
#   package xtr =  xlogger;                                     # xlogger                       is from   src/lib/x-kit/xclient/src/stuff/xlogger.pkg
    #

    #
    package evt =  gui_event_types;                             # gui_event_types               is from   src/lib/x-kit/widget/gui/gui-event-types.pkg
    package gts =  gui_event_to_string;                         # gui_event_to_string           is from   src/lib/x-kit/widget/gui/gui-event-to-string.pkg
    package gt  =  guiboss_types;                               # guiboss_types                 is from   src/lib/x-kit/widget/gui/guiboss-types.pkg

    package a2r =  windowsystem_to_xevent_router;               # windowsystem_to_xevent_router is from   src/lib/x-kit/xclient/src/window/windowsystem-to-xevent-router.pkg

    package gd  =  gui_displaylist;                             # gui_displaylist               is from   src/lib/x-kit/widget/theme/gui-displaylist.pkg

    package pp  =  standard_prettyprinter;                      # standard_prettyprinter        is from   src/lib/prettyprint/big/src/standard-prettyprinter.pkg

    package err =  compiler::error_message;                     # compiler                      is from   src/lib/core/compiler/compiler.pkg
                                                                # error_message                 is from   src/lib/compiler/front/basics/errormsg/error-message.pkg

    package ct  =  cutbuffer_types;                             # cutbuffer_types               is from   src/lib/x-kit/widget/edit/cutbuffer-types.pkg
#   package ct  =  gui_to_object_theme;                         # gui_to_object_theme           is from   src/lib/x-kit/widget/theme/object/gui-to-object-theme.pkg
#   package bt  =  gui_to_sprite_theme;                         # gui_to_sprite_theme           is from   src/lib/x-kit/widget/theme/sprite/gui-to-sprite-theme.pkg
#   package wt  =  widget_theme;                                # widget_theme                  is from   src/lib/x-kit/widget/theme/widget/widget-theme.pkg



    package boi =  spritespace_imp;                             # spritespace_imp               is from   src/lib/x-kit/widget/space/sprite/spritespace-imp.pkg
    package cai =  objectspace_imp;                             # objectspace_imp               is from   src/lib/x-kit/widget/space/object/objectspace-imp.pkg
    package pai =  widgetspace_imp;                             # widgetspace_imp               is from   src/lib/x-kit/widget/space/widget/widgetspace-imp.pkg

    #    
    package gtg =  guiboss_to_guishim;                          # guiboss_to_guishim            is from   src/lib/x-kit/widget/theme/guiboss-to-guishim.pkg

    package b2s =  spritespace_to_sprite;                       # spritespace_to_sprite         is from   src/lib/x-kit/widget/space/sprite/spritespace-to-sprite.pkg
    package c2o =  objectspace_to_object;                       # objectspace_to_object         is from   src/lib/x-kit/widget/space/object/objectspace-to-object.pkg

    package s2b =  sprite_to_spritespace;                       # sprite_to_spritespace         is from   src/lib/x-kit/widget/space/sprite/sprite-to-spritespace.pkg
    package o2c =  object_to_objectspace;                       # object_to_objectspace         is from   src/lib/x-kit/widget/space/object/object-to-objectspace.pkg

    package g2p =  gadget_to_pixmap;                            # gadget_to_pixmap              is from   src/lib/x-kit/widget/theme/gadget-to-pixmap.pkg

    package im  =  int_red_black_map;                           # int_red_black_map             is from   src/lib/src/int-red-black-map.pkg
#   package is  =  int_red_black_set;                           # int_red_black_set             is from   src/lib/src/int-red-black-set.pkg
    package sm  =  string_map;                                  # string_map                    is from   src/lib/src/string-map.pkg

    package r8  =  rgb8;                                        # rgb8                          is from   src/lib/x-kit/xclient/src/color/rgb8.pkg
    package r64 =  rgb;                                         # rgb                           is from   src/lib/x-kit/xclient/src/color/rgb.pkg
    package g2d =  geometry2d;                                  # geometry2d                    is from   src/lib/std/2d/geometry2d.pkg
    package g2j =  geometry2d_junk;                             # geometry2d_junk               is from   src/lib/std/2d/geometry2d-junk.pkg

    package e2g =  millboss_to_guiboss;                         # millboss_to_guiboss           is from   src/lib/x-kit/widget/edit/millboss-to-guiboss.pkg
    package mgm =  millgraph_millout;                           # millgraph_millout             is from   src/lib/x-kit/widget/edit/millgraph-millout.pkg

    package mt  =  millboss_types;                              # millboss_types                is from   src/lib/x-kit/widget/edit/millboss-types.pkg

#   package fm  =  fundamental_mode;                            # fundamental_mode              is from   src/lib/x-kit/widget/edit/fundamental-mode.pkg

#   package que =  queue;                                       # queue                         is from   src/lib/src/queue.pkg
    package nl  =  red_black_numbered_list;                     # red_black_numbered_list       is from   src/lib/src/red-black-numbered-list.pkg

    package psx =  posixlib;                                    # posixlib                      is from   src/lib/std/src/psx/posixlib.pkg

    tracefile   =  "widget-unit-test.trace.log";

    nb = log::note_on_stderr;                                   # log                           is from   src/lib/std/src/log.pkg


herein

    package millgraph_mill {                                    # 
        #
        Millgraph__Watchee                                                                                      # Type for tracking the client we are subscribed to for mt::Textmill_Statechange updates.
            =                                                                                                   #
            {   wrapped_millout:                        mt::Millout,                                            # 
                millout:                                mgm::Millgraph_Millout                                  # Unwrapped version of preceding.
            };


        Millgraph_Mill_State
          =
          {
            millgraph__inport:          mt::Inport,                                                             # Our name for our millgraph input port.
            millgraph__millin:          Ref( mt::Millin ),
            millgraph__watchee:         Ref( Null_Or( Millgraph__Watchee ) )                                    # Millgraph stream which we are currently reading. (Might be none, but that does not make much sense normally.)  Normally the millgraph outport on millboss_imp.
          };

        exception  MILLGRAPH_MILL_STATE  Millgraph_Mill_State;                                                  # Our per-pane persistent state (currently none).

        
        fun dummy_make_pane_guiplan                                                                                                             # Synthesize guiplan for a pane to display our state.
              {
                textpane_to_textmill:           mt::Textpane_To_Textmill,                                                                       # 
                filepath:                       Null_Or( String ),                                                                              # make_pane_guiplan will (should!) often select the pane mode to use based on the filename.
                textpane_hint:                  Crypt                                                                                           # Current pane mode (e.g. fundamental_mode) etc, wrapped up so textmill can't see the relevant types, in the interest of modularity.
              }
            :                                   gt::Gp_Widget_Type
            =
            {   msg = "dummy_make_pane() called?!  --textmill.pkg";
                log::fatal msg;                                                                                                                 # Should never return.
                raise exception DIE msg;                                                                                                        # To keep compiler happy.
            };
        make_pane_guiplan__hack                                                                                                                         # Nassssty hack to break a package dependency cycle.
            =                                                                                                                                   # This is used by App_To_Mill.make_pane_guiplan() below.
            REF dummy_make_pane_guiplan;                                                                                                        # This value will be overwritten by   src/lib/x-kit/widget/edit/millgraph-mode.pkg

        fun decrypt__millgraph_mill_state (crypt: Crypt): Millgraph_Mill_State
            =
            case crypt.data
                #
                MILLGRAPH_MILL_STATE
                millgraph_mill_state
                    =>
                    millgraph_mill_state;

                _ =>    {   msg = sprintf "decrypt__millgraph_mill_state:  Unknown Crypt value, type='%s' info='%s'  --millagraph-mill.pkg" 
                                        crypt.type
                                        crypt.info
                                  ;
                            log::fatal          msg;
                            raise exception DIE msg;
                        };
            esac;

        stipulate
            #

            fun initialize_textmill_extension                                                                   # This will get called by  startup()  in  src/lib/x-kit/widget/edit/textmill.pkg
                  {
                    mill_id:            Id,
                    textmill_q:         mt::Textmill_Q,
                    millins:            mt::ipm::Map(mt::Millin),                                               # Inports  exported by parent textmill.
                    millouts:           mt::opm::Map(mt::Millout),                                              # Outports exported by parent textmill.
                    make_pane_guiplan': mt::Make_Pane_Guiplan_Fn
                  }
                  :
                  { millins:            mt::ipm::Map(mt::Millin),                                               # Above 'millins'  augmented as required by this textmill extension.  Parent textmill will publish via its App_To_Mill interface.
                    millouts:           mt::opm::Map(mt::Millout),                                              # Above 'millouts' augmented as required by this textmill extension.  Parent textmill will publish via its App_To_Mill interface.
                    #
                    mill_extension_state:           Crypt,                                                      # Arbitrary private state for this mill extension.
                    #
                    make_pane_guiplan':             mt::Make_Pane_Guiplan_Fn,
                    finalize_textmill_extension:    Void -> Void                                                # Function to be called at textmill shutdown, so textmill extension can do any required shutdown of its own.
                  }
                =
                {
                    #############################################################################################
                    # Shared persistent state used in later routines.
                    #
                    millgraph__inport                                                                           # Name of     port on which we read in    millgraphs.
                      =
                      { mill_id,
                        inport_name  => "millgraph"
                      };

                    millgraph__watchee                                                                          # Port from           which we read in    millgraphs.
                      =
                      REF (NULL:  Null_Or( Millgraph__Watchee ));                                               # Millgraph stream which we are currently reading. (Might be none, but that does not make much sense normally.)  Normally millboss_millgraph_millout (the millgraph outport on millboss_imp) -- see below.

                    millgraph__millin                                                                           #             Port on which we read in    millgraphs.
                      =
                      REF {                                                                                     # First half of a grody little hack to deal with mutual recursion between millgraph__millin and note__millgraph__watchee + drop__millgraph__watchee.
                            inport     =>   millgraph__inport,                                                  # This gives the world a globally unique name for this particular inport.
                            port_type  =>   mgm::port_type,                                                     # This tells the world that on this port we listen for millgraphs.
                            mono       =>   TRUE,                                                               # This tells the world that we only listen on one input millgraph stream at a time.
                            #                                                                                   #
                            note_input =>   dummy__note__millgraph__watchee,                                    # Caller uses this to tell us to start reading from a different millgraph stream.
                            drop_input =>   dummy__drop__millgraph__watchee,                                    # Caller uses this to disconnect us from input millgraph stream.
                            #                                                                                   #
                            counter    =>   REF 0       
                          }                                                                                     # This record is a dummy that will be discarded momentarily -- see below.
                        where
                            fun dummy__note__millgraph__watchee (wrapped_millout:  mt::Millout) = ();           # Only has to be type-correct.
                            fun dummy__drop__millgraph__watchee (wrapped_millout:  mt::Millout) = ();           # Only has to be type-correct.
                        end;            

                    mill_extension_state
                      =
                      { millgraph__inport,
                        millgraph__millin,
                        millgraph__watchee
                      }
                      :         Millgraph_Mill_State;

                    mill_extension_state
                      =
                      MILLGRAPH_MILL_STATE
                      mill_extension_state;

                    mill_extension_state
                      =
                      { id   =>  issue_unique_id (),
                        type => "millgraph_mill::MILLGRAPH_MILL_STATE",
                        info => "Private state infor for millgraph extension millsgraph-mill.pkg",
                        data =>  mill_extension_state
                      };        

                    #
                    #############################################################################################



                    #############################################################################################
                    # millgraph input stuff
                    #
                    fun note__millgraph
                          (
                            outport:            mt::Outport,                                                    #
                            millgraph:          mt::Millgraph                                                   # 
                          )     
                        =
                        {   put_in_mailqueue  (textmill_q,
                                #
                                \\ (runstate as { id, me, ... }: mt::Textmill_Runstate)
                                    =
                                    {
nb {. sprintf "note__millgraph/AAA   --millgraph-mill.pkg"; };
                                        mills_by_name = millgraph.mills_by_name;
                                        millnames = sm::keys_list mills_by_name;
                                        apply do_millname millnames
                                                where
                                                    fun do_millname (millname: String)
                                                        =
                                                        {
nb {. sprintf "note__millgraph/BBB: millname='%s'   --millgraph-mill.pkg" millname; };
                                                        };
                                                end;
# XXX BUGGO FIXME TBD
                                        counter  =  (*millgraph__millin).counter;                               # Count messages read through port,
                                        counter := *counter + 1;                                                # for debug/display purposes.
                                    }
                            );
                        };
                    fun note__millgraph__watchee' (wrapped_millout:     mt::Millout)                            # Start watching 'wrapped_millout'.
                        =
                        {   millout =  mgm::unwrap__millgraph_millout  wrapped_millout;
                            #
                            case *millgraph__watchee
                                #
                                THE watchee =>  watchee.millout.drop_watcher  millgraph__inport;                # Say goodbye to previous watchee.
                                NULL        =>  ();
                            esac;

                            millout.note_watcher                                                                # Say hello   to new watchee.
                              (
                                millgraph__inport,
                                THE *millgraph__millin,                                                         # So note_watcher can pass Millout+Millin to millboss at same time, keeping millboss consistent.
                                note__millgraph
                              );

                            millgraph__watchee
                                :=
                                THE  { wrapped_millout, millout };
                        };
                    fun note__millgraph__watchee        (wrapped_millout: mt::Millout)                          # PUBLIC.  Start watching 'wrapped_millout'.
                        =
                        {   put_in_mailqueue  (textmill_q,
                                #
                                \\ (runstate: mt::Textmill_Runstate)
                                    =
                                    note__millgraph__watchee'  wrapped_millout                                  # We don't actually use runstate, but now we're running as the mill microthread instead of as caller, so any required mutual exclusion is assured.
                            );
                        };
                    fun drop__millgraph__watchee (wrapped_millout:  mt::Millout)                                # PUBLIC.
                        =
                        {   
                            put_in_mailqueue  (textmill_q,
                                #
                                \\ ({ id, me, ... }: mt::Textmill_Runstate)
                                    =
                                    {   millout =  mgm::unwrap__millgraph_millout  wrapped_millout;
                                        #
                                        case *millgraph__watchee
                                            #
                                            THE watchee =>  watchee.millout.drop_watcher  millgraph__inport;    # Say goodbye to previous watchee.
                                            NULL            =>  ();
                                        esac;

                                        millgraph__watchee
                                            :=
                                            NULL;
                                    }
                            );
                        };

                    millgraph__millin                                                                           # Second half of grody little hack to deal with mutual recursion between millgraph__millin and note__millgraph__watchee + drop__millgraph__watchee.
                      :=
                      { inport     =>   millgraph__inport,                                                      # This gives the world a globally unique name for this particular inport.
                        port_type  =>   mgm::port_type,                                                         # This tells the world that on this port we listen for millgraphs.
                        mono       =>   TRUE,                                                                   # This tells the world that we only listen on one input millgraph stream at a time.
                        #                                                                                       #
                        note_input =>   note__millgraph__watchee,                                               # Caller uses this to tell us to start reading from a different millgraph stream.
                        drop_input =>   drop__millgraph__watchee,                                               # Caller uses this to disconnect us from input millgraph stream.
                        #                                                                                       #
                        counter    =>   REF 0                                                                   # 
                      };

                    #
                    # millgraph input stuff
                    #####################################################################################################



                    #############################################################################################
                    # textmill extension wrapup stuff
                    #
                    fun finalize_textmill_extension (): Void
                        =
                        {                                                                                       # Currently nothing to do at textmill shutdown for this textmill extension.
                        };
                    #
                    #############################################################################################


                    note__millgraph__watchee'  millboss_millgraph_millout                                       # Subscribe to millboss_imp's millgraph stream.
                    where
                        (mt::get__mill_to_millboss  "millgraph_mode::initialize_panemode_state")
                            ->
                            (mill_to_millboss  as  mt::MILL_TO_MILLBOSS m2m);

                        m2m.app_to_mill -> mt::APP_TO_MILL a2m;

                        millboss_millouts =   a2m.millouts;

                        millboss_millgraph_outport
                          =
                          { mill_id          =>  a2m.id,
                            outport_name =>  "millgraph"
                          };

                        millboss_millgraph_millout
                            =
                            case (mt::opm::get (millboss_millouts, millboss_millgraph_outport))
                                #
                                THE millout => millout;

                                NULL => {   msg = "millport_imp did not export a millgraph millout?!  -- millgraph_mode::initialize_panemode_state";
                                            log::fatal msg;
                                            raise exception DIE msg;
                                        };
                            esac;
                    end;


                    millins = mt::ipm::set                                                                      # Add our millgraph inport to list of exports inports for this mill.  Our textmill parent will publish to the world via its App_To_Mill interface.
                                (
                                  millins,
                                  millgraph__inport,
                                 *millgraph__millin
                                );

                    make_pane_guiplan' = *make_pane_guiplan__hack;                                              # This will be millgraph_mode::make_textpane() but we don't want millgraph-mill to refer directly to millgraph-mode
                                                                                                                # (partly to avoid package dependency loops, partly because mills shouldn't know about gui stuff as a matter of good layering) hence the hack.

                    { millins,                                                                                  # Return augmented inport/outport sets to textmill parent for publication via App_To_Mill port.
                      millouts,
                      mill_extension_state,
                      make_pane_guiplan',
                      finalize_textmill_extension
                    };
                };

        herein            

            millgraph_mill                                                                                      # millgraph_mill mainly gets used in   textmill_options => [ mt::TEXTMILL_EXTENSION  mgm::millgraph_mill ... ]   in   src/lib/x-kit/widget/edit/millgraph-mode.pkg
              =
              { id => issue_unique_id (),
                #
                initialize_textmill_extension                                                                   # This will get called by  startup()  in  src/lib/x-kit/widget/edit/textmill.pkg
              }
              : mt::Textmill_Extension
              ;
        end;
    };

end;





Comments and suggestions to: bugs@mythryl.org

PreviousUpNext