SHARE
TWEET

Untitled

a guest Feb 18th, 2013 1,328 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. //========== Copyright © 2008, Valve Corporation, All rights reserved. ========
  2. //
  3. // Purpose: Script initially run after squirrel VM is initialized
  4. //
  5. //=============================================================================
  6.  
  7. //-----------------------------------------------------------------------------
  8. // General
  9. //-----------------------------------------------------------------------------
  10.  
  11. function printl( text )
  12. {
  13.         return print( text + "\n" );
  14. }
  15.  
  16. function Msg( text )
  17. {
  18.         return print( text );
  19. }
  20.  
  21. function Assert( b, msg = null )
  22. {
  23.         if ( b )
  24.                 return;
  25.                
  26.         if ( msg != null )
  27.         {
  28.                 throw "Assertion failed: " + msg;
  29.         }
  30.         else
  31.         {
  32.                 throw "Assertion failed";
  33.         }
  34. }
  35.  
  36. //-----------------------------------------------------------------------------
  37. // Documentation table
  38. //-----------------------------------------------------------------------------
  39.  
  40. if ( developer() > 0 )
  41. {
  42.         Documentation <-
  43.         {
  44.                 classes = {}
  45.                 functions = {}
  46.                 instances = {}
  47.         }
  48.  
  49.  
  50.         function RetrieveNativeSignature( nativeFunction )
  51.         {
  52.                 if ( nativeFunction in NativeFunctionSignatures )
  53.                 {
  54.                         return NativeFunctionSignatures[nativeFunction]
  55.                 }
  56.                 return "<unnamed>"
  57.         }
  58.        
  59.         function RegisterFunctionDocumentation( func, name, signature, description )
  60.         {
  61.                 if ( description.len() )
  62.                 {
  63.                         local b = ( description[0] == '#' );
  64.                         if ( description[0] == '#' )
  65.                         {
  66.                                 local colon = description.find( ":" );
  67.                                 if ( colon == null )
  68.                                 {
  69.                                         colon = description.len();
  70.                                 }
  71.                                 local alias = description.slice( 1, colon );
  72.                                 description = description.slice( colon + 1 );
  73.                                 name = alias;
  74.                                 signature = "#";
  75.                         }
  76.                 }
  77.                 Documentation.functions[name] <- [ signature, description ]
  78.         }
  79.  
  80.         function Document( symbolOrTable, itemIfSymbol = null, descriptionIfSymbol = null )
  81.         {
  82.                 if ( typeof( symbolOrTable ) == "table" )
  83.                 {
  84.                         foreach( symbol, itemDescription in symbolOrTable )
  85.                         {
  86.                                 Assert( typeof(symbol) == "string" )
  87.                                
  88.                                 Document( symbol, itemDescription[0], itemDescription[1] );
  89.                         }
  90.                 }
  91.                 else
  92.                 {
  93.                         printl( symbolOrTable + ":" + itemIfSymbol.tostring() + "/" + descriptionIfSymbol );
  94.                 }
  95.         }
  96.        
  97.         function PrintHelp( string = "*", exact = false )
  98.         {
  99.                 local matches = []
  100.                
  101.                 if ( string == "*" || !exact )
  102.                 {
  103.                         foreach( name, documentation in Documentation.functions )
  104.                         {
  105.                                 if ( string != "*" && name.tolower().find( string.tolower() ) == null )
  106.                                 {
  107.                                         continue;
  108.                                 }
  109.                                
  110.                                 matches.append( name );
  111.                         }
  112.                 }
  113.                 else if ( exact )
  114.                 {
  115.                         if ( string in Documentation.functions )
  116.                                 matches.append( string )
  117.                 }
  118.                
  119.                 if ( matches.len() == 0 )
  120.                 {
  121.                         printl( "Symbol " + string + " not found" );
  122.                         return;
  123.                 }
  124.                
  125.                 matches.sort();
  126.                
  127.                 foreach( name in matches )
  128.                 {
  129.                         local result = name;
  130.                         local documentation = Documentation.functions[name];
  131.                        
  132.                         printl( "Function:    " + name );
  133.                         local signature;
  134.                         if ( documentation[0] != "#" )
  135.                         {
  136.                                 signature = documentation[0];
  137.                         }
  138.                         else
  139.                         {
  140.                                 signature = GetFunctionSignature( this[name], name );
  141.                         }
  142.                        
  143.                         printl( "Signature:   " + signature );
  144.                         if ( documentation[1].len() )
  145.                                 printl( "Description: " + documentation[1] );
  146.                         print( "\n" );
  147.                 }
  148.         }
  149. }
  150. else
  151. {
  152.         function RetrieveNativeSignature( nativeFunction ) { return "<unnamed>"; }
  153.         function Document( symbolOrTable, itemIfSymbol = null, descriptionIfSymbol = null ) {}
  154.         function PrintHelp( string = "*", exact = false ) {}
  155. }
  156.  
  157. //-----------------------------------------------------------------------------
  158. // VSquirrel support functions
  159. //-----------------------------------------------------------------------------
  160.  
  161. function VSquirrel_OnCreateScope( name, outer )
  162. {
  163.         local result;
  164.         if ( !(name in outer) )
  165.         {
  166.                 result = outer[name] <- { __vname=name, __vrefs = 1 };
  167.                 delegate outer : result;
  168.         }
  169.         else
  170.         {
  171.                 result = outer[name];
  172.                 result.__vrefs += 1;
  173.         }
  174.         return result;
  175. }
  176.  
  177. function VSquirrel_OnReleaseScope( scope )
  178. {
  179.         scope.__vrefs -= 1;
  180.         if ( scope.__vrefs < 0 )
  181.         {
  182.                 throw "Bad reference counting on scope " + scope.__vname;
  183.         }
  184.         else if ( scope.__vrefs == 0 )
  185.         {
  186.                 delete scope.parent[scope.__vname];
  187.                 scope.__vname = null;
  188.                 delegate null : scope;
  189.         }
  190. }
  191.  
  192.  
  193. //-----------------------------------------------------------------------------
  194. //
  195. //-----------------------------------------------------------------------------
  196. class CCallChainer
  197. {
  198.         constructor( prefixString, scopeForThis = null )
  199.         {
  200.                 prefix = prefixString;
  201.                 if ( scopeForThis != null )
  202.                         scope = scopeForThis;
  203.                 else
  204.                         scope = ::getroottable();
  205.                 chains = {};
  206.                
  207.                 // Expose a bound global function to dispatch to this object
  208.                 scope[ "Dispatch" + prefixString ] <- Call.bindenv( this );
  209.         }
  210.        
  211.         function PostScriptExecute()
  212.         {
  213.                 foreach( key, value in scope )
  214.                 {
  215.                         if ( typeof( value ) == "function" )
  216.                         {
  217.                                 if ( key.find( prefix ) == 0 )
  218.                                 {
  219.                                         key = key.slice( prefix.len() );
  220.                                        
  221.                                         if ( !(key in chains) )
  222.                                         {
  223.                                                 //::print( "Creating new call chain " + key + "\n");
  224.                                                 chains[key] <- [];
  225.                                         }
  226.                                        
  227.                                         local chain = chains[key];
  228.                                        
  229.                                         if ( !chain.len() || chain.top() != value )
  230.                                         {
  231.                                                 chain.push( value );
  232.                                                 //::print( "Added " + value + " to call chain " + key + "\n" );
  233.                                         }
  234.                                 }
  235.                         }
  236.                 }
  237.         }
  238.        
  239.         function Call( event, ... )
  240.         {
  241.                 if ( event in chains )
  242.                 {
  243.                         local chain = chains[event];
  244.                         if ( chain.len() )
  245.                         {
  246.                                 local i;
  247.                                 local args = [];
  248.                                 if ( vargc > 0 )
  249.                                 {
  250.                                         args.push( scope );
  251.                                         for ( i = 0; i < vargc; i++ )
  252.                                         {
  253.                                                 args.push( vargv[i] );
  254.                                         }
  255.                                 }
  256.                                 for ( i = chain.len() - 1; i >= 0; i -= 1 )
  257.                                 {
  258.                                         local func = chain[i];
  259.                                         local result;
  260.                                         if ( !args.len() )
  261.                                         {
  262.                                                 result = func();
  263.                                         }
  264.                                         else
  265.                                         {
  266.                                                 result = func.acall( args );
  267.                                         }
  268.                                         if ( result != null && !result )
  269.                                                 return false;
  270.                                 }
  271.                         }
  272.                 }
  273.                
  274.                 return true;
  275.         }
  276.        
  277.         scope = null;
  278.         prefix = null;
  279.         chains = null;
  280. };
  281.  
  282.  
  283. //-----------------------------------------------------------------------------
  284. //
  285. //-----------------------------------------------------------------------------
  286. class CSimpleCallChainer
  287. {
  288.         constructor( prefixString, scopeForThis = null, exactNameMatch = false )
  289.         {
  290.                 prefix = prefixString;
  291.                 if ( scopeForThis != null )
  292.                         scope = scopeForThis;
  293.                 else
  294.                         scope = ::getroottable();
  295.                 chain = [];
  296.                
  297.                 // Expose a bound global function to dispatch to this object
  298.                 scope[ "Dispatch" + prefixString ] <- Call.bindenv( this );
  299.                
  300.                 exactMatch = exactNameMatch
  301.         }
  302.        
  303.         function PostScriptExecute()
  304.         {
  305.                 foreach( key, value in scope )
  306.                 {
  307.                         if ( typeof( value ) == "function" )
  308.                         {
  309.                                 local foundMatch = false;
  310.                                 if ( exactMatch )
  311.                                 {
  312.                                         foundMatch = ( prefix == key );
  313.                                 }
  314.                                 else
  315.                                 {
  316.                                         foundMatch = ( key.find( prefix ) == 0 )
  317.                                 }
  318.                                                
  319.                                 if ( foundMatch )
  320.                                 {
  321.                                         if ( !exactMatch )
  322.                                                 key = key.slice( prefix.len() );
  323.                                        
  324.                                         if ( !(chain) )
  325.                                         {
  326.                                                 //::print( "Creating new call simple chain\n");
  327.                                                 chain <- [];
  328.                                         }
  329.                                        
  330.                                         if ( !chain.len() || chain != value )
  331.                                         {
  332.                                                 chain.push( value );
  333.                                                 //::print( "Added " + value + " to call chain.\n" );
  334.                                         }
  335.                                 }
  336.                         }
  337.                 }
  338.         }
  339.        
  340.         function Call( ... )
  341.         {
  342.                 if ( chain.len() )
  343.                 {
  344.                         local i;
  345.                         local args = [];
  346.                         if ( vargc > 0 )
  347.                         {
  348.                                 args.push( scope );
  349.                                 for ( i = 0; i < vargc; i++ )
  350.                                 {
  351.                                         args.push( vargv[i] );
  352.                                 }
  353.                         }
  354.                         for ( i = chain.len() - 1; i >= 0; i -= 1 )
  355.                         {
  356.                                 local func = chain[i];
  357.                                 local result;
  358.                                 if ( !args.len() )
  359.                                 {
  360.                                         result = func.pcall( scope );
  361.                                 }
  362.                                 else
  363.                                 {
  364.                                         result = func.pacall( scope, args );
  365.                                 }
  366.                                 if ( result != null && !result )
  367.                                         return false;
  368.                         }
  369.                 }
  370.                
  371.                 return true;
  372.         }
  373.        
  374.         exactMatch = false
  375.         scope = null;
  376.         prefix = null;
  377.         chain = null;
  378. };
  379.  
  380. //-----------------------------------------------------------------------------
  381. // Late binding: allows a table to refer to parts of itself, it's children,
  382. // it's owner, and then have the references fixed up after it's fully parsed
  383. //
  384. // Usage:
  385. //    lateBinder <- LateBinder();
  386. //    lateBinder.Begin( this );
  387. //    
  388. //    Test1 <-
  389. //    {  
  390. //         Foo=1
  391. //    }  
  392. //    
  393. //    Test2 <-
  394. //    {  
  395. //         FooFoo = "I'm foo foo"
  396. //         BarBar="@Test1.Foo"
  397. //         SubTable = { boo=[bah, "@Test2.FooFoo", "@Test1.Foo"], booboo2={one=bah, two="@Test2.FooFoo", three="@Test1.Foo"} }
  398. //         booboo=[bah, "@Test2.FooFoo", "@Test1.Foo"]
  399. //         booboo2={one=bah, two="@Test2.FooFoo", three="@Test1.Foo"}
  400. //         bah=wha
  401. //    }  
  402. //    
  403. //    lateBinder.End();
  404. //    delete lateBinder;
  405. //
  406. // When End() is called, all of the unresolved symbols in the tables and arrays will be resolved,
  407. // any left unresolved will become a string prepended with '~', which later code can deal with
  408. //-----------------------------------------------------------------------------
  409.  
  410. class LateBinder
  411. {
  412.         // public:
  413.         function Begin( target, log = false )
  414.         {
  415.                 m_log = log;
  416.                
  417.                 HookRootMetamethod( "_get", function( key ) { return "^" + key; } );
  418.                 HookRootMetamethod( "_newslot", function( key, value ) { if ( typeof value == "table" ) { m_fixupSet.push( [ key, value ] ); this.rawset( key, value ); };  }.bindenv(this) );
  419.                 m_targetTable = target;
  420.                
  421.                 Log( "Begin late bind on table " + m_targetTable );
  422.         }
  423.        
  424.         function End()
  425.         {
  426.                 UnhookRootMetamethod( "_get" );
  427.                 UnhookRootMetamethod( "_newslot" );
  428.  
  429.                 Log( "End late bind on table " + m_targetTable );
  430.                
  431.                 foreach( subTablePair in m_fixupSet )
  432.                 {
  433.                         EstablishDelegation( m_targetTable, subTablePair[1] );
  434.                 }
  435.  
  436.                 Log( "Begin resolution... " )
  437.                 m_logIndent++;
  438.                
  439.                 local found = true;
  440.                
  441.                 while ( found )
  442.                 {
  443.                         foreach( subTablePair in m_fixupSet )
  444.                         {
  445.                                 Log( subTablePair[0] + " = " );
  446.                                 Log( "{" );
  447.                                 if ( !Resolve( subTablePair[1], subTablePair[1], false ) )
  448.                                 {
  449.                                         found = false;
  450.                                 }
  451.                                 Log( "}" );
  452.                         }
  453.                 }
  454.                        
  455.                 m_logIndent--;
  456.                
  457.                 foreach( subTablePair in m_fixupSet )
  458.                 {
  459.                         RemoveDelegation( subTablePair[1] );
  460.                 }
  461.                
  462.                 Log( "...end resolution" );
  463.         }
  464.                
  465.         // private:
  466.         function HookRootMetamethod( name, value )
  467.         {
  468.                 local saved = null;
  469.                 local roottable = getroottable();
  470.                 if ( name in roottable )
  471.                 {
  472.                         saved = roottable[name];
  473.                 }
  474.                 roottable[name] <- value;
  475.                 roottable["__saved" + name] <- saved;
  476.         }
  477.  
  478.         function UnhookRootMetamethod( name )
  479.         {
  480.                 local saveSlot = "__saved" + name;
  481.                 local roottable = getroottable();
  482.                 local saved = roottable[saveSlot];
  483.                 if ( saved != null )
  484.                 {
  485.                         roottable[name] = saved;
  486.                 }
  487.                 else
  488.                 {
  489.                         delete roottable[name];
  490.                 }
  491.                 delete roottable[saveSlot];
  492.         }
  493.  
  494.         function EstablishDelegation( parentTable, childTable )
  495.         {
  496.                 delegate parentTable : childTable;
  497.                
  498.                 foreach( key, value in childTable )
  499.                 {
  500.                         local type = typeof value;
  501.                         if ( type == "table" )
  502.                         {
  503.                                 EstablishDelegation( childTable, value );
  504.                         }
  505.                 }
  506.         }
  507.        
  508.         function RemoveDelegation( childTable )
  509.         {
  510.                 delegate null : childTable;
  511.                
  512.                 foreach( key, value in childTable )
  513.                 {
  514.                         local type = typeof value;
  515.                         if ( type == "table" )
  516.                         {
  517.                                 RemoveDelegation( value );
  518.                         }
  519.                 }
  520.         }
  521.  
  522.         function Resolve( lookupTable, subTableOrArray, throwException = false )
  523.         {
  524.                 m_logIndent++;
  525.                 local found = false;
  526.        
  527.                 foreach( key, value in subTableOrArray )
  528.                 {
  529.                         local type = typeof value;
  530.                         if ( type == "string" )
  531.                         {
  532.                                 if ( value.len() )
  533.                                 {
  534.                                         local unresolvedId = null;
  535.                                         local controlChar = value[0]
  536.                                         if ( controlChar == '^' )
  537.                                         {
  538.                                                 found = true;
  539.                                                 value = value.slice( 1 );
  540.                                                 if ( value in lookupTable )
  541.                                                 {
  542.                                                         subTableOrArray[key] = lookupTable[value];
  543.                                                         Log( key + " = " + lookupTable[value] + " <-- " + value );
  544.                                                 }
  545.                                                 else
  546.                                                 {
  547.                                                         subTableOrArray[key] = "~" + value;
  548.                                                         unresolvedId = value;
  549.                                                         Log( key + " = \"" + "~" + value + "\" (unresolved)" );
  550.                                                 }
  551.                                         }
  552.                                         else if ( controlChar == '@' )
  553.                                         {
  554.                                                 found = true;
  555.                                                 local identifiers = [];
  556.                                                 local iLast = 1;
  557.                                                 local iNext;
  558.                                                 while ( ( iNext = value.find( ".", iLast ) ) != null )
  559.                                                 {
  560.                                                         identifiers.push( value.slice( iLast, iNext ) );
  561.                                                         iLast = iNext + 1;
  562.                                                 }
  563.                                                 identifiers.push( value.slice( iLast ) );
  564.                                                
  565.                                                 local depthSuccess = 0;
  566.                                                 local result = lookupTable;
  567.                                                 foreach( identifier in identifiers )
  568.                                                 {
  569.                                                         if ( identifier in result )
  570.                                                         {
  571.                                                                 depthSuccess++;
  572.                                                                 result = result[identifier];
  573.                                                         }
  574.                                                         else
  575.                                                         {
  576.                                                                 break;
  577.                                                         }
  578.                                                 }
  579.                                                 if ( depthSuccess == identifiers.len() )
  580.                                                 {
  581.                                                         subTableOrArray[key] = result;
  582.                                                         Log( key + " = " + result + " <-- " + value );
  583.                                                 }
  584.                                                 else
  585.                                                 {
  586.                                                         subTableOrArray[key] = "~" + value.slice( 1 );
  587.                                                         unresolvedId = value;
  588.                                                         Log( key + " = \"" + "~" + value + "\" (unresolved)" );
  589.                                                 }
  590.                                         }
  591.                                        
  592.                                         if ( unresolvedId != null )
  593.                                         {
  594.                                                 if ( throwException )
  595.                                                 {
  596.                                                         local exception = "Unresolved symbol: " + bind + " in ";
  597.                                                         foreach ( entry in m_bindNamesStack )
  598.                                                         {
  599.                                                                 exception += entry;
  600.                                                                 exception += "."
  601.                                                         }
  602.                                                         exception += unresolvedId;
  603.                                                        
  604.                                                         throw exception;
  605.                                                 }
  606.                                         }
  607.                                 }
  608.                         }
  609.                 }
  610.  
  611.                 foreach( key, value in subTableOrArray )
  612.                 {
  613.                         local type = typeof value;
  614.                         local isTable = ( type == "table" );
  615.                         local isArray = ( type == "array" )
  616.                         if ( isTable || isArray )
  617.                         {
  618.                                 Log( key + " =" );
  619.                                 Log( isTable ? "{" : "[" );
  620.                                
  621.                                 m_bindNamesStack.push( key );
  622.                                 if ( Resolve( ( isTable ) ? value : lookupTable, value, throwException ) )
  623.                                 {
  624.                                         found = true;
  625.                                 }
  626.                                 m_bindNamesStack.pop();
  627.                                
  628.                                 Log( isTable ? "}" : "]" );
  629.                         }
  630.                 }
  631.                 m_logIndent--;
  632.                 return found;
  633.         }
  634.        
  635.         function Log( string )
  636.         {
  637.                 if ( m_log )
  638.                 {
  639.                         for ( local i = 0; i < m_logIndent; i++ )
  640.                         {
  641.                                 print( "  " );
  642.                         }
  643.                        
  644.                         printl( string );
  645.                 }
  646.         }
  647.  
  648.         m_targetTable = null;
  649.         m_fixupSet = [];
  650.         m_bindNamesStack = [];
  651.         m_log = false;
  652.         m_logIndent = 0;
  653. }
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top