private LuaTable GetNativeContainerCore(IDataContainer container) { // Makes the container friendly :) FriendLuaDataContainer fc = container as FriendLuaDataContainer; // Sanity check. if (fc == null) { throw new InvalidOperationException("The container has not been created by this instance of LuaDataFactory."); } // Returns the container. return(fc.Table); }
private FriendLuaDataContainer CreateContainerCore(LuaTable native, bool protectFromGC = false) { // Gets a protected version of the table if needed. if (protectFromGC) { native = _luaState.SafeProtectTableFromGC(native); } // Creates a new container. FriendLuaDataContainer ldc = new FriendLuaDataContainer(native, _luaState, this); // Returns the container. return(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); }