private unsafe void InitLighting() { LoadLightingShaders(); RegenerateLightingRenderTargets(); // Occlusion VAO. // Only handles positions, no other vertex data necessary. _occlusionVao = new GLHandle(GL.GenVertexArray()); GL.BindVertexArray(_occlusionVao.Handle); ObjectLabelMaybe(ObjectLabelIdentifier.VertexArray, _occlusionVao, nameof(_occlusionVao)); _occlusionVbo = new GLBuffer(this, BufferTarget.ArrayBuffer, BufferUsageHint.DynamicDraw, nameof(_occlusionVbo)); _occlusionEbo = new GLBuffer(this, BufferTarget.ElementArrayBuffer, BufferUsageHint.DynamicDraw, nameof(_occlusionEbo)); GL.VertexAttribPointer(0, 3, VertexAttribPointerType.Float, false, sizeof(Vector3), IntPtr.Zero); GL.EnableVertexAttribArray(0); // FOV FBO. _fovFbo = new GLHandle(GL.GenFramebuffer()); var boundDrawBuffer = GL.GetInteger(GetPName.DrawFramebufferBinding); var boundReadBuffer = GL.GetInteger(GetPName.ReadFramebufferBinding); GL.BindFramebuffer(FramebufferTarget.Framebuffer, _fovFbo.Handle); _fovDepthTexture = new GLHandle(GL.GenTexture()); GL.BindTexture(TextureTarget.Texture2D, _fovDepthTexture.Handle); _fovDepthTextureObject = _genTexture(_fovDepthTexture, (ShadowMapSize, 1), "FOV depth texture"); GL.TexImage2D(TextureTarget.Texture2D, 0, PixelInternalFormat.DepthComponent, ShadowMapSize, 1, 0, PixelFormat.DepthComponent, PixelType.Float, IntPtr.Zero); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapS, (int)OGLTextureWrapMode.Repeat); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureWrapT, (int)OGLTextureWrapMode.Repeat); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMagFilter, (int)TextureMagFilter.Nearest); GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureMinFilter, (int)TextureMinFilter.Nearest); GL.FramebufferTexture(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthAttachment, _fovDepthTexture.Handle, 0); GL.DrawBuffer(DrawBufferMode.None); GL.ReadBuffer(ReadBufferMode.None); var status = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer); DebugTools.Assert(status == FramebufferErrorCode.FramebufferComplete, $"new framebuffer has bad status {status}"); GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, boundDrawBuffer); GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, boundReadBuffer); }
/// <inheritdoc /> public void ClientDisconnect(string reason) { DebugTools.Assert(IsClient, "Should never be called on the server."); Disconnect?.Invoke(this, new NetChannelArgs(ServerChannel)); Shutdown(reason); }
private static void HandleEntityState(IComponentManager compMan, IEntity entity, EntityState curState, EntityState nextState) { var compStateWork = new Dictionary <uint, (ComponentState curState, ComponentState nextState)>(); var entityUid = entity.Uid; if (curState?.ComponentChanges != null) { foreach (var compChange in curState.ComponentChanges) { if (compChange.Deleted) { if (compMan.TryGetComponent(entityUid, compChange.NetID, out var comp)) { compMan.RemoveComponent(entityUid, comp); } } else { if (compMan.HasComponent(entityUid, compChange.NetID)) { continue; } var newComp = (Component)IoCManager.Resolve <IComponentFactory>().GetComponent(compChange.ComponentName); newComp.Owner = entity; compMan.AddComponent(entity, newComp, true); } } } if (curState?.ComponentStates != null) { foreach (var compState in curState.ComponentStates) { compStateWork[compState.NetID] = (compState, null); } } if (nextState?.ComponentStates != null) { foreach (var compState in nextState.ComponentStates) { if (compStateWork.TryGetValue(compState.NetID, out var state)) { compStateWork[compState.NetID] = (state.curState, compState); } else { compStateWork[compState.NetID] = (null, compState); } } } foreach (var kvStates in compStateWork) { if (!compMan.TryGetComponent(entityUid, kvStates.Key, out var component)) { DebugTools.Assert("Component does not exist for state."); } DebugTools.Assert(kvStates.Value.curState == null || kvStates.Value.curState.GetType() == component.StateType, "Component state is of the wrong type."); component.HandleComponentState(kvStates.Value.curState, kvStates.Value.nextState); } }
/// <summary> /// Constructs a new instance of <c>TypeEntityQuery</c>. /// </summary> /// <param name="componentType">Type of the component to match.</param> public TypeEntityQuery(Type componentType) { DebugTools.Assert(typeof(IComponent).IsAssignableFrom(componentType), "componentType must inherit IComponent"); ComponentType = componentType; }
private void HandleEntityState(IComponentManager compMan, IEntity entity, EntityState curState, EntityState nextState) { var compStateWork = new Dictionary <uint, (ComponentState curState, ComponentState nextState)>(); var entityUid = entity.Uid; if (curState?.ComponentChanges != null) { foreach (var compChange in curState.ComponentChanges) { if (compChange.Deleted) { if (compMan.TryGetComponent(entityUid, compChange.NetID, out var comp)) { compMan.RemoveComponent(entityUid, comp); } } else { if (compMan.HasComponent(entityUid, compChange.NetID)) { continue; } var newComp = (Component)IoCManager.Resolve <IComponentFactory>() .GetComponent(compChange.ComponentName); newComp.Owner = entity; compMan.AddComponent(entity, newComp, true); } } } if (curState?.ComponentStates != null) { foreach (var compState in curState.ComponentStates) { compStateWork[compState.NetID] = (compState, null); } } if (nextState?.ComponentStates != null) { foreach (var compState in nextState.ComponentStates) { if (compStateWork.TryGetValue(compState.NetID, out var state)) { compStateWork[compState.NetID] = (state.curState, compState); } else { compStateWork[compState.NetID] = (null, compState); } } } foreach (var kvStates in compStateWork) { if (!compMan.TryGetComponent(entityUid, kvStates.Key, out var component)) { DebugTools.Assert("Component does not exist for state."); continue; } try { component.HandleComponentState(kvStates.Value.curState, kvStates.Value.nextState); } catch (Exception e) { var wrapper = new ComponentStateApplyException( $"Failed to apply comp state: entity={component.Owner}, comp={component.Name}", e); #if EXCEPTION_TOLERANCE _runtimeLog.LogException(wrapper, "Component state apply"); #else throw wrapper; #endif } } }
public void Update() { DebugTools.Assert(_impl != null, "WebViewManager has not yet been initialized!"); _impl !.Update(); }
public IWebViewWindow CreateBrowserWindow(BrowserWindowCreateParameters createParams) { DebugTools.Assert(_impl != null, "WebViewManager has not yet been initialized!"); return(_impl !.CreateBrowserWindow(createParams)); }
public override void AlignPlacementMode(ScreenCoordinates mouseScreen) { const float SearchBoxSize = 1.5f; // size of search box in meters MouseCoords = ScreenToCursorGrid(mouseScreen); var mapGrid = pManager.MapManager.GetGrid(MouseCoords.GridID); if (mapGrid.IsDefaultGrid) { // check if we are on an edge of a grid // create a box around the cursor DebugTools.Assert(mapGrid.WorldPosition == Vector2.Zero); // assert that LocalPos == WorldPos var gridSearchBox = Box2.UnitCentered.Scale(SearchBoxSize).Translated(MouseCoords.Position); // find grids in search box var gridsInArea = pManager.MapManager.FindGridsIntersecting(mapGrid.ParentMapId, gridSearchBox); // find closest grid intersecting our search box. IMapGrid closest = null; var distance = float.PositiveInfinity; var intersect = new Box2(); foreach (var grid in gridsInArea) { // figure out closest intersect var gridIntersect = gridSearchBox.Intersect(grid.WorldBounds); var gridDist = (gridIntersect.Center - MouseCoords.Position).LengthSquared; if (gridDist >= distance) { continue; } distance = gridDist; closest = grid; intersect = gridIntersect; } if (closest != null) // stick to existing grid { // round to nearest cardinal dir var normal = new Angle(MouseCoords.Position - intersect.Center).GetCardinalDir().ToVec(); // round coords to center of tile var tileIndices = closest.WorldToTile(intersect.Center); var tileCenterWorld = closest.GridTileToWorldPos(tileIndices); // move mouse one tile out along normal var newTilePos = tileCenterWorld + normal * closest.TileSize; MouseCoords = new GridCoordinates(closest.WorldToLocal(newTilePos), closest.Index); } //else free place } CurrentTile = mapGrid.GetTileRef(MouseCoords); float tileSize = mapGrid.TileSize; //convert from ushort to float GridDistancing = tileSize; if (pManager.CurrentPermission.IsTile) { if (!mapGrid.IsDefaultGrid) { MouseCoords = new GridCoordinates(CurrentTile.X + tileSize / 2, CurrentTile.Y + tileSize / 2, MouseCoords.GridID); } // else we don't modify coords } else { MouseCoords = new GridCoordinates(CurrentTile.X + tileSize / 2 + pManager.PlacementOffset.X, CurrentTile.Y + tileSize / 2 + pManager.PlacementOffset.Y, MouseCoords.GridID); } }
public void Use() { DebugTools.Assert(Handle != -1); GL.BindBuffer(Type, Handle); }
public void ClientDisconnect(string reason) { DebugTools.Assert(IsClient); Disconnect?.Invoke(this, new NetChannelArgs(ServerChannel)); Shutdown(reason); }
public void ProcessPackets() { while (_messageChannel.Reader.TryRead(out var item)) { switch (item) { case ConnectMessage connect: { DebugTools.Assert(IsServer); var writer = connect.ChannelWriter; var uid = _genConnectionUid(); var sessionId = new NetSessionId($"integration_{uid}"); var connectArgs = new NetConnectingArgs(sessionId, new IPEndPoint(IPAddress.IPv6Loopback, 0)); Connecting?.Invoke(this, connectArgs); if (connectArgs.Deny) { writer.TryWrite(new DeniedConnectMessage()); continue; } writer.TryWrite(new ConfirmConnectMessage(uid, sessionId)); var channel = new IntegrationNetChannel(this, connect.ChannelWriter, uid, sessionId); _channels.Add(uid, channel); Connected?.Invoke(this, new NetChannelArgs(channel)); break; } case DataMessage data: { IntegrationNetChannel channel; if (IsServer) { if (!_channels.TryGetValue(data.Connection, out channel)) { continue; } } else { channel = ServerChannel; } var message = data.Message; message.MsgChannel = channel; if (_callbacks.TryGetValue(message.GetType(), out var callback)) { callback(message); } break; } case DisconnectMessage disconnect: { if (IsServer) { if (_channels.TryGetValue(disconnect.Connection, out var channel)) { Disconnect?.Invoke(this, new NetChannelArgs(channel)); _channels.Remove(disconnect.Connection); } } else { _channels.Clear(); } break; } case DeniedConnectMessage _: { DebugTools.Assert(IsClient); ConnectFailed?.Invoke(this, new NetConnectFailArgs("I didn't implement a deny reason!")); break; } case ConfirmConnectMessage confirm: { DebugTools.Assert(IsClient); var channel = new IntegrationNetChannel(this, NextConnectChannel, _genConnectionUid(), confirm.SessionId, confirm.AssignedUid); _channels.Add(channel.ConnectionUid, channel); Connected?.Invoke(this, new NetChannelArgs(channel)); break; } default: throw new ArgumentOutOfRangeException(); } } }
public Texture LoadTextureFromImage <T>(Image <T> image, string?name = null, TextureLoadParameters?loadParams = null) where T : unmanaged, IPixel <T> { DebugTools.Assert(_mainThread == Thread.CurrentThread); var actualParams = loadParams ?? TextureLoadParameters.Default; var pixelType = typeof(T); if (!_hasGLTextureSwizzle) { // If texture swizzle isn't available we have to pre-process the images to apply it ourselves // and then upload as RGBA8. // Yes this is inefficient but the alternative is modifying the shaders, // which I CBA to do. // Even 8 year old iGPUs support texture swizzle. if (pixelType == typeof(A8)) { // Disable sRGB so stuff doesn't get interpreter wrong. actualParams.Srgb = false; var img = ApplyA8Swizzle((Image <A8>)(object) image); return(LoadTextureFromImage(img, name, loadParams)); } if (pixelType == typeof(L8) && !actualParams.Srgb) { var img = ApplyL8Swizzle((Image <L8>)(object) image); return(LoadTextureFromImage(img, name, loadParams)); } } // Flip image because OpenGL reads images upside down. var copy = FlipClone(image); var texture = new GLHandle((uint)GL.GenTexture()); CheckGlError(); GL.BindTexture(TextureTarget.Texture2D, texture.Handle); CheckGlError(); ApplySampleParameters(actualParams.SampleParameters); PixelInternalFormat internalFormat; PixelFormat pixelDataFormat; PixelType pixelDataType; bool isActuallySrgb = false; if (pixelType == typeof(Rgba32)) { // Note that if _hasGLSrgb is off, we import an sRGB texture as non-sRGB. // Shaders are expected to compensate for this internalFormat = (actualParams.Srgb && _hasGLSrgb) ? PixelInternalFormat.Srgb8Alpha8 : PixelInternalFormat.Rgba8; isActuallySrgb = actualParams.Srgb; pixelDataFormat = PixelFormat.Rgba; pixelDataType = PixelType.UnsignedByte; } else if (pixelType == typeof(A8)) { if (image.Width % 4 != 0 || image.Height % 4 != 0) { throw new ArgumentException("Alpha8 images must have multiple of 4 sizes."); } internalFormat = PixelInternalFormat.R8; pixelDataFormat = PixelFormat.Red; pixelDataType = PixelType.UnsignedByte; unsafe { // TODO: Does it make sense to default to 1 for RGB parameters? // It might make more sense to pass some options to change swizzling. var swizzle = stackalloc[] { (int)All.One, (int)All.One, (int)All.One, (int)All.Red }; GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleRgba, swizzle); } } else if (pixelType == typeof(L8) && !actualParams.Srgb) { // Can only use R8 for L8 if sRGB is OFF. // Because OpenGL doesn't provide sRGB single/dual channel image formats. // Vulkan when? if (copy.Width % 4 != 0 || copy.Height % 4 != 0) { throw new ArgumentException("L8 non-sRGB images must have multiple of 4 sizes."); } internalFormat = PixelInternalFormat.R8; pixelDataFormat = PixelFormat.Red; pixelDataType = PixelType.UnsignedByte; unsafe { var swizzle = stackalloc[] { (int)All.Red, (int)All.Red, (int)All.Red, (int)All.One }; GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleRgba, swizzle); } } else { throw new NotImplementedException($"Unable to handle pixel type '{pixelType.Name}'"); } unsafe { var span = copy.GetPixelSpan(); fixed(T *ptr = span) { GL.TexImage2D(TextureTarget.Texture2D, 0, internalFormat, copy.Width, copy.Height, 0, pixelDataFormat, pixelDataType, (IntPtr)ptr); CheckGlError(); } } var pressureEst = EstPixelSize(internalFormat) * copy.Width * copy.Height; return(GenTexture(texture, (copy.Width, copy.Height), isActuallySrgb, name, pressureEst)); }
private void OnConnectFailed(object?sender, NetConnectFailArgs args) { DebugTools.Assert(RunLevel == ClientRunLevel.Connecting); Reset(); }
/// <inheritdoc /> public void StopSinglePlayer() { DebugTools.Assert(RunLevel == ClientRunLevel.SinglePlayerGame); DebugTools.Assert(!_net.IsConnected); GameStoppedReset(); }
private RenderTarget CreateRenderTarget(Vector2i size, RenderTargetFormatParameters format, TextureSampleParameters?sampleParameters = null, string?name = null) { // Cache currently bound framebuffers // so if somebody creates a framebuffer while drawing it won't ruin everything. var boundDrawBuffer = GL.GetInteger(GetPName.DrawFramebufferBinding); var boundReadBuffer = GL.GetInteger(GetPName.ReadFramebufferBinding); // Generate FBO. var fbo = new GLHandle(GL.GenFramebuffer()); // Bind color attachment to FBO. GL.BindFramebuffer(FramebufferTarget.Framebuffer, fbo.Handle); ObjectLabelMaybe(ObjectLabelIdentifier.Framebuffer, fbo, name); var(width, height) = size; ClydeTexture textureObject; GLHandle depthStencilBuffer = default; // Color attachment. { var texture = new GLHandle(GL.GenTexture()); GL.BindTexture(TextureTarget.Texture2D, texture.Handle); ApplySampleParameters(sampleParameters); var internalFormat = format.ColorFormat switch { RenderTargetColorFormat.Rgba8 => PixelInternalFormat.Rgba8, RenderTargetColorFormat.Rgba16F => PixelInternalFormat.Rgba16f, RenderTargetColorFormat.Rgba8Srgb => PixelInternalFormat.Srgb8Alpha8, RenderTargetColorFormat.R11FG11FB10F => PixelInternalFormat.R11fG11fB10f, RenderTargetColorFormat.R32F => PixelInternalFormat.R32f, RenderTargetColorFormat.RG32F => PixelInternalFormat.Rg32f, RenderTargetColorFormat.R8 => PixelInternalFormat.R8, _ => throw new ArgumentOutOfRangeException(nameof(format.ColorFormat), format.ColorFormat, null) }; GL.TexImage2D(TextureTarget.Texture2D, 0, internalFormat, width, height, 0, PixelFormat.Red, PixelType.Byte, IntPtr.Zero); GL.FramebufferTexture(FramebufferTarget.Framebuffer, FramebufferAttachment.ColorAttachment0, texture.Handle, 0); textureObject = GenTexture(texture, size, name == null ? null : $"{name}-color"); } // Depth/stencil buffers. if (format.HasDepthStencil) { depthStencilBuffer = new GLHandle(GL.GenRenderbuffer()); GL.BindRenderbuffer(RenderbufferTarget.Renderbuffer, depthStencilBuffer.Handle); ObjectLabelMaybe(ObjectLabelIdentifier.Renderbuffer, depthStencilBuffer, name == null ? null : $"{name}-depth-stencil"); GL.RenderbufferStorage(RenderbufferTarget.Renderbuffer, RenderbufferStorage.Depth24Stencil8, width, height); GL.FramebufferRenderbuffer(FramebufferTarget.Framebuffer, FramebufferAttachment.DepthStencilAttachment, RenderbufferTarget.Renderbuffer, depthStencilBuffer.Handle); } // This should always pass but OpenGL makes it easy to check for once so let's. var status = GL.CheckFramebufferStatus(FramebufferTarget.Framebuffer); DebugTools.Assert(status == FramebufferErrorCode.FramebufferComplete, $"new framebuffer has bad status {status}"); // Re-bind previous framebuffers. GL.BindFramebuffer(FramebufferTarget.DrawFramebuffer, boundDrawBuffer); GL.BindFramebuffer(FramebufferTarget.ReadFramebuffer, boundReadBuffer); var handle = AllocRid(); var renderTarget = new RenderTarget(size, textureObject, fbo, this, handle, depthStencilBuffer); _renderTargets.Add(handle, renderTarget); return(renderTarget); }
public Texture LoadTextureFromImage <T>(Image <T> image, string name = null, TextureLoadParameters?loadParams = null) where T : unmanaged, IPixel <T> { DebugTools.Assert(_mainThread == Thread.CurrentThread); var actualParams = loadParams ?? TextureLoadParameters.Default; var pixelType = typeof(T); var texture = new OGLHandle((uint)GL.GenTexture()); GL.BindTexture(TextureTarget.Texture2D, texture.Handle); _applySampleParameters(actualParams.SampleParameters); PixelInternalFormat internalFormat; PixelFormat pixelDataFormat; PixelType pixelDataType; if (pixelType == typeof(Rgba32)) { internalFormat = actualParams.Srgb ? PixelInternalFormat.Srgb8Alpha8 : PixelInternalFormat.Rgba8; pixelDataFormat = PixelFormat.Rgba; pixelDataType = PixelType.UnsignedByte; } else if (pixelType == typeof(Alpha8)) { if (image.Width % 4 != 0 || image.Height % 4 != 0) { throw new ArgumentException("Alpha8 images must have multiple of 4 sizes."); } internalFormat = PixelInternalFormat.R8; pixelDataFormat = PixelFormat.Red; pixelDataType = PixelType.UnsignedByte; // TODO: Does it make sense to default to 1 for RGB parameters? // It might make more sense to pass some options to change swizzling. var swizzle = new[] { (int)All.One, (int)All.One, (int)All.One, (int)All.Red }; GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleRgba, swizzle); } else if (pixelType == typeof(Gray8) && !actualParams.Srgb) { // Can only use R8 for Gray8 if sRGB is OFF. // Because OpenGL doesn't provide non-sRGB single/dual channel image formats. // Vulkan when? if (image.Width % 4 != 0 || image.Height % 4 != 0) { throw new ArgumentException("Gray8 non-sRGB images must have multiple of 4 sizes."); } internalFormat = PixelInternalFormat.R8; pixelDataFormat = PixelFormat.Red; pixelDataType = PixelType.UnsignedByte; var swizzle = new[] { (int)All.Red, (int)All.Red, (int)All.Red, (int)All.One }; GL.TexParameter(TextureTarget.Texture2D, TextureParameterName.TextureSwizzleRgba, swizzle); } else { throw new NotImplementedException($"Unable to handle pixel type '{pixelType.Name}'"); } unsafe { var span = image.GetPixelSpan(); fixed(T *ptr = span) { GL.TexImage2D(TextureTarget.Texture2D, 0, internalFormat, image.Width, image.Height, 0, pixelDataFormat, pixelDataType, (IntPtr)ptr); } } return(_genTexture(texture, (image.Width, image.Height), name)); }
private DockingComponent?GetDockable(PhysicsComponent body, TransformComponent dockingXform) { // Did you know Saltern is the most dockable station? // Assume the docking port itself (and its body) is valid if (!_mapManager.TryGetGrid(dockingXform.GridID, out var grid) || !EntityManager.HasComponent <ShuttleComponent>(grid.GridEntityId)) { return(null); } var transform = body.GetTransform(); var dockingFixture = _fixtureSystem.GetFixtureOrNull(body, DockingFixture); if (dockingFixture == null) { DebugTools.Assert(false); Logger.ErrorS("docking", $"Found null fixture on {(body).Owner}"); return(null); } Box2?aabb = null; for (var i = 0; i < dockingFixture.Shape.ChildCount; i++) { aabb = aabb?.Union(dockingFixture.Shape.ComputeAABB(transform, i)) ?? dockingFixture.Shape.ComputeAABB(transform, i); } if (aabb == null) { return(null); } var enlargedAABB = aabb.Value.Enlarged(DockingRadius * 1.5f); // Get any docking ports in range on other grids. _mapManager.FindGridsIntersectingEnumerator(dockingXform.MapID, enlargedAABB, out var enumerator); while (enumerator.MoveNext(out var otherGrid)) { if (otherGrid.Index == dockingXform.GridID) { continue; } foreach (var ent in otherGrid.GetAnchoredEntities(enlargedAABB)) { if (!EntityManager.TryGetComponent(ent, out DockingComponent? otherDocking) || !otherDocking.Enabled || !EntityManager.TryGetComponent(ent, out PhysicsComponent? otherBody)) { continue; } var otherTransform = otherBody.GetTransform(); var otherDockingFixture = _fixtureSystem.GetFixtureOrNull(otherBody, DockingFixture); if (otherDockingFixture == null) { DebugTools.Assert(false); Logger.ErrorS("docking", $"Found null docking fixture on {ent}"); continue; } for (var i = 0; i < otherDockingFixture.Shape.ChildCount; i++) { var otherAABB = otherDockingFixture.Shape.ComputeAABB(otherTransform, i); if (!aabb.Value.Intersects(otherAABB)) { continue; } // TODO: Need CollisionManager's GJK for accurate bounds // Realistically I want 2 fixtures anyway but I'll deal with that later. return(otherDocking); } } } return(null); }
/// <summary> /// Constructs a new instance of the given type, and return it cast to the specified type. /// </summary> /// <param name="dynamicTypeFactory">The dynamic type factory to use.</param> /// <param name="type">The type to instantiate.</param> /// <param name="args">The arguments to pass to the constructor.</param> /// <typeparam name="T">The type that the instance will be cast to.</typeparam> /// <returns>Newly created object, cast to <typeparamref name="T"/>.</returns> public static T CreateInstance <T>(this IDynamicTypeFactory dynamicTypeFactory, Type type, object[] args) { DebugTools.Assert(typeof(T).IsAssignableFrom(type), "type must be subtype of T"); return((T)dynamicTypeFactory.CreateInstance(type, args)); }
public void Shutdown() { DebugTools.Assert(_impl != null, "WebViewManager has not yet been initialized!"); _impl !.Shutdown(); }
public VVPropEditor SetProperty(ViewVariablesBlobMembers.MemberData member) { NameLabel.Text = member.Name; var type = Type.GetType(member.Type); _bottomLabel.Text = $"Type: {member.TypePretty}"; VVPropEditor editor; if (type == null || !_robustSerializer.CanSerialize(type)) { // Type is server-side only. // Info whether it's reference or value type can be figured out from the sent value. if (type?.IsValueType == true || member.Value is ViewVariablesBlobMembers.ServerValueTypeToken) { // Value type, just display it stringified read-only. editor = new VVPropEditorDummy(); } else { // Has to be a reference type at this point. DebugTools.Assert(member.Value is ViewVariablesBlobMembers.ReferenceToken || member.Value == null || type?.IsClass == true || type?.IsInterface == true); editor = _viewVariablesManager.PropertyFor(type ?? typeof(object)); } } else { editor = _viewVariablesManager.PropertyFor(type); } var view = editor.Initialize(member.Value, !member.Editable); if (!view.HorizontalExpand) { NameLabel.HorizontalExpand = true; } NameLabel.MinSize = new Vector2(150, 0); TopContainer.AddChild(view); /* * _beingEdited = obj; * _editedProperty = propertyInfo; * DebugTools.Assert(propertyInfo.DeclaringType != null); * DebugTools.Assert(propertyInfo.DeclaringType.IsInstanceOfType(obj)); * * DebugTools.Assert(ViewVariablesUtility.TryGetViewVariablesAccess(fieldInfo, out var access)); * NameLabel.Text = propertyInfo.Name; * * _bottomLabel.Text = $"Type: {propertyInfo.PropertyType.FullName}"; * * var editor = vvm.PropertyFor(propertyInfo.PropertyType); * var value = propertyInfo.GetValue(obj); * * var view = editor.Initialize(value, access != VVAccess.ReadWrite); * if (view.SizeFlagsHorizontal != SizeFlags.FillExpand) * { * NameLabel.HorizontalExpand = true; * } * NameLabel.MinSize = new Vector2(150, 0); * TopContainer.AddChild(view); * editor.OnValueChanged += v => { propertyInfo.SetValue(obj, v); }; */ return(editor); }
public IWebViewControlImpl MakeControlImpl(WebViewControl owner) { DebugTools.Assert(_impl != null, "WebViewManager has not yet been initialized!"); return(_impl !.MakeControlImpl(owner)); }
private void ExcitedGroupResetCooldowns(ExcitedGroup excitedGroup) { DebugTools.Assert(!excitedGroup.Disposed, "Excited group is disposed!"); excitedGroup.BreakdownCooldown = 0; excitedGroup.DismantleCooldown = 0; }
private void ProcessGraphUpdates() { var totalUpdates = 0; foreach (var update in _collidableUpdateQueue) { var entity = EntityManager.GetEntity(update.Owner); if (update.CanCollide) { HandleEntityAdd(entity); } else { HandleEntityRemove(entity); } totalUpdates++; } _collidableUpdateQueue.Clear(); foreach (var update in _accessReaderUpdateQueue) { if (update.Enabled) { HandleEntityAdd(update.Sender); } else { HandleEntityRemove(update.Sender); } totalUpdates++; } _accessReaderUpdateQueue.Clear(); foreach (var tile in _tileUpdateQueue) { HandleTileUpdate(tile); totalUpdates++; } _tileUpdateQueue.Clear(); var moveUpdateCount = Math.Max(50 - totalUpdates, 0); // Other updates are high priority so for this we'll just defer it if there's a spike (explosion, etc.) // If the move updates grow too large then we'll just do it if (_moveUpdateQueue.Count > 100) { moveUpdateCount = _moveUpdateQueue.Count - 100; } moveUpdateCount = Math.Min(moveUpdateCount, _moveUpdateQueue.Count); for (var i = 0; i < moveUpdateCount; i++) { HandleEntityMove(_moveUpdateQueue.Dequeue()); } DebugTools.Assert(_moveUpdateQueue.Count < 1000); }
/// <inheritdoc /> public void AddComponent <T>(IEntity entity, T component, bool overwrite = false) where T : Component { if (entity == null || !entity.IsValid()) { throw new ArgumentException("Entity is not valid.", nameof(entity)); } if (component == null) { throw new ArgumentNullException(nameof(component)); } if (component.Owner != entity) { throw new InvalidOperationException("Component is not owned by entity."); } var uid = entity.Uid; // get interface aliases for mapping var reg = _componentFactory.GetRegistration(component); // Check that there are no overlapping references. foreach (var type in reg.References) { if (!TryGetComponent(uid, type, out var duplicate)) { continue; } if (!overwrite) { throw new InvalidOperationException( $"Component reference type {type} already occupied by {duplicate}"); } // these two components are required on all entities and cannot be overwritten. if (duplicate is ITransformComponent || duplicate is IMetaDataComponent) { throw new InvalidOperationException("Tried to overwrite a protected component."); } RemoveComponentImmediate((Component)duplicate); } // add the component to the grid foreach (var type in reg.References) { _entTraitDict[type].Add(uid, component); _entCompIndex.Add(uid, component); } // add the component to the netId grid if (component.NetID != null) { // the main comp grid keeps this in sync var netId = component.NetID.Value; _entNetIdDict[netId].Add(uid, component); // mark the component as dirty for networking component.Dirty(); ComponentAdded?.Invoke(this, new AddedComponentEventArgs(component)); } component.ExposeData(DefaultValueSerializer.Reader()); component.OnAdd(); if (!entity.Initialized && !entity.Initializing) { return; } component.Initialize(); DebugTools.Assert(component.Initialized, "Component is not initialized after calling Initialize(). " + "Did you forget to call base.Initialize() in an override?"); if (entity.Initialized) { component.Running = true; } }
private static void HandleEntityState(IComponentManager compMan, IEntity entity, EntityState curState, EntityState nextState) { var compStateWork = new Dictionary <uint, (ComponentState curState, ComponentState nextState)>(); var entityUid = entity.Uid; if (curState?.ComponentChanges != null) { foreach (var compChange in curState.ComponentChanges) { if (compChange.Deleted) { if (compMan.TryGetComponent(entityUid, compChange.NetID, out var comp)) { compMan.RemoveComponent(entityUid, comp); } } else { if (compMan.HasComponent(entityUid, compChange.NetID)) { continue; } var newComp = (Component)IoCManager.Resolve <IComponentFactory>().GetComponent(compChange.ComponentName); newComp.Owner = entity; compMan.AddComponent(entity, newComp, true); } } } if (curState?.ComponentStates != null) { foreach (var compState in curState.ComponentStates) { compStateWork[compState.NetID] = (compState, null); } } if (nextState?.ComponentStates != null) { foreach (var compState in nextState.ComponentStates) { if (compStateWork.TryGetValue(compState.NetID, out var state)) { compStateWork[compState.NetID] = (state.curState, compState); } else { compStateWork[compState.NetID] = (null, compState); } } } foreach (var kvStates in compStateWork) { if (!compMan.TryGetComponent(entityUid, kvStates.Key, out var component)) { DebugTools.Assert("Component does not exist for state."); continue; } try { component.HandleComponentState(kvStates.Value.curState, kvStates.Value.nextState); } catch (Exception e) { Logger.ErrorS("entity", $"Failed to apply comp state: entity={component.Owner}, comp={component.Name}\n {e}"); DebugTools.Assert(e.Message); } } }
private async Task _moveToPage(int page) { // TODO: Network overhead optimization potential: // Right now, (in NETWORK mode) if I request page 5, it has to cache all 5 pages, // now the server obviously (enumerator and all that) has to TOO, but whatever. // The waste is that all pages are also SENT, even though we only really care about the fifth at the moment. // Because the cache can't have holes (and also the network system is too simplistic at the moment, // if you do do a by-page pull and you're way too far along, // you'll just get 0 elements which doesn't tell you where it ended but that's kinda necessary. if (page < 0) { page = 0; } if (page > HighestKnownPage || (!_ended && page == HighestKnownPage)) { if (_ended) { // The requested page is higher than the highest page we have (and we know this because the enumerator ended). page = HighestKnownPage; } else { // The page is higher than the highest page we have, but the enumerator hasn't ended yet so that might be valid. // Gotta get more data. await _cacheTo((page + 1) *ElementsPerPage); if (page > HighestKnownPage) { // We tried, but the enumerator ended before we reached our goal. // Oh well. DebugTools.Assert(_ended); page = HighestKnownPage; } } } _elementsVBox.DisposeAllChildren(); for (var i = page * ElementsPerPage; i < ElementsPerPage * (page + 1) && i < _cache.Count; i++) { var element = _cache[i]; ViewVariablesPropertyEditor editor; if (element == null) { editor = new ViewVariablesPropertyEditorDummy(); } else { var type = element.GetType(); editor = Instance.ViewVariablesManager.PropertyFor(type); } var control = editor.Initialize(element, true); if (editor is ViewVariablesPropertyEditorReference refEditor) { if (_networked) { var iSafe = i; refEditor.OnPressed += () => Instance.ViewVariablesManager.OpenVV( new ViewVariablesSessionRelativeSelector(Instance.Session !.SessionId, new object[] { new ViewVariablesEnumerableIndexSelector(iSafe), })); } else { refEditor.OnPressed += () => Instance.ViewVariablesManager.OpenVV(element !); } } _elementsVBox.AddChild(control); } _page = page; _updateControls(); }
/// <inheritdoc /> public virtual bool CanRemove(IEntity toremove) { DebugTools.Assert(!Deleted); return(Contains(toremove)); }
/// <summary> /// Docks 2 ports together and assumes it is valid. /// </summary> public void Dock(DockingComponent dockA, DockingComponent dockB) { if (dockB.Owner.GetHashCode() < dockA.Owner.GetHashCode()) { (dockA, dockB) = (dockB, dockA); } _sawmill.Debug($"Docking between {dockA.Owner} and {dockB.Owner}"); // https://gamedev.stackexchange.com/questions/98772/b2distancejoint-with-frequency-equal-to-0-vs-b2weldjoint // We could also potentially use a prismatic joint? Depending if we want clamps that can extend or whatever var dockAXform = EntityManager.GetComponent <TransformComponent>(dockA.Owner); var dockBXform = EntityManager.GetComponent <TransformComponent>(dockB.Owner); DebugTools.Assert(dockAXform.GridUid != null); DebugTools.Assert(dockBXform.GridUid != null); var gridA = dockAXform.GridUid !.Value; var gridB = dockBXform.GridUid !.Value; SharedJointSystem.LinearStiffness( 2f, 0.7f, EntityManager.GetComponent <PhysicsComponent>(gridA).Mass, EntityManager.GetComponent <PhysicsComponent>(gridB).Mass, out var stiffness, out var damping); // These need playing around with // Could also potentially have collideconnected false and stiffness 0 but it was a bit more suss??? WeldJoint joint; // Pre-existing joint so use that. if (dockA.DockJointId != null) { DebugTools.Assert(dockB.DockJointId == dockA.DockJointId); joint = _jointSystem.GetOrCreateWeldJoint(gridA, gridB, dockA.DockJointId); } else { joint = _jointSystem.GetOrCreateWeldJoint(gridA, gridB, DockingJoint + dockA.Owner); } var gridAXform = EntityManager.GetComponent <TransformComponent>(gridA); var gridBXform = EntityManager.GetComponent <TransformComponent>(gridB); var anchorA = dockAXform.LocalPosition + dockAXform.LocalRotation.ToWorldVec() / 2f; var anchorB = dockBXform.LocalPosition + dockBXform.LocalRotation.ToWorldVec() / 2f; joint.LocalAnchorA = anchorA; joint.LocalAnchorB = anchorB; joint.ReferenceAngle = (float)(gridBXform.WorldRotation - gridAXform.WorldRotation); joint.CollideConnected = true; joint.Stiffness = stiffness; joint.Damping = damping; dockA.DockedWith = dockB.Owner; dockB.DockedWith = dockA.Owner; dockA.DockJoint = joint; dockA.DockJointId = joint.ID; dockB.DockJoint = joint; dockB.DockJointId = joint.ID; if (TryComp <AirlockComponent>(dockA.Owner, out var airlockA)) { airlockA.SetBoltsWithAudio(true); } if (TryComp <AirlockComponent>(dockB.Owner, out var airlockB)) { airlockB.SetBoltsWithAudio(true); } if (TryComp(dockA.Owner, out DoorComponent? doorA)) { doorA.ChangeAirtight = false; _doorSystem.StartOpening(doorA.Owner, doorA); } if (TryComp(dockB.Owner, out DoorComponent? doorB)) { doorB.ChangeAirtight = false; _doorSystem.StartOpening(doorB.Owner, doorB); } var msg = new DockEvent { DockA = dockA, DockB = dockB, GridAUid = gridA, GridBUid = gridB, }; EntityManager.EventBus.RaiseLocalEvent(dockA.Owner, msg, false); EntityManager.EventBus.RaiseLocalEvent(dockB.Owner, msg, false); EntityManager.EventBus.RaiseEvent(EventSource.Local, msg); }
/// <inheritdoc /> public void ForceRemove(IEntity toRemove) { DebugTools.Assert(!Deleted); InternalRemove(toRemove); }
private static IRsiStateLike TextureForConfig(ObjectSerializer serializer, IResourceCache resourceCache) { DebugTools.Assert(serializer.Reading); if (serializer.TryGetCacheData <IRsiStateLike>(SerializationCache, out var dirTex)) { return(dirTex); } var tex = serializer.ReadDataField <string?>("texture", null); if (!string.IsNullOrWhiteSpace(tex)) { dirTex = resourceCache.GetResource <TextureResource>(SpriteComponent.TextureRoot / tex).Texture; serializer.SetCacheData(SerializationCache, dirTex); return(dirTex); } RSI rsi; var rsiPath = serializer.ReadDataField <string?>("sprite", null); if (string.IsNullOrWhiteSpace(rsiPath)) { dirTex = resourceCache.GetFallback <TextureResource>().Texture; serializer.SetCacheData(SerializationCache, dirTex); return(dirTex); } var path = SpriteComponent.TextureRoot / rsiPath; try { rsi = resourceCache.GetResource <RSIResource>(path).RSI; } catch { dirTex = resourceCache.GetFallback <TextureResource>().Texture; serializer.SetCacheData(SerializationCache, dirTex); return(dirTex); } var stateId = serializer.ReadDataField <string?>("state", null); if (string.IsNullOrWhiteSpace(stateId)) { Logger.ErrorS(LogCategory, "No state specified."); dirTex = resourceCache.GetFallback <TextureResource>().Texture; serializer.SetCacheData(SerializationCache, dirTex); return(dirTex); } if (rsi.TryGetState(stateId, out var state)) { serializer.SetCacheData(SerializationCache, state); return(state); } else { Logger.ErrorS(LogCategory, "State '{0}' does not exist on RSI.", stateId); return(resourceCache.GetFallback <TextureResource>().Texture); } }