December 03, 2020, 08:44:00 PM

Author Topic: [bmx] Console by N [ 1+ years ago ]  (Read 703 times)

Offline BlitzBot

  • Jr. Member
  • **
  • Posts: 1
[bmx] Console by N [ 1+ years ago ]
« on: June 29, 2017, 12:28:43 AM »
Title : Console
Author : N
Posted : 1+ years ago

Description : This does not handle displaying a console.  That's your job.  What this is is a simple system for registering cvars (console variables, for those less inclined to think) and console commands (e.g., in Doom 3, "/vid_restart").

I've tried to document the functions relatively simply, although it's not using bbdoc since this isn't a module and I don't really care.  For a simple example, see this:
Code: [Select]
Import "console.bmx"

Function test%( n$, l$ )
    Print "Console printed: "+l
End Function

RegisterConCommand( "test", test )

CallConsole( "/test foobaz" )
CallConsole( "testing" )

Print GetConsoleLog()


There is a basic framework for handling script callbacks, but since I cannot predict what interpreter you will use or how it handles callbacks, I've left that out.  You would insert this pretty much at the very end of CallConsole, where it looks like I've put an example of how I do it. [/i]

Code :
Code: BlitzMax
  1. SuperStrict
  2.  
  3. Import Brl.LinkedList
  4. Import Brl.Map
  5.  
  6. Private
  7.  
  8. Global ConsoleMap:TMap = New TMap
  9. Global ConsoleLog:TList = New TList
  10.  
  11. Public
  12. ' If a cvar is set, this hook is called
  13. ' useful for monitoring in-game/engine changes
  14. Global CVarSetHookID% = AllocHookID( )
  15. ' If anything is written to the console log, this hook is called
  16. ' useful for sending console messages to the debuglog, for example
  17. Global ConsolePrintHookID% = AllocHookID( )
  18.  
  19. Private
  20. Type ICVar
  21.     Field _name$        ' name
  22.     Field _value$       ' current value
  23.     Field _readonly%    ' read-only?
  24.     Field _system%      ' system/important?
  25.     Field _script%=2    ' set from the script?  2 = set by the engine, but not system, and can be modified by script, 1 = (now a?) script variable, 0 = not.
  26. End Type
  27.  
  28. Type ICCmd
  29.     Field _name$ ' Name
  30.     Field _callback:Int( n$, l$ )=Null ' Engine callback pointer
  31.     Field _scallback$="" ' Script callback name
  32.     Field _script%=0 ' Is a script callback?
  33.     Field _system%=0 ' Is a system/important callback?
  34. End Type
  35.  
  36. ' Not exaclty unicode-friendly thanks to Chr
  37. Function Strip( s$ Var, p$, replaceWith$="" )
  38.     Local q$ = s$
  39.     s = ""
  40.     For Local i:Int = 0 To q.Length-1
  41.         Local c$ = Chr(q[i])
  42.         If p.Find(c)>-1 Then c = replaceWith
  43.         s :+ c
  44.     Next
  45. End Function
  46.  
  47. Public
  48.  
  49. ' Register a console command/callback
  50. ' name is the name of the command, obviously
  51. ' cb is the function callback, null if script is true
  52. ' system specifies whether or not it is a core/system callback (e.g., important to the function of the entire system), true/false
  53. ' script specifies whether or not it uses the script callback, true/false
  54. ' sb is the script callback, for instances where an interpreter handles the callback
  55. Function RegisterConCommand( name$, cb:Int( n$, cmd$ ), system%=0, script%=0, sb$="" )
  56.     name = name.ToLower( )
  57.     Strip(name,"/;'~q.,[]():~~`-{}|?<>*&^%$#@!+=~n~r~t ","")
  58.     If name.Length = 0 Then Return
  59.  
  60.     Local value:Object = ConsoleMap.ValueForKey( name )
  61.     Local c:ICCmd = ICCmd(value)
  62.  
  63.     If c Then
  64.         If c._system Then
  65.             ConPrint( "Cannot overwrite system console command" )
  66.             Return
  67.         EndIf
  68.         If (cb = Null And script=0) Or (script=1 And sb.Length=0) Then
  69.             ConsoleMap.Remove( name )
  70.             Return
  71.         EndIf
  72.         c._callback = cb
  73.         Return
  74.     ElseIf Not cb Or value Then
  75.         Return
  76.     EndIf
  77.  
  78.     c = New ICCmd
  79.     c._name = name
  80.     c._callback = cb
  81.     c._script = script
  82.     c._system = system
  83.  
  84.     ConsoleMap.Insert( name, c )
  85. End Function
  86.  
  87. ' handles a call to the console
  88. ' messages that do not begin with / are interpreted as wanting to just write msg to the console log
  89. Function CallConsole( msg$ )
  90.     Strip(msg,"~n~r~t","")
  91.     If msg[0] <> "/"[0] Then
  92.         ConPrint( msg )
  93.         Return
  94.     EndIf
  95.    
  96.     Local sp:Int = msg.Find(" ")
  97.     If sp = -1 Then
  98.         sp = msg.Length
  99.     ElseIf sp = 1 Then
  100.         ConPrint( "Invalid console command" )
  101.         Return
  102.     EndIf
  103.  
  104.     Local name$ = msg[1..sp].Trim( ).ToLower( )
  105.     Strip(name,"/;'~q.,[]():~~`-{}|?<>*&^%$#@!+=","")
  106.     If name.Length = 0 Then
  107.         ConPrint( "Invalid console command" )
  108.         Return
  109.     EndIf
  110.  
  111.     Local value:Object = ConsoleMap.ValueForKey( name )
  112.     Local c:ICCmd = ICCmd(value)
  113.  
  114.     If c = Null Then
  115.         If sp = msg.Length Then
  116.             'ConPrint( FormatString("$1 = ~q$2~q", [name, GetCVar(name)]) )
  117.             ConPrint( name+" = ~q"+GetCVar(name)+"~q" )
  118.         Else
  119.             Local val$ = msg[sp..].Trim( )
  120.             'ConPrint( FormatString("set $1 ~q$2~q", [name, val]) )
  121.             SetCvar( name, val )
  122.             ConPrint( name+" = ~q"+GetCVar(name)+"~q" )
  123.         EndIf
  124.         Return
  125.     ElseIf c._script = 0 Then
  126.         c._callback( name, msg[sp..].Trim( ) )
  127.     Else
  128.         Rem
  129.         IScript.PushString( name )
  130.         IScript.PushString( msg[sp..].Trim( ) )
  131.         IScript.Call( c._scallback, 2, 0 )
  132.         EndRem
  133.         ' You'll have to insert how you handle script callbacks here.  I'm not responsible for it.
  134.     EndIf
  135. End Function
  136.  
  137. ' gets a cvar
  138. ' n is the name of the cvar, d is a default value to give the cvar if it does not exist
  139. ' passing null to d will not create a cvar in the event that n doesn't exist
  140. Function GetCVar$( n$, d$=Null )
  141.     Strip(n, "/;'~q.,[]():~~`-{}|?<>*&^%$#@!+=~n~r~t ", "")
  142.     n = n.ToLower( ).Trim( )
  143.  
  144.     Local value:Object = ConsoleMap.ValueForKey( n )
  145.     Local c:ICvar = ICVar(value)
  146.  
  147.     If Not c And d.Length>0 And Not value And d Then
  148.         SetCVar( n, d )
  149.         Return GetCVar(n)
  150.     ElseIf Not c
  151.         Return ""
  152.     Else
  153.         Return c._value
  154.     EndIf
  155. End Function
  156.  
  157. ' n is the name of the cvar
  158. ' v is the value- if the cvar already exists and v is null, the cvar is deleted
  159. ' readonly specifies whether or not calls to the console can modify the cvar (via CallConsole)
  160. ' fromScript specifies whether or not SetCVar is being called from a script function
  161. ' + in the event that the cvar does not already exist and fromScript is true, the cvar is created as a script cvar
  162. ' + (this is relatively meaningless unless you implement a way to save cvars)
  163. ' system specifies whether or not the cvar is a system/core/important cvar, roughly the same as specifying read-only
  164. ' + except that read-only cvars would not be saved in something like autoexec.cfg
  165. Function SetCVar( n$, v$, readonly%=-1, fromScript%=-1, system%=-1 )
  166.     n = n.ToLower( ).Replace("","").Trim( )
  167.     Strip(n, "/;'~q.,[]():~~`-{}|?<>*&^%$#@!+=~n~r~t ", "")
  168.  
  169.     Local value:Object = ConsoleMap.ValueForKey( n )
  170.     Local c:ICvar = ICVar(value)
  171.  
  172.     If Not c And Not value And v Then
  173.         c = New ICVar
  174.         c._name = n
  175.         ConsoleMap.Insert( n, c )
  176.     ElseIf Not c Then
  177.         Return
  178.     ElseIf Not v And c Then
  179.         ConsoleMap.Remove( n )
  180.         Return
  181.     EndIf
  182.  
  183.     If c._readonly And fromScript Then
  184.         ConPrint( n+" is a read-only cvar and cannot be overwritten" )
  185.         Return
  186.     EndIf
  187.    
  188.     Strip(v, "~t~n~r~0", "")
  189.     c._value = v
  190.     If readonly<>-1 Then c._readonly = readonly
  191.     If system<>-1 Then c._system = system
  192.     If c._script = 2 And fromScript <> -1 Then c._script = fromScript
  193.  
  194.     RunHooks( CVarSetHookID, [c._name,c._value] )
  195. End Function
  196.  
  197. ' deletes non-system cvars if force is zero, deletes all cvars if force is true
  198. Function FlushCVars( force%=0 )
  199.     For Local i:ICvar = EachIn ConsoleMap.Values()
  200.         If Not i._system Or force Then ConsoleMap.Remove( i._name )
  201.     Next
  202. End Function
  203.  
  204. ' deletes non-system commands if force is zero, deletes all commands if force is true
  205. Function FlushConCommands( force%=0 )
  206.     For Local i:ICvar = EachIn ConsoleMap.Values()
  207.         If Not i._system Or force Then ConsoleMap.Remove( i._name )
  208.     Next
  209. End Function
  210.  
  211. ' clears the console log (messages logged by ConPrint
  212. Function ClearConsole( )
  213.     ConsoleLog.Clear( )
  214. End Function
  215.  
  216. ' retrieves the console log as a string (useful for writing the log to a file)
  217. Function GetConsoleLog$( )
  218.     Local s$ = ""
  219.     For Local i$ = EachIn ConsoleLog
  220.         s :+ i + "~n"
  221.     Next
  222.     Return s.Trim()
  223. End Function
  224.  
  225. ' retrieves the console log in reverse as an array of strings (useful for displaying the console)
  226. Function ReverseConsoleArray$[]( )
  227.     Local obj:Object[] = (ConsoleLog.Reversed( ).ToArray( ))
  228.     Local arr:String[obj.Length]
  229.     For Local i:Int = 0 To arr.Length-1
  230.         arr[i] = obj[i].ToString()
  231.     Next
  232.     Return arr
  233. End Function
  234.  
  235. ' writes a message to the console log
  236. Function ConPrint( s$ )
  237.     Strip( s, "~r~t", "")
  238.     Local sp$[] = s.Split("~n")
  239.     Local i%
  240.     For i = sp.Length-1 To 0 Step -1
  241.         ConsoleLog.AddLast( sp[i] )
  242.     Next
  243.     RunHooks( ConsolePrintHookID, s )
  244. End Function
  245.  
  246. ' displays all cvars and their values in the console
  247. Function ListCVars( )
  248.     For Local i:ICVar = EachIn ConsoleMap.Values( )
  249.         ConPrint( "~q"+i._name+"~q = ~q"+i._value+"~q" )
  250.     Next
  251. End Function
  252.  
  253. ' lists all console commands in the console
  254. Function ListCommands( )
  255.     For Local i:ICCmd = EachIn ConsoleMap.Values( )
  256.         ConPrint( "~q"+i._name+"~q" )
  257.     Next
  258. End Function
  259.  
  260. ' resets the console to an initial state
  261. Function ResetConsole( )
  262.     FlushConCommands( True )
  263.     FlushCVars( True )
  264.     RegisterConCommand( "listcommands", clistCommands, 1 )
  265.     RegisterConCommand( "listcvars", clistCvars, 1 )
  266.     RegisterConCommand( "clear", cclearConsole, 1 )
  267.     ClearConsole( )
  268. End Function
  269.  
  270. Private
  271.  
  272. Function clistCommands%( n$, s$ )
  273.     ListCommands( )
  274. End Function
  275.  
  276. Function clistCvars%( n$, s$ )
  277.     ListCvars( )
  278. End Function
  279.  
  280. Function cclearConsole%( n$, s$ )
  281.     ClearConsole( )
  282. End Function
  283.  
  284. ResetConsole()


Comments : none...

 

SimplePortal 2.3.6 © 2008-2014, SimplePortal