Example #1
0
func (s *Service) Rewind(dt message.AbsoluteTick) error {
	if dt > s.tick {
		return errors.New(fmt.Sprintf("Cannot rewind by %d: negative tick", dt))
	} else if dt < 0 {
		return errors.New(fmt.Sprintf("Cannot rewind by %d: negative rewind", dt))
	} else if dt == 0 {
		return nil
	}

	target := s.tick - dt

	// Browse deltas list backward (from newer to older)
	for e := s.deltas.LastBefore(s.tick); e != nil; e = e.Prev() {
		d := e.Value.(*Delta)

		if d.tick <= target {
			// Reached target, stop here
			break
		}

		// Revert delta
		if d.From != nil {
			current := s.Get(d.EntityId)

			if current != nil {
				// The entity has been updated, revert update
				diff := d.Diff
				if diff == nil {
					diff = message.NewFilledEntityDiff(true)
				}

				current.ApplyDiff(diff, d.From)
			} else {
				// The entity has been deleted, restore it
				s.entities[d.EntityId] = d.From
			}
		} else {
			// The entity has been created, delete it
			delete(s.entities, d.EntityId)
		}

		if s.frontend != nil {
			s.frontend.locker.Lock()
			s.frontend.deltas.Insert(d.Inverse().(*Delta))
			s.frontend.locker.Unlock()
		}
	}

	s.tick = target

	return nil
}
Example #2
0
// Deep copy this entity.
func (e *Entity) Copy() *Entity {
	copy := New()
	copy.Id = e.Id
	copy.ApplyDiff(message.NewFilledEntityDiff(true), e)
	return copy
}