private Command.CalcTargetObjects MakeCommandCalcTargetObjectsInstance(LuaDataContainer ldc) { return(new Command.CalcTargetObjects(() => ldc.GetWherigoObjectListFromProvider <Thing>( "CalcTargetObjects", _helper.Cartridge, _helper.Player))); }
private Input.RunOnGetInput MakeInputRunOnGetInputInstance(LuaDataContainer ldc) { // Defines an action that can queue giving a result to the relevant input entity. Action <string, ExecutionQueue.FallbackAction> onGetInput = new Action <string, ExecutionQueue.FallbackAction>( (s, fa) => _helper.LuaExecutionQueue.BeginCallSelf(ldc, "OnGetInput", fa, s) ); // Defines a function that can create a fallback action in case giving a null // result to the relevant input entity raises an exception. // In that case, another try is done using an empty string instead. // No fallback action is given if the input answer is not null. Func <string, ExecutionQueue.FallbackAction> getFallback = new Func <string, ExecutionQueue.FallbackAction>( s => { if (s == null) { return(new ExecutionQueue.FallbackAction( ex => onGetInput("", null) )); } else { return(null); } }); // Returns an action that queues giving a result to this input, allowing // to do it again if the first attempt has been made with a null string // and failed. return(new Input.RunOnGetInput(s => onGetInput(s, getFallback(s)))); }
/// <summary> /// Sets a global path with the native table associated with a /// container. /// </summary> /// <param name="path">Path in the global table to set.</param> /// <param name="container">Container associated to the Lua table to set.</param> internal void SetContainerAt(string path, LuaDataContainer container) { // Gets the LuaTable for the container. LuaTable lt = GetNativeContainerCore(container); // Sets the global path to this table. _luaState.SafeSetGlobal(path, lt); }
/// <summary> /// Creates a new container and sets a global path with it. /// </summary> /// <remarks> /// If an object already exists at <paramref name="path"/>, it is /// replaced with the new container. /// </remarks> /// <param name="path">The global path to create the container at.</param> /// <returns>The created container.</returns> internal LuaDataContainer CreateContainerAt(string path) { // Creates the container. LuaTable native = _luaState.SafeCreateTable(); LuaDataContainer ldc = CreateContainerCore(native, true); // Sets the global path. _luaState.SafeSetGlobal(path, native); // Returns the container. return(ldc); }
public WherigoCollection <W> GetWherigoObjectListFromProvider <W>(string key, params object[] parameters) where W : WherigoObject { // Gets the provider at the key. LuaFunction lf = _luaState.SafeGetField <LuaFunction>(_luaTable, key); if (lf == null) { return(new WherigoCollection <W>()); } // Gets the self, unprotected, provider. LuaDataProvider ldp = _dataFactory.GetProvider(lf, this, false); // Executes and gets the first container. LuaDataContainer ldc = ldp.FirstContainerOrDefault(parameters); // Gets the list for this return(_dataFactory.GetWherigoObjectList <W>(ldc)); }
private WherigoObject GetWherigoObjectCore( LuaTable obj, bool dontFailIfNotWigEntity = false, bool forceProtectFromGC = false, bool allowsNullTable = false, Type typeToCompare = null) { // Sanity check. if (obj == null) { if (!allowsNullTable) { throw new ArgumentNullException("Null table argument is not allowed."); } return(null); } // Gets the class of the entity. string cn = _luaState.SafeGetField <string>(obj, "ClassName"); if (cn == null) { if (dontFailIfNotWigEntity) { return(null); } throw new InvalidOperationException("obj has no ClassName string property."); } // Does the entity have an ObjIndex? // YES -> it should be in the AllZObjects table, so retrieve or make it. // NO -> make it anyway. WherigoObject ret = null; double? oiRaw = _luaState.SafeGetField <double?>(obj, "ObjIndex"); if (oiRaw == null) { // Creates a container for the table. // It is not protected from GC by default. LuaDataContainer ldc = CreateContainerCore(obj, forceProtectFromGC); // Immediately wraps the table into its corresponding class. if ("ZonePoint" == cn) { ret = new ZonePoint(ldc); } else if ("ZCommand" == cn || "ZReciprocalCommand" == cn) { ret = new Command( ldc, MakeCommandCalcTargetObjectsInstance(ldc), MakeCommandExecuteCommandInstance(ldc) ); } else if ("Distance" == cn) { ret = new Distance(ldc); } } else { // Tries to get the object from the cache if it is not // the player or cartridge object. int oi = (int)oiRaw.Value; bool isPlayer = oi < 0; bool isCartridge = oi == 0; Node node; if (!isPlayer && !isCartridge) { bool hasValue; lock (_syncRoot) { hasValue = _wEntities.TryGetValue(oi, out node); } // The object is known, returns it. if (hasValue) { ret = node.Object; // Double check the classname. string cachedCn = ret.DataContainer.GetString("ClassName"); if (cn != cachedCn) { throw new InvalidOperationException(String.Format("The object with id {0} is known to have class {1}, but class {2} was requested.", oi, cachedCn ?? "<null>", cn ?? "<null>")); } } } // The object is not known, make it and create a node for it. if (ret == null) { // Creates a GC-protected container for the table. FriendLuaDataContainer ldc = CreateContainerCore(obj, true); // Creates the object. if ("ZInput" == cn) { ret = new Input( ldc, MakeInputRunOnGetInputInstance(ldc) ); } else if ("ZTimer" == cn) { ret = new Timer(ldc); } else if ("ZCharacter" == cn) { if (isPlayer && _helper.Player != null) { ret = _helper.Player; } else { ret = new Character( ldc, MakeUIObjectRunOnClickInstance(ldc) ); } } else if ("ZItem" == cn) { ret = new Item( ldc, MakeUIObjectRunOnClickInstance(ldc) ); } else if ("ZTask" == cn) { ret = new Task( ldc, MakeUIObjectRunOnClickInstance(ldc) ); } else if ("Zone" == cn) { ret = new Zone( ldc, MakeUIObjectRunOnClickInstance(ldc) ); } else if ("ZMedia" == cn) { // Gets the ZMedia from the Cartridge which has the same Id. Media media = _helper.Cartridge.Resources.Single(m => m.MediaId == oi); // Injects the data container with metadata about the media. media.DataContainer = ldc; // The returned object is the media. ret = media; } else if ("ZCartridge" == cn) { // Sanity checks if the Cartridge GUIDs match. string baseId = _helper.Cartridge.Guid; string reqId = ldc.GetString("Id"); if (baseId != reqId) { //throw new InvalidOperationException(String.Format("Requested Cartridge with id {0}, but only knows Cartridge with id {1}.", reqId, baseId)); System.Diagnostics.Debug.WriteLine("LuaDataFactory: WARNING: " + String.Format("Requested Cartridge with id {0}, but only knows Cartridge with id {1}.", reqId, baseId)); } // Returns the cartridge object. ret = _helper.Cartridge; // Binds the cartridge container if the cartridge is unbound. if (ret.DataContainer == null) { ret.DataContainer = ldc; } } else { throw new InvalidOperationException("obj has an unknown classname: " + cn); } // Creates a node and registers it. Cartridge and player are not registered. if (!isPlayer && !isCartridge) { node = new Node() { Container = ldc, Object = ret }; lock (_syncRoot) { _wEntities.Add(oi, node); } } } } // Final sanity checks. if (ret == null) { throw new InvalidOperationException("Returned value was not computed."); } if (typeToCompare != null && !typeToCompare.IsAssignableFrom(ret.GetType())) { throw new InvalidOperationException(String.Format("The wherigo object is known to have type {0}, not {1} as requested.", ret.GetType().FullName, typeToCompare.FullName)); } return(ret); }
/// <summary> /// Gets a provider for a lua function. /// </summary> /// <param name="func">Function to wrap.</param> /// <param name="self">If non-null, the provider will pass the underlying /// lua table as a first parameter during execution.</param> /// <param name="protectFromGC">If true, the provider is protected from garbage /// collection.</param> /// <returns>The LuaDataProvider for the function.</returns> internal LuaDataProvider GetProvider(LuaFunction func, LuaDataContainer self = null, bool protectFromGC = false) { return(CreateProviderCore(func, self == null ? null : GetNativeContainerCore(self), protectFromGC)); }
private Command.ExecuteCommand MakeCommandExecuteCommandInstance(LuaDataContainer ldc) { return(new Command.ExecuteCommand(t => _helper.LuaExecutionQueue.BeginCallSelf(ldc, "exec", t))); }
private UIObject.RunOnClick MakeUIObjectRunOnClickInstance(LuaDataContainer ldc) { return(new UIObject.RunOnClick(() => _helper.LuaExecutionQueue.BeginCallSelf(ldc, "OnClick"))); }
internal Enumerator(LuaDataContainer luaDataContainer) { this._parent = luaDataContainer; _baseEnumerator = _parent._luaState.SafeGetEnumerator(_parent._selfLuaTable); }