pretty simple, wrote in under hour, but I wanted to share this piece for anyone that does something like I did with chat modes and dont want to write 100 additional lines of code
Example:
JASS:
library StringIterator
/*
Made by: edo494
Version: 1.0
Description:
This piece of code allows you to forward iterate over words in strings,
reading them out from the "container" depending on the delimiter.
API:
struct StringIterator
static method create takes string container returns thistype
- creates new instance
method setDelims takes string delimiters returns nothing
- sets the delimiters to characters in "delimiters"
- example: "abc" will make the instance treat any
a, b or c inside the string as delimiter
method read takes nothing returns string
- returns string containing charaters from "position"
up to "end" or until any delimiter is found
method peek takes nothing returns string
- returns string containing charaters from "position"
up to "end" or until any delimiter is found
- does not move "position" forward
method nextDelim takes nothing returns string
- returns upcomming delimiter pack
- so if 2 or more delimiters after each other occur
this function returns all of them
method operator string= takes string newContainer returns nothing
- sets internal container to "newContainer"
- call to this function resets position
method operator start takes nothing returns boolean
- returns whether the iterator is at the start or not
method operator end takes nothing returns boolean
- returns whether the iterator is at the end or not
method operator size takes nothing returns integer
- returns number of charaters inside the container
method operator position takes nothing returns integer
- returns the current position of the iterator inside container
method operator position= takes integer newPos returns boolean
- sets the position to the "newPos"
- in debug mode, if <0 or >size, returns false
otherwise true
- outside of debug mode, returns true
method reset takes nothing returns nothing
- returns the iterator to start
*/
struct StringIterator
private string myStr
private string myDelims
private integer pointer
private integer sSize
private integer dSize
static method create takes string s returns thistype
local thistype this = allocate()
set this.myStr = s
set this.myDelims = " "
set this.pointer = 0
set this.dSize = StringLength(this.myDelims)
set this.sSize = StringLength(s)
return this
endmethod
static method createEx takes string container, string delims returns thistype
local thistype this = allocate()
set this.myStr = container
set this.myDelims = delims
set this.pointer = 0
set this.dSize = StringLength(delims)
set this.sSize = StringLength(container)
return this
endmethod
method setDelims takes string s returns nothing
set this.myDelims = s
set this.dSize = StringLength(s)
endmethod
method operator start takes nothing returns boolean
return this.pointer <= 0
endmethod
method operator end takes nothing returns boolean
return this.pointer >= this.sSize
endmethod
method operator size takes nothing returns integer
return this.sSize
endmethod
method operator position takes nothing returns integer
return this.pointer
endmethod
private method isDelim takes string s returns boolean
local integer i = this.dSize
local string delims = this.myDelims
if s == null then
return true
endif
loop
exitwhen i == 0
if s == SubString(delims, i-1, i) then
return true
endif
set i = i - 1
endloop
return false
endmethod
private method readBool takes boolean b returns string
local string helper = ""
local string ths = this.myStr
local integer size = this.sSize
local integer current = this.pointer
local string cont = ""
//evade all remaining delimiters from the last read
loop
if current == size then
exitwhen true
endif
exitwhen not isDelim(SubString(ths, current, current+1))
set current = current + 1
endloop
//fill up the string
loop
exitwhen current == size
set helper = SubString(ths, current, current+1)
exitwhen isDelim(helper)
set cont = cont + helper
set current = current + 1
endloop
if b then
set this.pointer = current
endif
//return the string
return cont
endmethod
method read takes nothing returns string
return readBool(true)
endmethod
method peek takes nothing returns string
return readBool(false)
endmethod
method nextDelim takes nothing returns string
local string ths = this.myStr
local integer size = this.sSize
local integer current = this.pointer
local string s = ""
local string q = ""
if current == size then
return ""
endif
//evade all non delimiters
loop
set q = SubString(ths, current, current+1)
exitwhen current == size or not isDelim(q)
set current = current + 1
endloop
//read next delimiters
loop
set q = SubString(ths, current, current+1)
exitwhen current == size or not isDelim(q)
set s = s + q
set current = current + 1
endloop
//return them
return s
endmethod
method operator position= takes integer newPosition returns boolean
debug if newPosition > this.size or newPosition < 0 then
debug return false
debug endif
set this.pointer = newPosition
return true
endmethod
method reset takes nothing returns nothing
set this.pointer = 0
endmethod
method operator string= takes string s returns nothing
set this.myStr = s
set this.sSize = StringLength(s)
set this.pointer = 0
endmethod
endstruct
endlibrary
Example:
JASS:
scope example initializer init
private function t takes nothing returns boolean
local string s = GetEventPlayerChatString()
local StringIterator iter = StringIterator.create(s)
call iter.setDelims(" ")
call BJDebugMsg("Message inserted by player:\n")
loop
exitwhen iter.end
call BJDebugMsg(iter.read())
endloop
return false
endfunction
private function init takes nothing returns nothing
local trigger tr = CreateTrigger()
call TriggerRegisterPlayerChatEvent(tr, Player(0), "", false)
call TriggerAddCondition(tr, Condition(function t))
set tr = null
endfunction
endscope
Last edited: