set here [file dirname [file join [pwd] [info script]]]
source [file join $here slides.tcl]


set obj [::html_slidemaker::object new]

$obj slide {
<h1 style="text-align: center;">The Clay Framework</h1>
<p style="text-align: center;">Sean Woods
}

$obj slide {
The Clay Framework is an attempt to allow prototype based programming within
TclOO.
} div {
<i>Without resorting to event more heroic means</i>
}

$obj slide {
<h1 style="text-align: center;">What is clay used for?</h1>
Clay introduces a Tcl-ish take on prototype based programming.
} ul {
} li {
The meta-class does virtually nothing, except know how to bolt on more functions through mixins.
} li {
As the object reads it's configuration it uses mixins to add new behavior.
} li {
The object then sets out to accomplish its task.
} /ul {}

$obj slide {
<h1 style="text-align: center;">Applications</h1>
<table border=1 width=900>
<tr><td width=20%>Dynamic web content</td><td>&nbsp;</td></tr>
<tr><td width=20%>A Tcl based make system</td><td>&nbsp;</td></tr>
<tr><td width=20%>Gaming/Chatbots/AI</td><td>&nbsp;</td></tr>
</table>
}

$obj slide {
<h1 style="text-align: center;">Applications</h1>
<table border=1 width=900>
<tr><td width=20%>Dynamic web content</td><td>Httpd / Toadhttpd</td></tr>
<tr><td width=20%>A Tcl based make system</td><td>Practcl</td></tr>
<tr><td width=20%>Gaming/Chatbots/AI</td><td>The Epic of Gilgamesh (Under Development)</td></tr>
</table>
}

$obj slide {
<h1 style="text-align: center;">Clay in Httpd</h1>
httpd::reply only provides basic MIME parsing and socket wrangling.
} ul {
} li {
Parts of that socket wrangling are swappable to implement proxies.
} li {
Custom content replaces the content method.
} li {
Large sites can swap out the header/footer methods to provide sitewide
navigation, inline style sheets, Bootstrap/jQuery integration
} /ul {}

$obj slide {
<h1 style="text-align: center;">Clay in Httpd</h1>
httpd::server utilizes mixins:
} ul {
} li {
Controlled through the <b>plugin</b> method
} li {
Used to swap out dispatch engines, logging mechanisms, and security lockdowns.
} /ul {}

$obj slide {
<h1 style="text-align: center; vertical-align: top;">Rest API Example</h1>
} code {
HTTPD uri direct * restapi {} {
  # Have the reply do its own dispatching
  set URI [split [my request get REQUEST_URI] /]
  lassign [split $URI] base method uuid
  set class [find_class $method]
  if {$class eq {}} {
    # Errors will turned into the appropriate HTTP reply
    tailcall my error 404 {Not Found} {}
  }
  # Mix in a new behavior
  my clay mixinmap rest $class
  my reply set Content-Type application/json
  # Pass off control to a method brought in by the mixin
  tailcall my RestContent
}
}

$obj slide {
<h1 style="text-align: center;">Clay in Practcl</h1>
<p>
Practcl is a Tcl based make system. It can generate Tclkits, binary libaries,
pure-tcl modules, and large collections of pure-tcl packages.
}

$obj slide {
<h1 style="text-align: center;">Clay in Practcl</h1>
When implementing a build system, it helps to be able to refer to a generic build
product, and then get more elaborate as we know more about it. Especially if we need to
detect information from the compiler or environment during the course of compilation.
} code {set affinepath [file dirname [file normalize [info script]]]

namespace eval ::odielib {}
my define set initfunc OdieAffine_Init
my add [file join $affinepath const.tcl]

foreach file [lsort -dictionary [glob [file join $affinepath *.tcl]]] {
  if {[file tail $file] in {const.tcl cmatrixforms.tcl}} continue
  my add $file
}
# Run cmatrixforms at the end
my add [file join $affinepath cmatrixforms.tcl]
my add [file join $affinepath hardcoded_h_file.h]
my add [file join $affinepath hardcoded_c_file.c]
}


$obj slide {
<h1 style="text-align: center;">Clay in Fun Stuff</h1>
When implementing a Role Playing Game, many configuration options require
a modification of behavior. Those options are orthoganal, and often interact
with one another.
}

$obj slide {
<img src=charactersheet.jpg>
}

$obj slide {
<h1 style="text-align: center;">Clay in Fun Stuff</h1>
<table border=1 width=100>
<tr><td>Player</td><td>Yes<td></tr>
<tr><td>Species</td><td>Human<td></tr>
<tr><td>Gender</td><td>Male<td></tr>
<tr><td>Class</td><td>Wizard<td></tr>
</table>
}

$obj slide {
<h1 style="text-align: center;">Clay in Fun Stuff</h1>
<table border=1 width=100>
<tr><td>Player</td><td>Yes<td><td>::gilgamesh::core/avatar</td></tr>
<tr><td>Species</td><td>Human<td><td>::gilgamesh::species/human</td></tr>
<tr><td>Gender</td><td>Male<td><td>::gilgamesh::gender/male</td></tr>
<tr><td>Class</td><td>Wizard<td><td>::gilgamesh::class/wizard</td></tr>
</table>
}

$obj slide {
<h1 style="text-align: center;">Clay in Fun Stuff</h1>
} code {
# Create a database record
GAME object create {
  uuid PLAYER
  name Hypnotoad
  core avatar
  species human
  gender male
  class  wizard
}
# Implement the object from that database record
set obj [GAME object wake PLAYER]
}


$obj slide {
<h1 style="text-align: center;">Developing in Clay</h1>
Clay injects a method into oo::class and oo::object called <b>clay</b>.
<p>
The clay method manages all of the interactions with the framework.
} div {
<p>
<i>ALL OF THEM</i>
}

$obj slide {
<h1 style="text-align: center;">Structured Data</h1>
The principle function of the clay method is to implement a <strike>dictionary</strike>
tree that is stored internally in the object.
} div {
<p>
And in the class
} div {<p>
And all of the mixins
} div {<p>
And all of the ancestors of the class and the mixins
}


$obj slide {
<h1 style="text-align: center;">Structured Data</h1>
} code {
::oo::class create foo {}
foo clay set this/means something
set obj [foo new]
$obj clay get this/means
> something

# Can use file system style paths, or dict style paths
$obj clay get this means
> something
}

$obj slide {
<h1 style="text-align: center;">Structured Data</h1>
} code {
::oo::class create foo {}
foo clay set this means something
::oo::class create bar {
  superclass foo
}
bar clay set this is madness

set obj [bar new]
$obj clay get this means
> something
$obj clay get this is
> madness
$obj clay get this
> means something is madness
}

$obj slide {
<h1 style="text-align: center;">Object can overwrite class data</h1>
} code {
$obj clay set this is Sanity
$obj clay get this is
> Sanity
}

$obj slide {
<h1 style="text-align: center;">And ... a bug</h1>
} code {
$obj clay get this
> means something is madness

###
# SHOULD HAVE BEEN
###
> means something is Sanity
}

$obj slide {
<h1 style="text-align: center;">This stuff isn't easy</h1>
Managing mixins and a stuctured data is EASY.
<p>
Doing it properly... well.... my tests are getting longer than the implementation.
}

$obj slide {
<h1 style="text-align: center;">Delegation</h1>
} code {
sqlite3 ::DB ~/db/mydatabase.sqlite

oo::class create ::mydb {
  method dump_record {table rowid} {
    # <db> goes out to the database
    my <db> eval "select * from $table where rowid=:rowid" record {}
    return [array get record]
  }
}
$obj clay delegate db ::DB
$obj clay mixin ::mydb
set data [$obj dump_record object PLAYER]
}

$obj slide {
<h1 style="text-align: center;">Mixin Events</h1>
} code {
# Script right before a class is removed
::mydb clay set mixin unmap-script {puts "Db...gone"}
$obj clay mixin

# Script as a class is mixed in
::mydb clay set mixin map-script {puts "Db...present"}
# Script as another class is mixed in
::foo clay set mixin react-script {puts "I saw what you did there..."}

$obj clay mixin ::mydb
> Db...Present
> I saw what you did there...
}

$obj slide {
<h1 style="text-align: center;">Introspection</h1>
} code {
$obj clay provenance this/means
> ::foo
$obj clay provenance this/is
> ::bar
$obj ancestors
::bar ::foo ::oo::class
}

$obj slide {
<h1 style="text-align: center;">Option Passing</h1>
} code {
$obj clay set this/is Sanity
$obj clay get this/is
> Sanity
$obj clay provenance this/is
> self
}

$obj slide {
<h1 style="text-align: center;">Option Passing</h1>
} code {
$obj clay set config {
  color blue
  flavor blueberry
}
$obj clay get config color
> blue
}


$obj slide {
<h1 style="text-align: center;">Clay Dialect</h1>
Populating clay can get a bit... verbose. To make clay feel more like a
part of oo, Clay includes an oo::dialect.
} code {
clay::define myclass {
  clay set is keyword yes

  # Variable you want initialized
  Variable running 0

  # Dict for which the initial value is a merge of all
  # of the classes in the object
  Dict state {
    running 0
    completed 0
  }
}
}

$obj slide {
<h1 style="text-align: center;">Clay Dialect</h1>
Method Ensembles
} code {
clay::define myclass {
  Ensemble state::get args {
    my variable state
    tailcall dict get $state {*}$args
  }
  Ensemble state::set args {
    my variable state
    dict set state {*}$args
  }
}
}

$obj slide {
<h1 style="text-align: center;">Clay Dialect</h1>
Method Ensembles
} code {
$obj mixin ::myclass
$obj state get running
0
$obj state get notexists
> error "Unknown method notexists, valid: get set"
}


$obj slide {
<h1 style="text-align: center;">Clay Dialect</h1>
Method Ensembles follow interitance
} code {
clay::define ::myotherclass {
  superclass ::myclass
  Ensemble state::notexists args {
    return "It's here"
  }
}
$obj state set running 1
$obj mixin ::myotherclass
$obj state get running
> 1
$obj state get notexists
> It's here
}

$obj slide {
<h1 style="text-align: center;">...End of Prepared Slides</h1>
Live demos or hasty retreat.
}

set fname [file rootname [file tail [info script]]].html
set fout [open $fname w]
puts $fout [$obj html_header {The Clay Framework}]]
puts $fout [$obj assemble]
puts $fout [$obj html_footer]
close $fout
