/// <summary> /// Executes asynchronously a call to a Lua self-function on the thread this ExecutionQueue is associated with. /// </summary> /// <remarks>This method returns once the call job is queued.</remarks> /// <param name="obj">Entity that contains the self-function.</param> /// <param name="func">Field name in underlying LuaTable of <paramref name="obj"/> that corresponds to the /// self-function to call.</param> /// <param name="parameters">Optional parameters to pass to the function. <paramref name="obj"/> is automatically /// added as first parameter.</param> public void BeginCallSelf(WherigoObject obj, string func, params object[] parameters) { // Conforms the parameters and enqueues a job. IDataContainer cont = obj.DataContainer; AcceptJob(GetJob(cont, func, ConformParameters(parameters), true)); }
public W CreateWherigoObject <W>(params object[] arguments) where W : WherigoObject { Type wherigoType = typeof(W); WherigoObject obj = null; // Conforms parameters. List <object> args = new List <object>(); if (arguments != null) { args.AddRange(arguments); } // Creates the object if the requested type is supported. if (wherigoType == typeof(ZonePoint)) { obj = CreateZonePoint(args); } else if (wherigoType == typeof(Distance)) { obj = CreateDistance(args); } else { throw new NotSupportedException("Requested type is not supported."); } // Checks the type and returns the object. if (!(obj is W)) { throw new InvalidOperationException(String.Format("Requested type {0}, got type {1}.", wherigoType.Name, obj.GetType().Name)); } return((W)obj); }
protected override void OnWherigoObjectChanged(WherigoObject obj) { if (obj != null) { RefreshStatusText(); } }
/// <summary> /// Gets a list of Wherigo objects of a certain type from a list of /// Wherigo entities in a Lua table. /// </summary> /// <typeparam name="W">The type of Wherigo objects to get.</typeparam> /// <param name="luaTable">The table containing entities.</param> /// <returns>A list of entities of type <typeparamref name="W"/>, eventually /// empty.</returns> internal WherigoCollection <W> GetWherigoObjectList <W>(LuaTable luaTable) where W : WherigoObject { // Creates an empty list to store the objects. List <W> list = new List <W>(); // Enumerates through all values of the lua table that are lua tables. // For each of them, tries to convert to a W. var e = _luaState.SafeGetEnumerator(luaTable); while (e.MoveNext()) { if (e.Value is LuaTable) { // Tries to get a wherigo object for this entity. WherigoObject wo = GetWherigoObjectCore((LuaTable)e.Value, dontFailIfNotWigEntity: true); // If the object is a W, adds it to the list. if (wo != null && wo is W) { list.Add((W)wo); } } } // Returns the list. return(new WherigoCollection <W>(list)); }
/// <summary> /// Gets the LuaDataContainer which has a particular object index. /// </summary> /// <param name="objIndex">The object index to look for. Must be 0 or greater.</param> /// <returns>The LuaDataContainer of the wherigo object with this index.</returns> /// <exception cref="ArgumentException"><paramref name="objIndex"/> is smaller than 0.</exception> internal LuaDataContainer GetContainer(int objIndex) { // Gets the Wherigo object for this index and performs sanity checks. WherigoObject wo = GetWherigoObjectCore(objIndex); // Returns the container. return((LuaDataContainer)wo.DataContainer); }
/// <summary> /// Gets the native lua table for a Wherigo object. /// </summary> /// <param name="obj">WherigoObject to get the table of.</param> /// <returns>The lua table for the object.</returns> /// <exception cref="InvalidOperationException">The object has not /// been created by this factory, or has no data container.</exception> internal LuaTable GetNativeContainer(WherigoObject obj) { // Checks if the data container exists. if (obj.DataContainer == null) { throw new InvalidOperationException("The object has no data container."); } // Returns the native table. return(GetNativeContainerCore(obj.DataContainer)); }
public W CreateWherigoObject <W>(params object[] arguments) where W : WherigoObject { // Gets the classname for the needed type. string classname = GetWherigoClassname(typeof(W)); // Creates the object. WherigoObject wo = CreateWherigoObjectCore(classname, typeof(W), arguments); // Returns the object. return((W)wo); }
/// <summary> /// Navigates the app to the view that best fits a Thing object. /// </summary> /// <param name="wherigoObj"></param> public void NavigateToView(Thing wherigoObj) { // If the thing is the player, navigates to device and player info view. if (WherigoObject.AreSameEntities(wherigoObj, _parent.Model.Core.Player)) { NavigateToPlayerInfo(); } else { NavigateCore(new Uri("/Views/ThingPage.xaml?wid=" + wherigoObj.ObjIndex, UriKind.Relative), cancelIfAlreadyActive: true); } }
public W GetWherigoObject <W>(int objIndex) where W : WherigoObject { // Gets the object. WherigoObject wo = GetWherigoObjectCore(objIndex, dontFailIfBadArg: true); // Checks if the wherigo object is of the right type. if (wo != null && !(wo is W)) { throw new InvalidOperationException(String.Format("The object with index {0} is known to be of type {1}, not {2} as requested.", objIndex, wo.GetType().FullName, typeof(W).FullName)); } // Returns the object, cast to the proper type. return((W)wo); }
/// <summary> /// Executes asynchronously a call to a Lua self-function on the thread this ExecutionQueue is associated with, /// after making sure that calls of the same function that are queued but yet to execute /// are being removed from the queue. /// </summary> /// <remarks>This method returns once the call job is queued.</remarks> /// <param name="obj">Entity that contains the self-function.</param> /// <param name="func">Field name in underlying LuaTable of <paramref name="obj"/> that corresponds to the /// self-function to call. Cannot be null.</param> /// <param name="parameters">Optional parameters to pass to the function. <paramref name="obj"/> is automatically /// added as first parameter.</param> public void BeginCallSelfUnique(WherigoObject obj, string func, params object[] parameters) { if (func == null) { throw new ArgumentNullException("func"); } // Removes all job for this function. RemoveJobsWithTag(func); // Conforms the parameters and enqueues a job. IDataContainer cont = obj.DataContainer; AcceptJob(GetJob(cont, func, ConformParameters(parameters), true), tag: func); }
/// <summary> /// Executes asynchronously a call to a Lua function on the thread this ExecutionQueue is associated with. /// </summary> /// <remarks>This method returns once the call job is queued.</remarks> /// <param name="obj">Table entity that contains the function.</param> /// <param name="func">Field name in the underlying IDataContainer of <paramref name="obj"/> that corresponds to the /// function to call.</param> /// <param name="parameters">Optional parameters to pass to the function.</param> public void BeginCall(WherigoObject obj, string func, params object[] parameters) { // Conforms the parameters and enqueues a job. AcceptJob(GetJob(obj.DataContainer, func, ConformParameters(parameters))); }
internal static void CallSelf(this WherigoObject wo, string funcName, params object[] parameters) { // Gets the self-provider and calls it. ((LuaDataContainer)wo.DataContainer).CallSelf(funcName, parameters); }
/// <summary> /// Loads a save game for the current cartridge from a stream. /// </summary> /// <param name="stream">Stream to load the game from.</param> /// <returns>The metadata of the file.</returns> public Metadata Load(Stream stream) { int numAllZObjects; Metadata metadata; using (BinaryReader input = new BinaryReader(stream)) { // Loads the GWS metadata. metadata = LoadMetadata(input); // Belongs this GWS file to the cartridge if (!metadata.CartridgeCreateDate.Equals(_cartridgeEntity.CreateDate)) { throw new Exception("Trying to load a GWS file with different creation date of cartridge."); } // TODO // Check, if all fields are the same as the fields from the GWC cartridge. // If not, than ask, if we should go on, even it could get problems. int numOfObjects = input.ReadInt32(); _allZObjects = _cartridge.GetContainer("AllZObjects"); numAllZObjects = _allZObjects.Count; string objectType = null; for (int i = 1; i < numOfObjects; i++) { objectType = readString(input); if (i > numAllZObjects - 1) { // Object creation can be done using: WherigoObject wo = _dataFactory.CreateWherigoObject(objectType, _cartridge); } else { // TODO: Check, if objectType and real type of object are the same } } // Now update allZObjects, because it could be, that new ones are created _allZObjects = _cartridge.GetContainer("AllZObjects"); numAllZObjects = _allZObjects.Count; //LuaTable obj = _player; LuaDataContainer obj = _player; objectType = readString(input); // Read begin table (5) for player byte b = input.ReadByte(); // Read data for player readTable(input, obj); for (int i = 0; i < numAllZObjects; i++) { objectType = readString(input); b = input.ReadByte(); if (b != 5) { // error throw new InvalidOperationException(); } else { obj = (LuaDataContainer)_allZObjects.GetContainer(i); readTable(input, obj); } } input.Close(); } // Now deserialize all ZObjects for (int i = 0; i < numAllZObjects; i++) { ((LuaDataContainer)_allZObjects.GetContainer(i)).CallSelf("deserialize"); } // TODO: Update all lists return(metadata); }
protected override void OnWherigoObjectChanged(WherigoObject obj) { RefreshActionVisibilities(); RefreshContainerVisibilities(); RefreshStatusText(); }
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> /// Called when the associated Wherigo object has changed. /// </summary> /// <param name="obj"></param> protected virtual void OnWherigoObjectChanged(WherigoObject obj) { }