TASK 3 milestone 1: webcam capture (MediaCapture CPU-first, CameraManager refcount, picker, clip/mirror, schema v2, tests)
This commit is contained in:
+44
-4
@@ -31,7 +31,7 @@ public class LayoutStore : IDisposable
|
||||
{
|
||||
string[] statements =
|
||||
{
|
||||
"PRAGMA user_version = 1;",
|
||||
"PRAGMA user_version = 2;",
|
||||
"""
|
||||
CREATE TABLE IF NOT EXISTS Scene (
|
||||
Id TEXT PRIMARY KEY,
|
||||
@@ -65,6 +65,8 @@ public class LayoutStore : IDisposable
|
||||
Opacity REAL NOT NULL DEFAULT 1,
|
||||
MonitorIndex INTEGER,
|
||||
DeviceId TEXT,
|
||||
ClipShape TEXT NOT NULL DEFAULT 'Traditional',
|
||||
IsMirrored INTEGER NOT NULL DEFAULT 0,
|
||||
SortOrder INTEGER NOT NULL DEFAULT 0
|
||||
);
|
||||
""",
|
||||
@@ -75,6 +77,36 @@ public class LayoutStore : IDisposable
|
||||
cmd.CommandText = sql;
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
MigrateSourceTable();
|
||||
}
|
||||
|
||||
// v1 → v2: Source gains ClipShape + IsMirrored (webcam clip/mirror prefs).
|
||||
// CREATE TABLE IF NOT EXISTS doesn't touch existing tables, so pre-v2 DBs
|
||||
// get the columns here instead.
|
||||
private void MigrateSourceTable()
|
||||
{
|
||||
var columns = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
|
||||
using (var cmd = _connection.CreateCommand())
|
||||
{
|
||||
cmd.CommandText = "PRAGMA table_info(Source);";
|
||||
using var reader = cmd.ExecuteReader();
|
||||
while (reader.Read())
|
||||
columns.Add(reader.GetString(1));
|
||||
}
|
||||
|
||||
if (!columns.Contains("ClipShape"))
|
||||
{
|
||||
using var cmd = _connection.CreateCommand();
|
||||
cmd.CommandText = "ALTER TABLE Source ADD COLUMN ClipShape TEXT NOT NULL DEFAULT 'Traditional';";
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
if (!columns.Contains("IsMirrored"))
|
||||
{
|
||||
using var cmd = _connection.CreateCommand();
|
||||
cmd.CommandText = "ALTER TABLE Source ADD COLUMN IsMirrored INTEGER NOT NULL DEFAULT 0;";
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
}
|
||||
|
||||
public List<Scene> Load()
|
||||
@@ -102,7 +134,7 @@ public class LayoutStore : IDisposable
|
||||
{
|
||||
cmd.CommandText = """
|
||||
SELECT Id, SceneId, AssetId, Type, Name, IsEnabled,
|
||||
X, Y, Width, Height, Opacity, MonitorIndex, DeviceId
|
||||
X, Y, Width, Height, Opacity, MonitorIndex, DeviceId, ClipShape, IsMirrored
|
||||
FROM Source ORDER BY SortOrder
|
||||
""";
|
||||
using var reader = cmd.ExecuteReader();
|
||||
@@ -123,6 +155,8 @@ public class LayoutStore : IDisposable
|
||||
Opacity = reader.GetDouble(10),
|
||||
MonitorIndex = reader.IsDBNull(11) ? null : reader.GetInt32(11),
|
||||
DeviceId = reader.IsDBNull(12) ? null : reader.GetString(12),
|
||||
ClipShape = Enum.TryParse<ClipShape>(reader.GetString(13), out var clip) ? clip : ClipShape.Traditional,
|
||||
IsMirrored = reader.GetInt32(14) != 0,
|
||||
};
|
||||
if (!sourcesByScene.TryGetValue(sceneId, out var list))
|
||||
sourcesByScene[sceneId] = list = new List<Source>();
|
||||
@@ -185,9 +219,11 @@ public class LayoutStore : IDisposable
|
||||
{
|
||||
cmd.CommandText = """
|
||||
INSERT INTO Source (Id, SceneId, AssetId, Type, Name, IsEnabled,
|
||||
X, Y, Width, Height, Opacity, MonitorIndex, DeviceId, SortOrder)
|
||||
X, Y, Width, Height, Opacity, MonitorIndex, DeviceId,
|
||||
ClipShape, IsMirrored, SortOrder)
|
||||
VALUES ($id, $sceneId, $assetId, $type, $name, $isEnabled,
|
||||
$x, $y, $w, $h, $opacity, $monitor, $device, $sort)
|
||||
$x, $y, $w, $h, $opacity, $monitor, $device,
|
||||
$clip, $mirrored, $sort)
|
||||
""";
|
||||
cmd.Transaction = tx;
|
||||
var idP = cmd.Parameters.Add("$id", SqliteType.Text);
|
||||
@@ -203,6 +239,8 @@ public class LayoutStore : IDisposable
|
||||
var opacityP = cmd.Parameters.Add("$opacity", SqliteType.Real);
|
||||
var monitorP = cmd.Parameters.Add("$monitor", SqliteType.Integer);
|
||||
var deviceP = cmd.Parameters.Add("$device", SqliteType.Text);
|
||||
var clipP = cmd.Parameters.Add("$clip", SqliteType.Text);
|
||||
var mirroredP = cmd.Parameters.Add("$mirrored", SqliteType.Integer);
|
||||
var sortP = cmd.Parameters.Add("$sort", SqliteType.Integer);
|
||||
|
||||
foreach (var scene in scenes)
|
||||
@@ -223,6 +261,8 @@ public class LayoutStore : IDisposable
|
||||
opacityP.Value = source.Opacity;
|
||||
monitorP.Value = (object?)source.MonitorIndex ?? DBNull.Value;
|
||||
deviceP.Value = (object?)source.DeviceId ?? DBNull.Value;
|
||||
clipP.Value = source.ClipShape.ToString();
|
||||
mirroredP.Value = source.IsMirrored ? 1 : 0;
|
||||
sortP.Value = sort++;
|
||||
cmd.ExecuteNonQuery();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user