Exemple #1
0
 static void FillVolume(EnvironmentObjectBuilder env, IntBox volume, TileData data)
 {
     foreach (var p in volume.Range())
     {
         env.SetTileData(p, data);
     }
 }
Exemple #2
0
 public static IntVector3 GetRandomVectorInRange(IntBox boxRange)
 {
     return(new IntVector3(
                UnityEngine.Random.Range(boxRange.min.x, boxRange.max.x + 1),
                UnityEngine.Random.Range(boxRange.min.y, boxRange.max.y + 1),
                UnityEngine.Random.Range(boxRange.min.z, boxRange.max.z + 1)));
 }
Exemple #3
0
 public static IntVector3 GetRandomVectorInRange(IntBox boxRange, System.Random random)
 {
     return(new IntVector3(
                random.Next(boxRange.min.x, boxRange.max.x + 1),
                random.Next(boxRange.min.y, boxRange.max.y + 1),
                random.Next(boxRange.min.z, boxRange.max.z + 1)));
 }
 public void Set(IntBox area, T obj)
 {
     if (area.isEmpty)
     {
         return;
     }
     SetInternal(area, obj, root, rootLevel, range.min);
 }
 public void Remove(IntBox area)
 {
     if (area.isEmpty)
     {
         return;
     }
     RemoveInternal(area, root, rootLevel, range.min);
 }
    // Returns whether the node is changed.
    private bool RemoveInternal(IntBox area, OctreeNode <T> node, int level, IntVector3 corner)
    {
        IntBox nodeArea = new IntBox(corner, corner + ((1 << level) - 1) * IntVector3.one);

        if (area.Contains(nodeArea))
        {
            if (!node.isEmpty)
            {
                node.obj      = default(T);
                node.objCount = 0;
                node.RemoveChildren();
                return(true);
            }
            else
            {
                return(false);
            }
        }
        else if (!node.obj.Equals(default(T)))
        {
            node.Split();
        }

        int        childSize     = 1 << (level - 1);
        IntVector3 childIndexMin = IntVector3.Max((area.min - corner) / childSize, IntVector3.zero);
        IntVector3 childIndexMax = IntVector3.Min((area.max - corner) / childSize, IntVector3.one);
        bool       changed       = false;

        for (int x = childIndexMin.x; x <= childIndexMax.x; x++)
        {
            for (int y = childIndexMin.y; y <= childIndexMax.y; y++)
            {
                for (int z = childIndexMin.z; z <= childIndexMax.z; z++)
                {
                    IntVector3 childIndex = new IntVector3(x, y, z);
                    var        childNode  = node.GetChild(childIndex);
                    if (childNode != null)
                    {
                        long oldChildObjCount = childNode.objCount;
                        bool childChanged     = RemoveInternal(area, childNode, level - 1, corner + childIndex * childSize);
                        if (childChanged)
                        {
                            changed        = true;
                            node.objCount += childNode.objCount - oldChildObjCount;
                            if (childNode.isEmpty)
                            {
                                node.RemoveChild(childIndex);
                            }
                        }
                    }
                }
            }
        }
        return(changed);
    }
    // Returns whether the node is changed.
    private bool SetInternal(IntBox area, T obj, OctreeNode <T> node, int level, IntVector3 corner)
    {
        IntBox nodeArea = new IntBox(corner, corner + ((1 << level) - 1) * IntVector3.one);

        if (node.obj.Equals(obj))
        {
            return(false);
        }
        else if (area.Contains(nodeArea))
        {
            node.obj      = obj;
            node.objCount = 1 << level;
            node.RemoveChildren();
            return(true);
        }
        else if (node.isFilled)
        {
            node.Split();
        }

        int        childSize     = 1 << (level - 1);
        IntVector3 childIndexMin = IntVector3.Max((area.min - corner) / childSize, IntVector3.zero);
        IntVector3 childIndexMax = IntVector3.Min((area.max - corner) / childSize, IntVector3.one);
        bool       changed       = false;

        for (int x = childIndexMin.x; x <= childIndexMax.x; x++)
        {
            for (int y = childIndexMin.y; y <= childIndexMax.y; y++)
            {
                for (int z = childIndexMin.z; z <= childIndexMax.z; z++)
                {
                    IntVector3 childIndex = new IntVector3(x, y, z);
                    var        childNode  = node.GetChild(childIndex);
                    if (childNode == null)
                    {
                        childNode = node.CreateChild(childIndex);
                    }

                    long oldChildObjCount = childNode.objCount;
                    bool childChanged     = SetInternal(area, obj, childNode, level - 1, corner + childIndex * childSize);
                    if (childChanged)
                    {
                        changed        = true;
                        node.objCount += childNode.objCount - oldChildObjCount;
                        if (childNode.isFilled)
                        {
                            node.MergeIfPossible(obj);
                        }
                    }
                }
            }
        }
        return(changed);
    }
    public OctreeGrid(IntBox range)
    {
        if (range.isEmpty)
        {
            throw new System.Exception("Range is empty!");
        }
        this.range = range;
        IntVector3 size = range.size;

        rootLevel = ((uint)Mathf.Max(size.x, size.y, size.z) - 1).NumberOfBit();
        root      = new OctreeNode <T>();
    }
Exemple #9
0
 public static IntBox OuterBound(IntBox b1, IntBox b2)
 {
     if (b1.isEmpty)
     {
         return(b2);
     }
     if (b2.isEmpty)
     {
         return(b1);
     }
     return(new IntBox(IntVector3.Min(b1.min, b2.min), IntVector3.Max(b1.max, b2.max)));
 }
Exemple #10
0
 public bool Contains(IntBox other)
 {
     if (other.isEmpty)
     {
         return(true);
     }
     if (isEmpty)
     {
         return(false);
     }
     return(other.min >= min && other.max <= max);
 }
        public void Draw(ObservableCollection <BoxOverlay.Box> boxes, UploadBuffer upload, int mipmap, Size2 dim)
        {
            var    dev  = Device.Get();
            IntBox ibox = new IntBox();

            for (var i = 0; i < boxes.Count; i++)
            {
                var box = boxes[i];
                ibox.Color  = box.Color;
                ibox.Border = Math.Max(box.Border >> mipmap, 1);
                // calc integer start and end
                ibox.Start = box.Start.ToPixels(dim);
                ibox.End   = box.End.ToPixels(dim);

                upload.SetData(ibox);
                dev.Pixel.SetConstantBuffer(0, upload.Handle);
                dev.ContextHandle.DrawInstanced(4, 1, i * 4, 0);
            }
        }
Exemple #12
0
        public Tuple <SDS, IntermediateSDS> Complete()
        {
            //Log.Message("Finalize SDS g" + generation);

            var cs = data.localChangeSet.Clone();
            InconsistencyCoverage ic = data.ic.Clone();

            foreach (var n in Simulation.Neighbors)
            {
                IntBox box = n.ICImportRegion;

                var rcs = old.InboundRCS[n.LinearIndex];
                if (rcs != null)
                {
                    cs.Include(rcs.CS);
                    ic.Include(rcs.IC, box.Min);
                    if (rcs.IC.OneCount > 0)
                    {
                        Log.Message(n.Name + ": Inconsistent RCS @g" + generation + ": " + rcs.IC.OneCount);
                    }
                }
                else
                {
                    Log.Message(n.Name + ": Missing RCS @g" + generation);
                    ic.SetOne(box);
                }
            }
            EntityPool p2 = data.entities.Clone();

            cs.Execute(p2, ic, ctx);

            SDS rs = new SDS(generation, p2.ToArray(), ic);

#if !DRY_RUN
            if (!ic.AnySet)
            {
                DB.PutAsync(new SerialSDS(rs, Simulation.ID.XYZ), false).Wait();
            }
#endif
            Log.Message("Completed g" + Generation + " with IC ones: " + ic.OneCount + " " + Math.Round((float)ic.OneCount / ic.Size.Product * 100) + "%");
            return(new Tuple <SDS, IntermediateSDS>(rs, data));
        }
    public bool GotoChild(IntVector3 childIndex)
    {
        if (!node.isBranched)
        {
            return(false);
        }
        var child = node.GetChild(childIndex);

        if (child == null)
        {
            return(false);
        }

        path.Add(child);
        _level++;
        IntVector3 min = _range.min + childIndex * (1 << _level);

        _range = new IntBox(min, min + (1 << _level) * IntVector3.one);
        return(true);
    }
Exemple #14
0
    public static List <IntVector3> AffectedChunks(IntBox box)
    {
        int shift = VoxelTerrainConstants._shift;

        box.xMax++;
        box.yMax++;
        box.zMax++;
        List <IntVector3> retlist = new List <IntVector3> ();

        for (int x = (box.xMin >> shift); x <= (box.xMax >> shift); ++x)
        {
            for (int y = (box.yMin >> shift); y <= (box.yMax >> shift); ++y)
            {
                for (int z = (box.zMin >> shift); z <= (box.zMax >> shift); ++z)
                {
                    retlist.Add(new IntVector3(x, y, z));
                }
            }
        }
        return(retlist);
    }
Exemple #15
0
        static void SetupScenario(BaseDB.ConfigContainer cfg, IEnumerable <Entity> entities)
        {
            BaseDB.PutConfigAsync(cfg).Wait();
            //Simulation.Configure(new ShardID(), cfg, true);
            //if (DB.HasAdminAccess)
            InconsistencyCoverage.CommonResolution = (int)Math.Ceiling(1f / cfg.r);
            var clearTask = BaseDB.ClearSimulationDataAsync();

            SDSFactory[,,] grid = new SDSFactory[cfg.extent.X, cfg.extent.Y, cfg.extent.Z];
            cfg.extent.Cover(at =>
            {
                grid[at.X, at.Y, at.Z] = new SDSFactory(at, null /*new SimulationContext(false)*/, cfg.extent);
            }
                             );
            var gridBox         = IntBox.FromMinAndMax(Int3.Zero, cfg.extent, Bool3.False);
            var simulationSpace = Box.FromMinAndMax(Vec3.Zero, new Vec3(cfg.extent), Bool3.True);

            foreach (var e in entities)
            {
                if (!simulationSpace.Contains(e.ID.Position))
                {
                    throw new Exception("Scenario entity " + e + " is located outside simulation space");
                }
                var cell = gridBox.Clamp(e.ID.Position.FloorInt3);
                grid[cell.X, cell.Y, cell.Z].Include(e);
            }

            clearTask.Wait();
            Task[] tasks = new Task[cfg.extent.Product];
            int    idx   = 0;

            foreach (var factory in grid)
            {
                tasks[idx++] = DB.PutAsync(factory.Finish(), true);
            }

            Task.WaitAll(tasks);
        }
Exemple #16
0
 static void FillVolume(EnvironmentObjectBuilder env, IntBox volume, TileData data)
 {
     foreach (var p in volume.Range())
         env.SetTileData(p, data);
 }
Exemple #17
0
    public override void OnGL()
    {
        foreach (SelBox sbox in m_Boxes)
        {
            IntBox ibox = sbox.m_Box;
            Bounds box  = new Bounds(Vector3.zero, Vector3.zero);
            box.SetMinMax(new Vector3(ibox.xMin - 0.05f, ibox.yMin - 0.05f, ibox.zMin - 0.05f) * VCEditor.s_Scene.m_Setting.m_VoxelSize,
                          new Vector3(ibox.xMax + 1.05f, ibox.yMax + 1.05f, ibox.zMax + 1.05f) * VCEditor.s_Scene.m_Setting.m_VoxelSize);
            float sv = (float)(sbox.m_Val) / 255.0f;

            // Edge
            if (sv > 0.99f)
            {
                GL.Begin(GL.LINES);
                GL.Color(m_LineColor.Evaluate(sv));
                GL.Vertex3(box.min.x, box.min.y, box.min.z);
                GL.Vertex3(box.max.x, box.min.y, box.min.z);
                GL.Vertex3(box.min.x, box.min.y, box.max.z);
                GL.Vertex3(box.max.x, box.min.y, box.max.z);
                GL.Vertex3(box.min.x, box.max.y, box.min.z);
                GL.Vertex3(box.max.x, box.max.y, box.min.z);
                GL.Vertex3(box.min.x, box.max.y, box.max.z);
                GL.Vertex3(box.max.x, box.max.y, box.max.z);

                GL.Vertex3(box.min.x, box.min.y, box.min.z);
                GL.Vertex3(box.min.x, box.max.y, box.min.z);
                GL.Vertex3(box.min.x, box.min.y, box.max.z);
                GL.Vertex3(box.min.x, box.max.y, box.max.z);
                GL.Vertex3(box.max.x, box.min.y, box.min.z);
                GL.Vertex3(box.max.x, box.max.y, box.min.z);
                GL.Vertex3(box.max.x, box.min.y, box.max.z);
                GL.Vertex3(box.max.x, box.max.y, box.max.z);

                GL.Vertex3(box.min.x, box.min.y, box.min.z);
                GL.Vertex3(box.min.x, box.min.y, box.max.z);
                GL.Vertex3(box.min.x, box.max.y, box.min.z);
                GL.Vertex3(box.min.x, box.max.y, box.max.z);
                GL.Vertex3(box.max.x, box.min.y, box.min.z);
                GL.Vertex3(box.max.x, box.min.y, box.max.z);
                GL.Vertex3(box.max.x, box.max.y, box.min.z);
                GL.Vertex3(box.max.x, box.max.y, box.max.z);
                GL.End();
            }

            // Face
            GL.Begin(GL.QUADS);
            GL.Color(m_BoxColor.Evaluate(sv));
            GL.Vertex3(box.min.x, box.min.y, box.min.z);
            GL.Vertex3(box.min.x, box.min.y, box.max.z);
            GL.Vertex3(box.min.x, box.max.y, box.max.z);
            GL.Vertex3(box.min.x, box.max.y, box.min.z);

            GL.Vertex3(box.max.x, box.min.y, box.min.z);
            GL.Vertex3(box.max.x, box.min.y, box.max.z);
            GL.Vertex3(box.max.x, box.max.y, box.max.z);
            GL.Vertex3(box.max.x, box.max.y, box.min.z);

            GL.Vertex3(box.min.x, box.min.y, box.min.z);
            GL.Vertex3(box.min.x, box.min.y, box.max.z);
            GL.Vertex3(box.max.x, box.min.y, box.max.z);
            GL.Vertex3(box.max.x, box.min.y, box.min.z);

            GL.Vertex3(box.min.x, box.max.y, box.min.z);
            GL.Vertex3(box.min.x, box.max.y, box.max.z);
            GL.Vertex3(box.max.x, box.max.y, box.max.z);
            GL.Vertex3(box.max.x, box.max.y, box.min.z);

            GL.Vertex3(box.min.x, box.min.y, box.min.z);
            GL.Vertex3(box.min.x, box.max.y, box.min.z);
            GL.Vertex3(box.max.x, box.max.y, box.min.z);
            GL.Vertex3(box.max.x, box.min.y, box.min.z);

            GL.Vertex3(box.min.x, box.min.y, box.max.z);
            GL.Vertex3(box.min.x, box.max.y, box.max.z);
            GL.Vertex3(box.max.x, box.max.y, box.max.z);
            GL.Vertex3(box.max.x, box.min.y, box.max.z);
            GL.End();
        }
    }
Exemple #18
0
    public override void OnGL()
    {
        if (m_Center.x < -50)
        {
            return;
        }
        for (int x = -m_Expand; x <= m_Expand; ++x)
        {
            for (int y = -m_Expand; y <= m_Expand; ++y)
            {
                for (int z = -m_Expand; z <= m_Expand; ++z)
                {
                    IntVector3 pos = new IntVector3(x + m_Center.x, y + m_Center.y, z + m_Center.z);
                    if (VCEditor.s_Scene.m_IsoData.GetVoxel(VCIsoData.IPosToKey(pos)).Volume > 0)
                    {
                        IntBox ibox = new IntBox();
                        ibox.xMin = (short)pos.x; ibox.xMax = (short)pos.x;
                        ibox.yMin = (short)pos.y; ibox.yMax = (short)pos.y;
                        ibox.zMin = (short)pos.z; ibox.zMax = (short)pos.z;
                        Bounds box = new Bounds(Vector3.zero, Vector3.zero);
                        box.SetMinMax(new Vector3(ibox.xMin - 0.03f, ibox.yMin - 0.03f, ibox.zMin - 0.03f) * VCEditor.s_Scene.m_Setting.m_VoxelSize,
                                      new Vector3(ibox.xMax + 1.03f, ibox.yMax + 1.03f, ibox.zMax + 1.03f) * VCEditor.s_Scene.m_Setting.m_VoxelSize);
                        float sv = (float)(Mathf.Max(Mathf.Abs(x), Mathf.Abs(y), Mathf.Abs(z))) / (float)(m_Expand);

                        Color lc = m_BoxColors.Evaluate(sv);
                        Color bc = lc;
                        lc.a *= 1.5f;

                        // Edge
                        GL.Begin(GL.LINES);
                        GL.Color(lc);
                        GL.Vertex3(box.min.x, box.min.y, box.min.z);
                        GL.Vertex3(box.max.x, box.min.y, box.min.z);
                        GL.Vertex3(box.min.x, box.min.y, box.max.z);
                        GL.Vertex3(box.max.x, box.min.y, box.max.z);
                        GL.Vertex3(box.min.x, box.max.y, box.min.z);
                        GL.Vertex3(box.max.x, box.max.y, box.min.z);
                        GL.Vertex3(box.min.x, box.max.y, box.max.z);
                        GL.Vertex3(box.max.x, box.max.y, box.max.z);

                        GL.Vertex3(box.min.x, box.min.y, box.min.z);
                        GL.Vertex3(box.min.x, box.max.y, box.min.z);
                        GL.Vertex3(box.min.x, box.min.y, box.max.z);
                        GL.Vertex3(box.min.x, box.max.y, box.max.z);
                        GL.Vertex3(box.max.x, box.min.y, box.min.z);
                        GL.Vertex3(box.max.x, box.max.y, box.min.z);
                        GL.Vertex3(box.max.x, box.min.y, box.max.z);
                        GL.Vertex3(box.max.x, box.max.y, box.max.z);

                        GL.Vertex3(box.min.x, box.min.y, box.min.z);
                        GL.Vertex3(box.min.x, box.min.y, box.max.z);
                        GL.Vertex3(box.min.x, box.max.y, box.min.z);
                        GL.Vertex3(box.min.x, box.max.y, box.max.z);
                        GL.Vertex3(box.max.x, box.min.y, box.min.z);
                        GL.Vertex3(box.max.x, box.min.y, box.max.z);
                        GL.Vertex3(box.max.x, box.max.y, box.min.z);
                        GL.Vertex3(box.max.x, box.max.y, box.max.z);
                        GL.End();

                        // Face
                        GL.Begin(GL.QUADS);
                        GL.Color(bc);
                        GL.Vertex3(box.min.x, box.min.y, box.min.z);
                        GL.Vertex3(box.min.x, box.min.y, box.max.z);
                        GL.Vertex3(box.min.x, box.max.y, box.max.z);
                        GL.Vertex3(box.min.x, box.max.y, box.min.z);

                        GL.Vertex3(box.max.x, box.min.y, box.min.z);
                        GL.Vertex3(box.max.x, box.min.y, box.max.z);
                        GL.Vertex3(box.max.x, box.max.y, box.max.z);
                        GL.Vertex3(box.max.x, box.max.y, box.min.z);

                        GL.Vertex3(box.min.x, box.min.y, box.min.z);
                        GL.Vertex3(box.min.x, box.min.y, box.max.z);
                        GL.Vertex3(box.max.x, box.min.y, box.max.z);
                        GL.Vertex3(box.max.x, box.min.y, box.min.z);

                        GL.Vertex3(box.min.x, box.max.y, box.min.z);
                        GL.Vertex3(box.min.x, box.max.y, box.max.z);
                        GL.Vertex3(box.max.x, box.max.y, box.max.z);
                        GL.Vertex3(box.max.x, box.max.y, box.min.z);

                        GL.Vertex3(box.min.x, box.min.y, box.min.z);
                        GL.Vertex3(box.min.x, box.max.y, box.min.z);
                        GL.Vertex3(box.max.x, box.max.y, box.min.z);
                        GL.Vertex3(box.max.x, box.min.y, box.min.z);

                        GL.Vertex3(box.min.x, box.min.y, box.max.z);
                        GL.Vertex3(box.min.x, box.max.y, box.max.z);
                        GL.Vertex3(box.max.x, box.max.y, box.max.z);
                        GL.Vertex3(box.max.x, box.min.y, box.max.z);
                        GL.End();
                    }
                }
            }
        }
    }
Exemple #19
0
 public bool Intersects(IntBox other)
 {
     return(!Intersection(this, other).isEmpty);
 }
 public OctreeNodeNavigator(List <OctreeNode <T> > path, IntBox range, int level)
 {
     this.path = path;
     _range    = range;
     _level    = level;
 }
Exemple #21
0
 public void SetOne(IntBox box)
 {
     SetOne(box.Min, box.Size);
 }
Exemple #22
0
 public InconsistencyCoverage Sub(IntBox box)
 {
     return(Sub(box.Min, box.Size));
 }
Exemple #23
0
 public static IntBox Intersection(IntBox b1, IntBox b2)
 {
     return(new IntBox(IntVector3.Max(b1.min, b2.min), IntVector3.Min(b1.max, b2.max)));
 }
Exemple #24
0
        public SDSComputation(DateTime applicationBeginDeadline, ExtMessagePack clientMessages, TimeSpan entityLogicTimeout, EntityChange.ExecutionContext ctx)
        {
            this.ctx   = ctx;
            generation = ctx.GenerationNumber;
            Deadline   = applicationBeginDeadline;
            SDSStack stack = Simulation.Stack;

            SDSStack.Entry input = stack.FindGeneration(generation - 1);
            if (input == null)
            {
                throw new IntegrityViolation("Unable to locate previous SDS at generation " + (generation - 1));
            }
            if (!input.IsFinished)
            {
                throw new IntegrityViolation("Previous SDS at generation " + (generation - 1) + " exists but is not finished");
            }

            //if (input.Generation != generation-1)
            //	throw new IntegrityViolation("Generation mismatch");
            old = stack.FindGeneration(generation);
            if (old == null)
            {
                throw new IntegrityViolation("Unable to locate original SDS at generation " + generation);
            }

            data = new IntermediateSDS();
            data.inputConsistent = input.IsFullyConsistent;

            {
                using (var ms = new MemoryStream())
                {
                    input.SDS.AddToStream(ms);
                    clientMessages.AddToStream(ms);
                    ms.Seek(0, SeekOrigin.Begin);
                    data.inputHash = new Digest(SHA256.Create().ComputeHash(ms), true);
                }
            }


            //old bad or dont exist, new maybe good
            if (clientMessages.HasBeenDiscarded)
            {
                throw new IntegrityViolation("Available client messages are incomplete but recorded messages have been discarded");
            }
            this.clientMessages = clientMessages.MessagePack;

            if (old.IntermediateSDS != null && old.IntermediateSDS.inputHash == data.inputHash)
            {
                data = old.IntermediateSDS;
                return;
            }



            data.entities       = new EntityPool(input.SDS.FinalEntities, ctx);
            data.localChangeSet = new EntityChangeSet();
            data.ic             = input.SDS.IC.Clone();
            if (!this.clientMessages.Completed)
            {
                Log.Message("Client messages are not complete for generation " + generation + ", setting everything inconsistent");
                data.ic.SetAllOne();
            }
            //bool doSendClientMessages = freshClientMessages != null && freshClientMessages.ArchivedGeneration == generation;
            errors = data.localChangeSet.Evolve(input.SDS.FinalEntities, this.clientMessages.Messages, data.ic, entityLogicTimeout, ctx);
            if (errors == null && input.IsFullyConsistent && data.ic.OneCount != 0 && clientMessages.MessagePack.Completed)
            {
                throw new IntegrityViolation("Input is fully consistent, and there are no errors. IC should have remaining empty");
            }

            InconsistencyCoverage untrimmed = data.ic.Grow(false);

            if (untrimmed.Size != InconsistencyCoverage.CommonResolution + 2)
            {
                throw new IntegrityViolation("IC of unsupported size: " + untrimmed.Size);
            }
            data.ic = untrimmed.Sub(new Int3(1), new Int3(InconsistencyCoverage.CommonResolution));



            foreach (var n in Simulation.Neighbors)
            {
                IntBox remoteBox = n.ICExportRegion;
                var    ic        = untrimmed.Sub(remoteBox);
                RCS    rcs       = new RCS(new EntityChangeSet(data.localChangeSet, n.WorldSpace, ctx), ic);
                var    oID       = n.GetOutboundRCSID(Generation);
                if (generation >= n.OldestGeneration)
                {
                    Log.Message("Dispatched " + oID + ", IC ones=" + ic.OneCount);
                    n.Set(oID.ToString(), new RCS.Serial(rcs, generation));
                    if (rcs.IsFullyConsistent)
                    {
                        n.UploadToDB(generation, rcs);
                    }
                }
                else
                {
                    Log.Error("Recomputed generation, but remote shard will not want generated RCS");
                }
            }
            data.localChangeSet.FilterByTargetLocation(Simulation.MySpace, ctx);
        }
        /// <summary>
        /// This is a javascript application.
        /// </summary>
        /// <param name="page">HTML document rendered by the web server which can now be enhanced.</param>
        public Application(IApp page)
        {
            // a linked list builder

            #region title
            Native.document.ontitlechanged +=
                delegate
                {
                    page.topic.value = Native.document.title;
                };

            page.topic.onchange +=
                delegate
                {
                    Native.document.title = page.topic.value;
                };
            #endregion


            #region onscroll
            page.content.onscroll +=
                delegate
                {
                    //                c = nyMABtNdQz66ZYUODttTfw(new Number((-a[0].page.RAAABuvXAzazmyjb19NBig().scrollTop)), 'px');
                    //ugcABL0v_bj2Oe_a3KkOpn0g.title = (new ctor$UQAABt6szjCsnB_aL9_aJaIQ(c, a[0].page.RgAABuvXAzazmyjb19NBig().scrollTop)+'');

                    var scrollTop = page.content.scrollTop;

                    var marginTop = (-scrollTop) + "px";

                    //Native.document.title = new { marginTop, scrollTop }.ToString();

                    page.contentinfo.style.marginTop = marginTop;

                };
            #endregion

            var yx = 0;
            var y = 0;
            var i = -1;


            // http://www.w3schools.com/cssref/tryit.asp?filename=trycss3_nth-child_formula

            var xxx = default(CSSStyleRuleMonkier);
            //var xxxi = -1;

            page.content.onmouseout +=
                e =>
                {
                    xxx.OrphanizeRule();
                };

            var w = new Stopwatch();

            #region onmousemove

         

            bool skip = false;

            page.content.style.backgroundColor = "rgba(0,0,0,0.1)";
            page.content.onmousemove +=
                e =>
                {
                    if (skip)
                        return;

                    w.Restart();

                    //// Uncaught TypeError: Cannot read property 'layerY' of null
                    y = e.OffsetY;

                    // the padding
                    yx = e.OffsetX - 128;

                    if (page.fs.@checked)
                    {
                        // ??? magic!
                        //y += page.topic.clientHeight;
                    }

                    y = (int)Math.Floor((double)y / ((IHTMLElement)page.contentinfo.firstChild).clientHeight);

                    page.content.style.cursor = IStyle.CursorEnum.text;
                    page.content.title = "";


                    page.contentinfo.childNodes.ElementAtOrDefault(y).With(
                        li =>
                        {
                            // how many chars until the outer right is more than y?

                            // script: error JSC1000: No implementation found for this native method, please implement [static System.Linq.Enumerable.Cast(System.Collections.IEnumerable)]
                            i = li.childNodes.AsEnumerable().Select(z => (IHTMLSpan)z).TakeWhile(span => span.offsetLeft < yx).Count();

                            // cant be less than 0 yet can be more than visible chars
                            li.childNodes.AsEnumerable().Select(z => (IHTMLSpan)z).ElementAtOrDefault(i).With(
                                 async span =>
                                 {

                                     if (span.title == "c")
                                         if ((string)span.getAttribute("data-prev2") == "js")
                                         {

                                             // reveal
                                             //page.content.style.visibility = IStyle.VisibilityEnum.hidden;


                                             // upgrade
                                             span.style.cursor = IStyle.CursorEnum.pointer;
                                             //span.title = "jsc";

                                             // once
                                             span.onclick +=
                                                 ee =>
                                                 {
                                                     e.preventDefault();
                                                     e.stopPropagation();

                                                     Native.window.alert("jsc");
                                                 };

                                             span.onmouseout +=
                                                 delegate
                                                 {

                                                     page.content.style.zIndex = 10;
                                                     skip = false;
                                                 };

                                             skip = true;
                                             page.content.style.zIndex = -10;
                                             await Native.window.requestAnimationFrameAsync;


                                             span.ondragstart +=
                                                 async ee =>
                                                 {
                                                     //ee.preventDefault();
                                                     //ee.stopPropagation();

                                                     Console.WriteLine("dragstart!");

                                                     ee.dataTransfer.setData("text/uri-list", "http://my.jsc-solutions.net");

                                                     await Native.window.requestAnimationFrameAsync;
                                                     page.content.style.zIndex = 10;
                                                     skip = false;

                                                     // revert, stop events
                                                     //page.content.style.visibility = IStyle.VisibilityEnum.visible;
                                                 };


                                             return;
                                         }


                                 }
                            );
                        }
                    );



                    w.Stop();
                };
            #endregion





            //page.content.onsel

            // Uncaught SyntaxError: An invalid or illegal string was specified. 



            //Uncaught SyntaxError: An invalid or illegal string was specified. 
            //page.contentinfo.css[IHTMLElement.HTMLElementEnum.li][">span:contains('<')"].style.color = "red";

            // http://www.w3schools.com/cssref/pr_gen_content.asp
            page.contentinfo.css[IHTMLElement.HTMLElementEnum.li][IHTMLElement.HTMLElementEnum.span].before.style.content = "attr(title)";


            #region  charmap
            for (char ch = '!'; ch < 0xff; ch++)
            {
                var color = "purple";

                if (char.IsNumber(ch))
                {
                    color = "red";
                }
                else if (char.IsLetter(ch))
                {
                    color = "blue";
                }

                // Uncaught SyntaxError: An invalid or illegal string was specified. 
                // "[title='" + new string(ch, 1) + "']"

                // IStyleSheetRule.AddRule error { text = [style-id="0"] > li > span[title='']{/**/} }

                // { ch = 92, byAttr = [title='\'] } 

                var charAsString = new string(ch, 1);

                //var byAttr = "[title='" + new string(ch, 1)
                //    .Replace("\\", "\\\\")
                //    .Replace("'", "\\'")
                //    + "']";

                //Console.WriteLine(new { ch, charAsString });
                var s = page.contentinfo.css
                    [IHTMLElement.HTMLElementEnum.li]
                    [IHTMLElement.HTMLElementEnum.span]
                    [span => span.title == charAsString];
                
                //li span [title=?] {  }
            
                Console.WriteLine(new { s.selectorText });

                s.before.style.color = color;

            }
            #endregion

            // .before.style.color = color;
            //page.contentinfo.css[IHTMLElement.HTMLElementEnum.li]
            var charAsString_n = "\\n";

            page.contentinfo.css
                  [IHTMLElement.HTMLElementEnum.li]
                  [IHTMLElement.HTMLElementEnum.span]
                  [span => span.title == charAsString_n].With(
                    n =>
                    {
                        n.before.content = "¶";
                        n.before.style.color = "gray";
                    }
            );


            //page.contentinfo.css[IHTMLElement.HTMLElementEnum.li].after.style.color = "gray";


            page.contentinfo.css
                 [IHTMLElement.HTMLElementEnum.li]
                 [IHTMLElement.HTMLElementEnum.span]
                 ["[data-prev1='j']"]
                 ["[data-next1='c']"]
                 [span => span.title == "s"].before.style.backgroundColor = "yellow";

            page.contentinfo.css
               [IHTMLElement.HTMLElementEnum.li]
               [IHTMLElement.HTMLElementEnum.span]
               ["[data-prev2='js']"]
               [span => span.title == "c"].With(__c =>
                   {
                       __c.before.style.backgroundColor = "black";
                       __c.before.style.color = "yellow";
                       __c.before.style.textDecoration = "underline";

                       // make clickable
                       __c.style.zIndex = 200;
                   }
            );


            page.contentinfo.css
               [IHTMLElement.HTMLElementEnum.li]
               [IHTMLElement.HTMLElementEnum.span]
               ["[data-next1='s']"]
               [span => span.title == "j"].before.style.backgroundColor = "yellow";


            // { selectorText = [style-id="0"] > li > :nth-child(3) > span::before } 

            var SelectedRowIndex = new IntBox { index = 1 };
            var SelectedColumnIndex = new IntBox { index = 1 };

            var xs_focus = page.contentinfo.css[() => SelectedRowIndex.index];
            xs_focus.style.backgroundColor = "rgba(0,0,0,0.2)";

            var xs_hover = page.contentinfo.css[() => y];

            xs_hover.style.backgroundColor = "rgba(0,0,0,0.1)";


            xs_focus[() => SelectedColumnIndex.index].before.With(
                async blinker =>
                {
                    while (true)
                    {
                        blinker.style.backgroundColor = "red";
                        await Task.Delay(300);

                        blinker.style.backgroundColor = "";
                        await Task.Delay(100);
                    }
                }
            );
            xs_hover[() => i].before.style.backgroundColor = "cyan";

            //[IHTMLElement.HTMLElementEnum.span]
            //.before;

            //Console.WriteLine(new { xs.selectorText });

            //xs.style.backgroundColor = "cyan";

            #region onvaluechanged
            Action onvaluechanged = delegate
            {
                w.Restart();

                page.content.style.color = "transparent";


                page.contentinfo.Clear();

                page.content.Lines.ToArray().WithEachIndex(
                    (text, index) =>
                    {
                        var li = new IHTMLListItem();



                        var spans = text.ToCharArray().AsEnumerable().Select(item =>
                            {
                                //Console.WriteLine(new { item });

                                IHTMLSpan span = item;



                                //span.title = " " + item;
                                span.title = span.innerText;
                                span.Clear();

                                //if (item == '\n')
                                //{
                                //    span.title = "\\n";
                                //    span.style.backgroundColor = "red";
                                //}

                                span.AttachTo(li);

                                return span;
                            }
                        ).ToArray();

                        new IHTMLSpan { title = "\\n" }.AttachTo(li);


                        // make css happy by pre indexing 
                        // script: error JSC1000: No implementation found for this native method, please implement [static System.Linq.Enumerable.Aggregate(
                        // { x = , yy =  } 
                        spans.Aggregate(
                            seed: new List<IHTMLSpan>(),
                            func: (prev, current) =>
                            {
                                if (prev.Count > 0)
                                {
                                    var prev1 = prev[0];

                                    //Console.WriteLine(
                                    //    new { prev1 = prev1.title, current = current.title }
                                    //    );



                                    //dynamic current_data = current;



                                    current.setAttribute("data-prev1", prev1.title);

                                    prev1.setAttribute("data-next1", current.title);


                                    if (prev.Count > 1)
                                    {
                                        var prev2 = prev[1];

                                        current.setAttribute("data-prev2", prev2.title + prev1.title);
                                    }
                                }

                                var list = new List<IHTMLSpan>();

                                list.Add(current);


                                list.AddRange(
                                    prev
                                );



                                return list;
                            }
                        );


                        //foreach (var item in text)
                        //{
                        //    IHTMLSpan span = item;

                        //    span.title = span.innerText;
                        //    span.Clear();


                        //    span.AttachTo(li);
                        //}


                        li.AttachTo(page.contentinfo);
                    }
                );

                w.Stop();
                page.content.style.zIndex = 10;
                skip = false;
            };
            #endregion


            page.content.onvaluechanged += onvaluechanged;



            onvaluechanged();

            page.content.value += "\n\n hover, click or drag jsc <--";


            Native.window.onframe +=
                delegate
                {
                    SelectedRowIndex.index = page.content.value.Substring(0, page.content.SelectionStart).ToCharArray().Where(x => x == '\n').Count();

                    // script: error JSC1000: No implementation found for this native method, please implement [static System.Linq.Enumerable.TakeWhile(System.Collections.Generic.IEnumerable`1[[System.Char, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], System.Func`2[[System.Char, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]])]
                    var reverse = page.content.value.Substring(0, page.content.SelectionStart).ToCharArray().Reverse();


                    SelectedColumnIndex.index = reverse.TakeWhile(x => x != '\n').Count();



                    var lines = page.content.Lines.ToArray();

                    Native.document.title = new
                    {
                        y,
                        yx,
                        i,

                        row = SelectedRowIndex.index,
                        col = SelectedColumnIndex.index,

                        page.content.SelectionStart,
                        lines.Length,

                        w.ElapsedMilliseconds
                    }.ToString();
                };
        }