lllivefile.cpp 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. /**
  2. * @file lllivefile.cpp
  3. *
  4. * $LicenseInfo:firstyear=2006&license=viewergpl$
  5. *
  6. * Copyright (c) 2006-2009, Linden Research, Inc.
  7. *
  8. * Second Life Viewer Source Code
  9. * The source code in this file ("Source Code") is provided by Linden Lab
  10. * to you under the terms of the GNU General Public License, version 2.0
  11. * ("GPL"), unless you have obtained a separate licensing agreement
  12. * ("Other License"), formally executed by you and Linden Lab. Terms of
  13. * the GPL can be found in doc/GPL-license.txt in this distribution, or
  14. * online at http://secondlifegrid.net/programs/open_source/licensing/gplv2
  15. *
  16. * There are special exceptions to the terms and conditions of the GPL as
  17. * it is applied to this Source Code. View the full text of the exception
  18. * in the file doc/FLOSS-exception.txt in this software distribution, or
  19. * online at
  20. * http://secondlifegrid.net/programs/open_source/licensing/flossexception
  21. *
  22. * By copying, modifying or distributing this software, you acknowledge
  23. * that you have read and understood your obligations described above,
  24. * and agree to abide by those obligations.
  25. *
  26. * ALL LINDEN LAB SOURCE CODE IS PROVIDED "AS IS." LINDEN LAB MAKES NO
  27. * WARRANTIES, EXPRESS, IMPLIED OR OTHERWISE, REGARDING ITS ACCURACY,
  28. * COMPLETENESS OR PERFORMANCE.
  29. * $/LicenseInfo$
  30. */
  31. #include "linden_common.h"
  32. #include "lllivefile.h"
  33. #include "lleventtimer.h"
  34. #include "llframetimer.h"
  35. class LLLiveFile::Impl
  36. {
  37. public:
  38. Impl(const std::string& filename, F32 refresh_period);
  39. ~Impl();
  40. bool check();
  41. void changed();
  42. public:
  43. F32 mRefreshPeriod;
  44. time_t mLastModTime;
  45. time_t mLastStatTime;
  46. LLEventTimer* mEventTimer;
  47. LLFrameTimer mRefreshTimer;
  48. std::string mFilename;
  49. bool mForceCheck;
  50. bool mLastExists;
  51. };
  52. LLLiveFile::Impl::Impl(const std::string& filename, F32 refresh_period)
  53. : mForceCheck(true),
  54. mRefreshPeriod(refresh_period),
  55. mFilename(filename),
  56. mLastModTime(0),
  57. mLastStatTime(0),
  58. mLastExists(false),
  59. mEventTimer(NULL)
  60. {
  61. }
  62. LLLiveFile::Impl::~Impl()
  63. {
  64. delete mEventTimer;
  65. }
  66. LLLiveFile::LLLiveFile(const std::string& filename, F32 refresh_period)
  67. : impl(*new Impl(filename, refresh_period))
  68. {
  69. }
  70. LLLiveFile::~LLLiveFile()
  71. {
  72. delete &impl;
  73. }
  74. bool LLLiveFile::Impl::check()
  75. {
  76. if (!mForceCheck && mRefreshTimer.getElapsedTimeF32() < mRefreshPeriod)
  77. {
  78. // Skip the check if not enough time has elapsed and we're not
  79. // forcing a check of the file
  80. return false;
  81. }
  82. mForceCheck = false;
  83. mRefreshTimer.reset();
  84. // Stat the file to see if it exists and when it was last modified.
  85. llstat stat_data;
  86. int res = LLFile::stat(mFilename, &stat_data);
  87. if (res)
  88. {
  89. // Could not stat the file, that means it does not exist or is
  90. // broken somehow. Clear flags and return.
  91. if (mLastExists)
  92. {
  93. mLastExists = false;
  94. return true; // No longer existing is a change !
  95. }
  96. return false;
  97. }
  98. // The file exists, decide if we want to load it.
  99. if (mLastExists)
  100. {
  101. // The file existed last time, do not read it if it has not changed
  102. // since last time.
  103. if (stat_data.st_mtime <= mLastModTime)
  104. {
  105. return false;
  106. }
  107. }
  108. // We want to read the file. Update status info for the file.
  109. mLastExists = true;
  110. mLastStatTime = stat_data.st_mtime;
  111. return true;
  112. }
  113. void LLLiveFile::Impl::changed()
  114. {
  115. // We wanted to read this file, and we were successful.
  116. mLastModTime = mLastStatTime;
  117. }
  118. bool LLLiveFile::checkAndReload()
  119. {
  120. bool changed = impl.check();
  121. if (changed)
  122. {
  123. if (loadFile())
  124. {
  125. impl.changed();
  126. this->changed();
  127. }
  128. else
  129. {
  130. changed = false;
  131. }
  132. }
  133. return changed;
  134. }
  135. std::string LLLiveFile::filename() const
  136. {
  137. return impl.mFilename;
  138. }
  139. namespace
  140. {
  141. class LiveFileEventTimer : public LLEventTimer
  142. {
  143. public:
  144. LiveFileEventTimer(LLLiveFile& f, F32 refresh)
  145. : LLEventTimer(refresh),
  146. mLiveFile(f)
  147. {
  148. }
  149. bool tick()
  150. {
  151. mLiveFile.checkAndReload();
  152. return false;
  153. }
  154. private:
  155. LLLiveFile& mLiveFile;
  156. };
  157. }
  158. void LLLiveFile::addToEventTimer()
  159. {
  160. impl.mEventTimer = new LiveFileEventTimer(*this, impl.mRefreshPeriod);
  161. }
  162. void LLLiveFile::setRefreshPeriod(F32 seconds)
  163. {
  164. if (seconds < 0.f)
  165. {
  166. seconds = -seconds;
  167. }
  168. impl.mRefreshPeriod = seconds;
  169. }