jschnet / unicon

http://www.unicon.org
Other
2 stars 0 forks source link

Dynamic file update #3

Open jschnet opened 2 years ago

jschnet commented 2 years ago

More of a complicated problem. IVIB writes values to tags that it can later retrieve and reload the gui design from this layout code. The problem is that these tags aren't updated on the code side so when a change is made to the code, it is not represented in the ivib layout and is overwritten.

jschnet commented 2 years ago

#

Output the code to file called s.

# method output_code(s) local f f := open(s, "w") | return alert_error("Couldn't open " || s)

  if self.imports_out(f) then
     write(f)

  self.header_out(f)

  add_setup_methods()
  if self.methods_out(f) then
     write(f)
  self.setup_out(f)

  if \self.parent_Canvas.gen_initially then {
     write(f)
     self.initially_out(f)
  }
  write(f, "end")
  if \self.parent_Canvas.gen_main then {
     write(f)
     self.main_out(f)
  }
  write(f)
  encoded_canvas_out(f)

  close(f)
  if f := open(s) then {
 ivib_maindialog.source := []
 while put(ivib_maindialog.source, read(f))
 close(f)
 }

  return

end

jschnet commented 2 years ago

#

Interpose code to already existing file named src_name, resulting in dest_name.

# method interpose_code(src_name, dest_name) local f, part1, t, reading_class, id, method_name, part2, tempname, s static idchars initial idchars := &letters++&digits++''

  /dest_name := src_name

  add_setup_methods()

  if not (f := open(src_name)) then {
 alert_error("warning, couldn't open " || src_name)
 # the file has disappeared, try writing it from the copy we saved
 if f := open(src_name, "w") then {
    every write(f, !ivib_maindialog.source)
    close(f)
    if not (f := open(src_name)) then
       return alert_error("Couldn't open " || src_name)
    }
 else
    return alert_error("Couldn't open " || src_name)
 }

  #
  # Save contents up to setup() method
  #
  part1 := []
  repeat {
     t := read(f) | return alert_error("Couldn't find setup method")
     t ? {
        tab(many(' '))
        if ="class " then {
           tab(upto('(')) | return alert_error("No ( after class declaration")
           move(1)
           reading_class := 1
        }
        if \reading_class then {
           tab(many(' \t'))
           while id := tab(many(idchars)) do {
              delete(class_vars, id)
              tab(many(', '))
           }
           if any(')') then
              reading_class := &null
        }
        else if ="method " then {
           tab(many(' '))
           method_name := tab(many(idchars))
           if method_name == "setup" then
              break
           delete(methods, method_name)
        }
        else if ="import " then {
           while tab(upto(idchars)) do
              delete(imports, tab(many(idchars)))
        }
     }
     put(part1, t)
  }

  #
  # Skip over old setup method
  #
  repeat {
     t := read(f) | return alert_error("Unexpected eof in setup method")
     t ? {
        tab(many(' '))
        if tab(0) == "end" then
           break
     }
  }

  #
  # Get remainder of file, stopping at end-of-file or the ### marker (v1/2)
  #
  part2 := []

  while t := read(f) & t ~== v2_marker & t ~== v1_marker do {
     t ? {
        tab(many(' '))
        if ="method " then
           delete(methods, tab(many(idchars)))
     }
     put(part2, t)
  }
  close(f)

  #
  # Re-create file
  #
  temp_name := dest_name || ".temp"
  f := open(temp_name, "w") | return alert_error("Couldn't open " || temp_name)

  #
  # Output any new imports
  #
  imports_out(f)

  reading_class := &null
  every s := !part1 do {
     s ? {
        if ="class " then {
           # Substitute our own class and superclass name
           s := "class " || self.parent_Canvas.name || " : " ||
              self.parent_Canvas.superclass_name || "("
           tab(upto('('))
           move(1)
           s ||:= tab(0)
           &subject := s
           reading_class := 1
        }
        if \reading_class then {
           # Look for the end of the class variables and insert our
           # new variables.
           if s := tab(upto(')')) then {
              reading_class := &null
              #
              # Add any new class vars.
              #
              if *class_vars > 0 then {
                 if s[-1] ~== "(" then
                    s ||:= ", "
                 every s ||:= !sort(class_vars) || ", "
                 s[-2:0] := ""
              }
              s ||:= tab(0)
           }
        }
        write(f, s)
     }
  }

  if self.methods_out(f) then
     write(f)
  self.setup_out(f)

  every s := !part2 do {
     #
     # Map v1 initially call to v2.
     #
     s ? {
        tab(many(' '))
        if match("self$_Dialog.initially()") then
           s[&pos:0] := "self.Dialog.initially()"
     }
     write(f, s)
  }

  encoded_canvas_out(f)

  close(f)

  #
  # Everything okay, so rename
  #
  remove(dest_name)
  rename(temp_name, dest_name) | stop("Couldn't rename new source file " || temp_name || " to " || dest_name)

  return

end

jschnet commented 2 years ago

#

Hypothesis

Create new class for updating ivib tags -- updateivibtags.icn #

Handle update on save functions

jschnet commented 2 years ago

I am just gonna create a new class that imports the package lang to be able to handle encoding and decoding of ivib tags. Here, we should be able to further implement dynamic file updating, but due to time restrictions, only basic implementation will be added to update pr-existing code which should be always the case so long as the call for this class in it's functions are called after an initial creation of ivib tags. -- The two remaining functions above will be used for reference in the creation of this new class