Sean Woods
Dynamic web content | |
A Tcl based make system | |
Gaming/Chatbots/AI |
Dynamic web content | Httpd / Toadhttpd |
A Tcl based make system | Practcl |
Gaming/Chatbots/AI | The Epic of Gilgamesh (Under Development) |
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 }
Practcl is a Tcl based make system. It can generate Tclkits, binary libaries, pure-tcl modules, and large collections of pure-tcl packages.
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]
Player | Yes | |
Species | Human | |
Gender | Male | |
Class | Wizard |
Player | Yes | ::gilgamesh::core/avatar | |
Species | Human | ::gilgamesh::species/human | |
Gender | Male | ::gilgamesh::gender/male | |
Class | Wizard | ::gilgamesh::class/wizard |
# 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]
The clay method manages all of the interactions with the framework.
ALL OF THEM
And in the class
And all of the mixins
And all of the ancestors of the class and the mixins
::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
::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 clay set this is Sanity $obj clay get this is > Sanity
$obj clay get this > means something is madness ### # SHOULD HAVE BEEN ### > means something is Sanity
Doing it properly... well.... my tests are getting longer than the implementation.
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]
# 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 clay provenance this/means > ::foo $obj clay provenance this/is > ::bar $obj ancestors ::bar ::foo ::oo::class
$obj clay set this/is Sanity $obj clay get this/is > Sanity $obj clay provenance this/is > self
$obj clay set config { color blue flavor blueberry } $obj clay get config color > blue
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 } }
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 mixin ::myclass $obj state get running 0 $obj state get notexists > error "Unknown method notexists, valid: get set"
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