mSL++ is an object oriented framework for the mIRC scripting language.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Description: This is the base class, which every ;
; class inherits from... ;
; ;
; Usage: $Class(<uID>,<Params>,...).<Member> ;
; Example: var %x $Class ;
; Example: $Class.Delete(%x) ;
; Example: $Class(%x,Name,Some Text).setv ;
; Example: $Class(%x,Name).getv ;
; Example: $Class(%x,Name).removev ;
; Example: $Class.Delete(%x) ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Public Declarations ;
;;;;;;;;;;;;;;;;;;;;;;;
alias Class.DELETE.Public
alias Class.GETV.Public
alias Class.SETV.Public
alias Class.GETB.Public
alias Class.SETB.Public
alias Class.REMV.Public
alias Class.REMB.Public
;;;;;;;;;;;;;;;;;;;;;;;;;;
; Exception Declarations ;
;;;;;;;;;;;;;;;;;;;;;;;;;;
alias Class.EXCEPTION.Null
;;;;;;;;;;;;;;;
; Class Alias ;
;;;;;;;;;;;;;;;
alias Class {
if (!$prop) goto init
if ($IsPublic(Class,$prop)) goto $prop
return $catch(0,MemberErr,$qt($prop) is not a public member of Class)
:init
inc %oop
var %x $Class.INIT($md5($ctime $+ $ticks $+ %oop),Class)
$iif($1,$InheritsFrom($1))
return %x
:delete
return $Class.DELETE($1)
:getv
return $Class.GETV($1,$2)
:setv
return $Class.SETV($1,$2,$3,$4)
:setb
if $bvar($3,0) { return $Class.SETV($1,$2,$3,0,1) }
else { $catch($1,ParamErr,You have specified insufficent parameters) }
return
:getb
if $3 { return $Class.GETV($1,$2,$3) }
else { return $Catch($1,ParamErr,You have specified insufficent parameters) }
:remv
:remb
return $Class.REMOVEV($1,$2,$3)
}
;;;;;;;;;;;;;;;;;
; Class Methods ;
;;;;;;;;;;;;;;;;;
alias Class.IMPORT {
if !$exists(object/) { mkdir object }
if $hget($1,INIT) { return }
hmake $1
hload -b $1 $+(object/,$1.obj)
if $hget($1,INIT) { return $v1 }
return
}
alias Class.EXPORT {
if !$exists(object/) { mkdir object }
hsave -b $1 $+(object/,$1.obj)
return
}
alias Class.COPY {
if !$exists(object/) { mkdir object }
if $IsInstance($1) {
var %x $Class
hsave -b $1 $+(object/,$1.cpy)
hload -b %x $+(object/,$1.cpy)
.remove $+(object/,$1.cpy)
return %x
}
return
}
alias Class.INIT {
hadd -m $1 INIT $2
return $1
}
alias Class.SETV {
var %x $hget($1,$2)
hadd $iif($5,-mb,-m) $1 $2 $3
if $4 { $Object(%x).delete }
return %x
}
alias Class.GETV {
return $iif($3,$hget($1,$2,$3),$hget($1,$2))
}
alias Class.REMOVEV {
var %x $hget($1,$2)
hdel $1 $2
if $3 {
$Object(%x).delete
}
}
alias Class.DELETE {
;;;;;;;;;;;;;;;;;;;;;;
; Do Destroying here ;
;;;;;;;;;;;;;;;;;;;;;;
var %x 1
while $hget($1,%x).data {
var %y $v1
if $isinstance(%y) && $2 { $Object(%y).delete }
inc %x
}
.hfree $1
return
}
;;;;;;;;;;;;;
; End Class ;
;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Description: Returns whether or not a class member ;
; is public. ;
; ;
; Usage: $IsPublic(<Class>,<Member>) ;
; Example: if ($IsInstanceOf(%Player,Player)) .. ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
alias IsPublic return $isalias($+($1.,$2.,Public))
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Description: Called from the class constructor to ;
; let the object know that the specified object ;
; inherits from the specified class ;
; ;
; Usage: $InheritsFrom(<Object>,<Class>) ;
; Example: $InheritsFrom(%instance,Player) ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
alias InheritsFrom hadd -m $1 INIT $2 $hget($1,INIT)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Description: Returns whether or not an instance is ;
; an instance of the specified class ;
; ;
; Usage: $IsInstanceOf(<Instance>,<Class>) ;
; Example: if ($IsInstanceOf(%Player,Player)) .. ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
alias IsInstanceOf return $findtok($hget($1,INIT),$2,0,32)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Description: Returns whether or not an instance ;
; exists in memory ;
; ;
; Usage: $IsInstance(<Instance>) ;
; Example: if (!$IsInstance(%x)) %x = $Player ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
alias IsInstance { return $token($hget($1,INIT),1,32) }
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Description: Called when ever an error is caught ;
; ;
; Usage: $catch(<Instance>,<Error>,<Message>) ;
; Example: if (!$IsInstanceOf(%Player,Player)) { ;
; $catch(%Player,InstanceErr,Object %player is not ;
; an instance of class Player) ;
; } ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
alias Catch {
var %error $2,%message $3,%instance $1
+ Caught $qt(%error) exception: %message
if %instance {
var %x 1,%z $hget($1,INIT)
while $token(%z,%x,32) {
var %y $+($v1,.Exception.,%error)
if $isalias(%y) {
return $($+($,%y,$chr(40),%instance,$chr(44),%message,$chr(41),$chr(32),),2)
}
inc %x
}
}
}
;;;;;;;;;;;;;
; End Catch ;
;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Description: Used to call the first found method ;
; associated with an objects inheritance tree... ;
; ;
; Usage: $Object(<Instance>,..).<Method> ;
; Example: $Object(%stack,$2).add ;
; Equivelent: $List(%stack,$2).add ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
alias Object {
var %x 1,%y $hget($1,INIT),%a ,,
while $token(%y,%x,32) {
var %z $v1
if $isalias(%z $+ . $+ $prop $+ .Public) {
return $($ $+ %z $+ $chr(40) $+ $1 %a $2 %a $3 %a $4 %a $5 %a $6 %a $7 %a $8 %a $9 %a $+ $chr(41) $+ . $+ $prop,2)
}
inc %x
}
$catch($1,MemberErr,$prop is not a public member of $isinstance($1))
}
;;;;;;;;;;;;;;
; End Object ;
;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Description: Exports and object to the hard-drive ;
; to later be loaded with $ImportObject() ;
; ;
; Usage: $ExportObject(<Instance>) ;
; Example: - $ExportObject(%instance) ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
alias ExportObject {
var %x $hget($1,INIT),%y 1
while $token(%x,%y,32) {
var %z $v1 $+ .EXPORT
if $isalias(%z) {
%z $1
}
inc %y
}
if %x { return 1 }
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Description: Imports an exported object into memory ;
; and returns whether or not the operation has completed ;
; successfully ;
; ;
; Usage: $ImportObject(%StoredHandleToExportedObj) ;
; Example: var %imported $ImportObject(%handle) ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
alias ImportObject {
var %x $Class.Import($1)
var %y $numtok(%x,32) - 1
if %x {
while %y {
var %z $token(%x,%y,32) $+ .IMPORT
if $isalias(%z) {
%z $1
}
dec %y
}
return $token(%x,1,32)
}
$Catch(0,ImportErr,Failed to import object $qt($1))
}
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Description: Exports and object to the hard-drive ;
; to later be loaded with $ImportObject() ;
; ;
; Usage: $CopyObject(<Instance>) ;
; Example: var %newInstance $CopyObject(%instance) ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
alias CopyObject {
var %a $Class.Copy($1)
var %x $hget(%a,INIT)
var %y $numtok(%x,32) - 1
if %a {
while %y {
var %z $token(%x,%y,32) $+ .COPY
if $isalias(%z) {
%z $1
}
dec %y
}
return %a
}
$Catch(0,CopyErr,Failed to copy object $qt($1))
}
alias - { !noop $1- }
alias + { $iif($Window(@Debug),echo @Debug,!noop) $1- }
this implementation actually brings all 3 of those aspects of OOP to mIRC
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Description: This class can be used as a simulate a ;
; stack. It inherits from my List class, so any method ;
; that can be used on an list, can also be used on a ;
; stack. ;
; ;
; Usage: $Stack(<uID>,<Params>,...).<Member> ;
; Example: var %itemID = $stack(%x,%text).push ;
; Example: var %text = $stack(%x).pop ;
; Example: var %x $stack(%x).Count ;
; Example: $stack(%x).Clear ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Public Declarations ;
;;;;;;;;;;;;;;;;;;;;;;;
alias Stack.DELETE.Public
alias Stack.Push.Public
alias Stack.Pop.Public
alias Stack.Clear.Public
;;;;;;;;;;;;;;;;;;;;;;;;;;
; Exception Declarations ;
;;;;;;;;;;;;;;;;;;;;;;;;;;
alias Stack.Exception.RangeErr return Out of Bounds!
;;;;;;;;;;;;;;;;;;
; Stack Alias ;
;;;;;;;;;;;;;;;;;;
alias Stack {
if (!$prop) goto init
if ($IsPublic(Stack,$prop)) goto $prop
return $catch($1,MemberErr, $qt($prop) is not a public member of Stack)
:init
return $Stack.INIT($1)
:delete
return $Stack.DELETE($1)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Put your own method handlers here ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
:Push
var %x $list($1,$2).add
return
:Pop
if $list($1).count {
var %y $list($1,$v1).get
$list($1,$v1).remove
return %y
}
return
:Clear
while ($list($1).count) {
$list($1,1).remove
}
return
}
;;;;;;;;;;;;;;;;;;;;
; Stack Methods ;
;;;;;;;;;;;;;;;;;;;;
alias Stack.INIT {
if ($instanceOf($1,list)) return $inheritsFrom($1,Stack)
var %instance $List
$inheritsFrom(%instance,Stack)
;;;;;;;;;;;;;;;;;;;;;;;;
; Do Initializing here ;
;;;;;;;;;;;;;;;;;;;;;;;;
return %instance
}
alias Stack.DELETE {
;;;;;;;;;;;;;;;;;;;;;;
; Do Destroying here ;
;;;;;;;;;;;;;;;;;;;;;;
return $Class($1).DELETE
}
;;;;;;;;;;;;;;;;
; End Stack ;
;;;;;;;;;;;;;;;;
as you can see the Stack class inherits from the List class and List operations can be used on a stack object by using $List(%stackObject,..).listOperation or class operations by using $Class(%stackObject,..).classOperation
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Description: This class can be used as a dynamically sized ;
; List to store any data type ;
; ;
; Usage: $List(<ListPtr>,<Params>,...).<Member> ;
; Example: var %x = $List ;
; Example: var %itemID = $List(%x,$long(500)).add ;
; Example: $List(%x,%itemID,$long(499)).set ;
; Example: $List(%x,%ItemID).remdel ;
; Example: $List(%x).delete ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;;;;;;;;;;
; Public Declarations ;
;;;;;;;;;;;;;;;;;;;;;;;
alias List.DELETE.Public
alias List.Add.PUBLIC
alias List.Remove.PUBLIC
alias List.Get.PUBLIC
alias List.Count.PUBLIC
alias List.Set.PUBLIC
alias List.Remdel.PUBLIC
;;;;;;;;;;;;;;;;;;;;;;;;;;
; Exception Declarations ;
;;;;;;;;;;;;;;;;;;;;;;;;;;
;;;;;;;;;;;;;;
; List Alias ;
;;;;;;;;;;;;;;
alias List {
if (!$prop) goto init
if ($IsPublic(List,$prop)) goto $prop
return $catch($1,MemberErr, $qt($prop) is not a public member of List)
:init
return $List.INIT($1)
:delete
return $List.DELETE($1,$2)
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Put your own method handlers here ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
:MethodHandler
:add
return $List.Add($1,$2)
:Remdel
:Remove
return $List.Remove($1,$2)
:get
return $List.Get($1,$2)
:count
return $hget($1,COUNT)
:set
return $List.Set($1,$2,$3)
}
;;;;;;;;;;;;;;;;
; List Methods ;
;;;;;;;;;;;;;;;;
alias List.INIT {
var %instance $Class
$inheritsFrom(%instance,List)
;;;;;;;;;;;;;;;;;;;;;;;;
; Do Initializing here ;
;;;;;;;;;;;;;;;;;;;;;;;;
return %instance
}
alias List.REMOVE {
if $2 !isnum 1- $+ $hget($1,COUNT) { return $catch($1,RangeErr,$qt($2) is not a valid list index for object $qt($1)) }
hdec $1 COUNT
- $Class($1,ITEMS,&items).getb
var %x $calc(1 + (($2 - 1) * 32)),%y %x + 32,%z $bvar(&items,%x,32).text
if %y > $bvar(&items,0) { dec %y }
var %var $bvar(&items,%x,32).text
bcopy -c &items %x &items %y -1
- $Class($1,%var).remv
- $Class($1,ITEMS,&items).setb
}
alias List.ADD {
hinc $1 COUNT
hinc $1 TOTAL
var %x $md5($hget($1,TOTAL))
- $Class($1,ITEMS,&items).getb
bset -t &items $calc(1 + (($hget($1,COUNT) - 1) * 32)) %x
- $Class($1,ITEMS,&items).setb
- $iif($bvar($2,0),$Class($1,%x,$2).setb,$Class($1,%x,$2).setv)
return $hget($1,Count)
}
alias List.GET {
if $2 !isnum 0- $+ $hget($1,COUNT) { return $catch($1,RangeErr,$qt($2) is not a valid list index for object $qt($1) $chr(40) $+ Valid Ranges: 1- $+ $hget($1,COUNT) $+ $chr(41)) }
$iif($2 == 0,return $hget($1,COUNT))
- $hget($1,ITEMS,&items)
var %var2 $bvar(&items,$calc(1 + (($2 - 1) * 32)),32).text
return $hget($1,%var2)
}
alias List.SET {
var %z $bvar(&items,$calc(1 + (($2 - 1) * 32)),32).text
var %x $Class($1,%z).getv
if $IsInstance(%x) { noop $Object(%x).delete }
- $Class($1,%z,$3).setv
}
alias List.IMPORT {
var %x $List($1).count
while %x {
if $ImportObject($List($1,%x).get) {
+ Loaded object $qt($List($1,%x).get) of type $qt($IsInstance($List($1,%x).get))
}
dec %x
}
if $exists($+(object/,$1.bvr)) {
bread $+(object/,$1.bvr) 1 $file($+(object/,$1.bvr)).size &data
- $Class($1,ITEMS,&data).setb
}
}
alias List.EXPORT {
var %x $List($1).count
while %x {
var %y $List($1,%x).get
if $IsInstance(%y) {
- $ExportObject(%y)
+ Saved object $qt($List($1,%x).get)
}
dec %x
}
- $Class($1,ITEMS,&data).getb
if $exists($+(object/,$1.bvr)) {
.remove $+(object/,$1.bvr)
}
bwrite $+(object/,$1.bvr) 1 -1 &data
}
alias List.DELETE {
;;;;;;;;;;;;;;;;;;;;;;
; Do Destroying here ;
;;;;;;;;;;;;;;;;;;;;;;
- $Class($1,ITEMS).remv
- $Class($1,TOTAL).remv
- $Class($1,COUNT).remv
if $2 {
while $hget($1,1).item {
var %y $v1
var %x $hget($1,%y)
if $IsInstance(%x) {
- $Object(%x,1).delete
+ Removed object: $qt(%x) from list $qt($1)
}
- $Class($1,%y).remv
}
}
return $Class($1).DELETE
}
;;;;;;;;;;;;
; End List ;
;;;;;;;;;;;;
Here's an example of opening a socket and handeling socket events