blob: 31550b7f5420454f75396207b921e030b1f1677a [file] [log] [blame]
// Copyright 2015 The Cobalt Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#ifndef COBALT_BASE_CLOCK_H_
#define COBALT_BASE_CLOCK_H_
#include "base/basictypes.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/time/time.h"
namespace base {
// A generic base::BasicClock interface for querying the current time.
// Inserting a level of indirection between querying for the current time allows
// one to have greater control over how their system reacts to time changes.
class BasicClock : public ::base::RefCountedThreadSafe<BasicClock> {
public:
virtual ::base::TimeDelta Now() = 0;
protected:
virtual ~BasicClock() {}
friend class ::base::RefCountedThreadSafe<BasicClock>;
};
// The SystemClock calls in to the standard ::base::TimeTicks::HighResNow()
// method to obtain a time.
class SystemMonotonicClock : public BasicClock {
public:
SystemMonotonicClock() { origin_ = ::base::TimeTicks::Now(); }
::base::TimeDelta Now() override {
return ::base::TimeTicks::Now() - origin_;
}
private:
::base::TimeTicks origin_;
~SystemMonotonicClock() override {}
};
// The MinimumResolutionClock modifies the output of an existing clock by
// clamping its minimum resolution to a predefined amount. This is implemented
// by rounding down the existing clock's time to the previous multiple of the
// desired clock resolution.
class MinimumResolutionClock : public BasicClock {
public:
MinimumResolutionClock(scoped_refptr<BasicClock> parent,
const ::base::TimeDelta& min_resolution)
: parent_(parent),
min_resolution_in_microseconds_(min_resolution.InMicroseconds()) {
DCHECK(parent);
}
::base::TimeDelta Now() override {
::base::TimeDelta now = parent_->Now();
int64 microseconds = now.InMicroseconds();
return ::base::TimeDelta::FromMicroseconds(
microseconds - (microseconds % min_resolution_in_microseconds_));
}
private:
scoped_refptr<BasicClock> parent_;
const int64_t min_resolution_in_microseconds_;
};
// The OffsetClock takes a parent clock and an offset upon construction, and
// when queried for the time it returns the time of the parent clock offset by
// the specified offset.
class OffsetClock : public BasicClock {
public:
OffsetClock(const scoped_refptr<BasicClock> parent,
const ::base::TimeDelta& origin)
: parent_(parent), origin_(origin) {
DCHECK(parent_);
}
::base::TimeDelta Now() override { return parent_->Now() - origin_; }
::base::TimeDelta origin() const { return origin_; }
private:
~OffsetClock() override {}
scoped_refptr<BasicClock> parent_;
const ::base::TimeDelta origin_;
};
// Simple clock that needs to be manually advanced.
class ManualAdvanceClock : public BasicClock {
public:
::base::TimeDelta Now() override { return value_; }
void Advance(const ::base::TimeDelta& advance_amount) {
DCHECK_GE(advance_amount, ::base::TimeDelta());
value_ += advance_amount;
}
private:
~ManualAdvanceClock() override {}
::base::TimeDelta value_;
};
} // namespace base
#endif // COBALT_BASE_CLOCK_H_