/// <summary> /// Determines whether the specified <see cref="System.Object" />, is equal to this instance. /// </summary> /// <param name="obj">The <see cref="System.Object" /> to compare with this instance.</param> /// <returns> /// <c>true</c> if the specified <see cref="System.Object" /> is equal to this instance; otherwise, <c>false</c>. /// </returns> public override bool Equals(object obj) { DynValue other = obj as DynValue; if (other == null) { return(false); } if ((other.Type == DataType.Nil && this.Type == DataType.Void) || (other.Type == DataType.Void && this.Type == DataType.Nil)) { return(true); } if (other.Type != this.Type) { return(false); } switch (Type) { case DataType.Void: case DataType.Nil: return(true); case DataType.Boolean: return(Boolean == other.Boolean); case DataType.Number: return(Number == other.Number); case DataType.String: return(String == other.String); case DataType.Function: return(Function == other.Function); case DataType.ClrFunction: return(Callback == other.Callback); case DataType.Table: return(Table == other.Table); case DataType.Tuple: case DataType.TailCallRequest: return(Tuple == other.Tuple); case DataType.Thread: return(Coroutine == other.Coroutine); case DataType.UserData: { UserData ud1 = this.UserData; UserData ud2 = other.UserData; if (ud1 == null || ud2 == null) { return(false); } if (ud1.Descriptor != ud2.Descriptor) { return(false); } if (ud1.Object == null && ud2.Object == null) { return(true); } if (ud1.Object != null && ud2.Object != null) { return(ud1.Object.Equals(ud2.Object)); } return(false); } default: return(object.ReferenceEquals(this, other)); } }
/// <summary> /// Gets the metamethod to be used for a binary operation using op1 and op2. /// </summary> public DynValue GetBinaryMetamethod(DynValue op1, DynValue op2, string eventName) { return(m_Processor.GetBinaryMetamethod(op1, op2, eventName)); }
internal DynamicExpression(Script S, string strExpr, DynValue constant) { ExpressionCode = strExpr; OwnerScript = S; m_Constant = constant; }
/// <summary> /// Gets the metatable associated with the given value. /// </summary> /// <param name="value">The value.</param> /// <returns></returns> public Table GetMetatable(DynValue value) { return(m_Processor.GetMetatable(value)); }
/// <summary> /// Gets the specified metamethod associated with the given value. /// </summary> /// <param name="value">The value.</param> /// <param name="metamethod">The metamethod name.</param> /// <returns></returns> public DynValue GetMetamethod(DynValue value, string metamethod) { return(m_Processor.GetMetamethod(value, metamethod)); }
/// <summary> /// Gets the value associated with the specified key. /// </summary> /// <param name="key">The key.</param> public DynValue Get(DynValue key) { //Contract.Ensures(Contract.Result<DynValue>() != null); return(RawGet(key) ?? DynValue.Nil); }
/// <summary> /// Get a function to calculate properties for a set given edge attributes. /// </summary> /// <returns></returns> public sealed override EdgeFactor Factor(IAttributeCollection attributes) { lock (_script) { // build lua table. _attributesTable.Clear(); if (attributes == null || attributes.Count == 0) { return(EdgeFactor.NoFactor); } foreach (var attribute in attributes) { _attributesTable.Set(attribute.Key, DynValue.NewString(attribute.Value)); } // call factor_and_speed function. _resultsTable.Clear(); _script.Call(_script.Globals["factor"], _attributesTable, _resultsTable); // get the results. if (!_resultsTable.TryGetDouble("forward", out var forwardFactor)) { forwardFactor = 0; } if (!_resultsTable.TryGetDouble("backward", out var backwardFactor)) { backwardFactor = 0; } if (!_resultsTable.TryGetBool("canstop", out var canstop)) { canstop = backwardFactor != 0 || forwardFactor != 0; } // the speeds are supposed to be in m/s. if (!_resultsTable.TryGetDouble("forward_speed", out var speedForward)) { // when forward_speed isn't explicitly filled, the assumption is that factors are in 1/(m/s) speedForward = 0; if (forwardFactor > 0) { // convert to m/s. speedForward = 1.0 / forwardFactor; } } else { // when forward_speed is filled, it's assumed to be in km/h, it needs to be convert to m/s. speedForward /= 3.6; } if (!_resultsTable.TryGetDouble("backward_speed", out var speedBackward)) { // when backward_speed isn't explicitly filled, the assumption is that factors are in 1/(m/s) speedBackward = 0; if (backwardFactor > 0) { // convert to m/s. speedBackward = 1.0 / backwardFactor; } } else { // when forward_speed is filled, it's assumed to be in km/h, it needs to be convert to m/s. speedBackward /= 3.6; } return(new EdgeFactor((uint)(forwardFactor * 100), (uint)(backwardFactor * 100), (ushort)(speedForward * 100), (ushort)(speedBackward * 100), canstop)); } }
private void PerformTableSet <T>(LinkedListIndex <T, TablePair> listIndex, T key, DynValue keyDynValue, DynValue value, bool isNumber, int appendKey) { TablePair prev = listIndex.Set(key, new TablePair(keyDynValue, value)); // If this is an insert, we can invalidate all iterators and collect dead keys if (m_ContainsNilEntries && value.IsNotNil() && (prev.Value == null || prev.Value.IsNil())) { CollectDeadKeys(); } // If this value is nil (and we didn't collect), set that there are nil entries, and invalidate array len cache else if (value.IsNil()) { m_ContainsNilEntries = true; if (isNumber) { m_CachedLength = -1; } } else if (isNumber) { // If this is an array insert, we might have to invalidate the array length if (prev.Value == null || prev.Value.IsNilOrNan()) { // If this is an array append, let's check the next element before blindly invalidating if (appendKey >= 0) { LinkedListNode <TablePair> next = m_ArrayMap.Find(appendKey + 1); if (next == null || next.Value.Value == null || next.Value.Value.IsNil()) { m_CachedLength += 1; } else { m_CachedLength = -1; } } else { m_CachedLength = -1; } } } }
/// <summary> /// Sets the value associated to the specified key. /// </summary> /// <param name="key">The key.</param> /// <param name="value">The value.</param> public void Set(int key, DynValue value) { this.CheckScriptOwnership(value); PerformTableSet(m_ArrayMap, key, DynValue.NewNumber(key), value, true, -1); }
/// <summary> /// Creates a new dynamic expression which is actually quite static, returning always the same constant value. /// </summary> /// <param name="code">The code of the not-so-dynamic expression.</param> /// <param name="constant">The constant to return.</param> /// <returns></returns> public DynamicExpression CreateConstantDynamicExpression(string code, DynValue constant) { this.CheckScriptOwnership(constant); return(new DynamicExpression(this, code, constant)); }
/// <summary> /// Append the value to the table using the next available integer index. /// </summary> /// <param name="value">The value.</param> public void Append(DynValue value) { this.CheckScriptOwnership(value); PerformTableSet(m_ArrayMap, Length + 1, DynValue.NewNumber(Length + 1), value, true, Length + 1); }
/// <summary> /// Creates a coroutine pointing at the specified function. /// </summary> /// <param name="function">The function.</param> /// <returns> /// The coroutine handle. /// </returns> /// <exception cref="System.ArgumentException">Thrown if function is not of DataType.Function or DataType.ClrFunction</exception> public DynValue CreateCoroutine(object function) { return(CreateCoroutine(DynValue.FromObject(this, function))); }
/// <summary> /// Calls the specified function. /// </summary> /// <param name="function">The Lua/MoonSharp function to be called </param> /// <param name="args">The arguments to pass to the function.</param> /// <returns></returns> /// <exception cref="System.ArgumentException">Thrown if function is not of DataType.Function</exception> public DynValue Call(object function, params object[] args) { return(Call(DynValue.FromObject(this, function), args)); }
/// <summary> /// Calls the specified function. /// </summary> /// <param name="function">The Lua/MoonSharp function to be called</param> /// <returns></returns> /// <exception cref="System.ArgumentException">Thrown if function is not of DataType.Function</exception> public DynValue Call(object function) { return(Call(DynValue.FromObject(this, function))); }
/// <summary> /// Calls the specified function. /// </summary> /// <param name="function">The Lua/MoonSharp function to be called</param> /// <returns> /// The return value(s) of the function call. /// </returns> /// <exception cref="System.ArgumentException">Thrown if function is not of DataType.Function</exception> public DynValue Call(DynValue function) { return(Call(function, new DynValue[0])); }
///// <summary> ///// Loads a Lua/MoonSharp script from a System.IO.Stream. NOTE: This will *NOT* close the stream! ///// </summary> ///// <param name="stream">The stream containing code.</param> ///// <param name="globalTable">The global table to bind to this chunk.</param> ///// <param name="codeFriendlyName">Name of the code - used to report errors, etc.</param> ///// <returns> ///// A DynValue containing a function which will execute the loaded code. ///// </returns> //public DynValue LoadStream(Stream stream, Table globalTable = null, string codeFriendlyName = null) //{ // this.CheckScriptOwnership(globalTable); // // Stream codeStream = new UndisposableStream(stream); // //if (!Processor.IsDumpStream(codeStream)) // //{ // using (StreamReader sr = new StreamReader(stream)) // { // string scriptCode = sr.ReadToEnd(); // return LoadString(scriptCode, globalTable, codeFriendlyName); // } // //} // //else // //{ // // string chunkName = string.Format("{0}", codeFriendlyName ?? "dump_" + m_Sources.Count.ToString()); // // SourceCode source = new SourceCode(codeFriendlyName ?? chunkName, // // string.Format("-- This script was decoded from a binary dump - dump_{0}", m_Sources.Count), // // m_Sources.Count, this); // // m_Sources.Add(source); // // bool hasUpvalues; // // int address = m_MainProcessor.Undump(codeStream, m_Sources.Count - 1, globalTable ?? m_GlobalTable, out hasUpvalues); // // SignalSourceCodeChange(source); // // SignalByteCodeChange(); // // if (hasUpvalues) // // return MakeClosure(address, globalTable ?? m_GlobalTable); // // else // // return MakeClosure(address); // //} //} ///// <summary> ///// Dumps on the specified stream. ///// </summary> ///// <param name="function">The function.</param> ///// <param name="stream">The stream.</param> ///// <exception cref="System.ArgumentException"> ///// function arg is not a function! ///// or ///// stream is readonly! ///// or ///// function arg has upvalues other than _ENV ///// </exception> //public void Dump(DynValue function, Stream stream) //{ // this.CheckScriptOwnership(function); // if (function.Type != DataType.Function) // throw new ArgumentException("function arg is not a function!"); // if (!stream.CanWrite) // throw new ArgumentException("stream is readonly!"); // Closure.UpvaluesType upvaluesType = function.Function.GetUpvaluesType(); // if (upvaluesType == Closure.UpvaluesType.Closure) // throw new ArgumentException("function arg has upvalues other than _ENV"); // UndisposableStream outStream = new UndisposableStream(stream); // m_MainProcessor.Dump(outStream, function.Function.EntryPointByteCodeLocation, upvaluesType == Closure.UpvaluesType.Environment); //} // /// <summary> // /// Loads a string containing a Lua/MoonSharp script. // /// </summary> // /// <param name="filename">The code.</param> // /// <param name="globalContext">The global table to bind to this chunk.</param> // /// <param name="friendlyFilename">The filename to be used in error messages.</param> // /// <returns> // /// A DynValue containing a function which will execute the loaded code. // /// </returns> // public DynValue LoadFile(string filename, Table globalContext = null, string friendlyFilename = null) // { // this.CheckScriptOwnership(globalContext); //#pragma warning disable 618 // filename = Options.ScriptLoader.ResolveFileName(filename, globalContext ?? m_GlobalTable); //#pragma warning restore 618 // object code = Options.ScriptLoader.LoadFile(filename, globalContext ?? m_GlobalTable); // if (code is string) // { // return LoadString((string)code, globalContext, friendlyFilename ?? filename); // } // else if (code is byte[]) // { // using (MemoryStream ms = new MemoryStream((byte[])code)) // return LoadStream(ms, globalContext, friendlyFilename ?? filename); // } // else if (code is Stream) // { // try // { // return LoadStream((Stream)code, globalContext, friendlyFilename ?? filename); // } // finally // { // ((Stream)code).Dispose(); // } // } // else // { // if (code == null) // throw new InvalidCastException("Unexpected null from IScriptLoader.LoadFile"); // else // throw new InvalidCastException(string.Format("Unsupported return type from IScriptLoader.LoadFile : {0}", code.GetType())); // } // } /// <summary> /// Loads and executes a string containing a Lua/MoonSharp script. /// </summary> /// <param name="code">The code.</param> /// <param name="globalContext">The global context.</param> /// <param name="codeFriendlyName">Name of the code - used to report errors, etc. Also used by debuggers to locate the original source file.</param> /// <returns> /// A DynValue containing the result of the processing of the loaded chunk. /// </returns> public DynValue DoString(string code, Table globalContext = null, string codeFriendlyName = null) { DynValue func = LoadString(code, globalContext, codeFriendlyName); return(Call(func)); }