<commit_before>#pragma once

#include <experimental/filesystem>
#include <fstream>
#include <functional>
#include <map>
#include <memory>
#include <string>

#include "base/not_null.hpp"
#include "ksp_plugin/interface.hpp"
#include "serialization/journal.pb.h"

namespace principia {

using base::not_null;

namespace ksp_plugin {

using PointerMap = std::map<std::uint64_t, void*>;

struct InitGoogleLogging {
  using Message = serialization::InitGoogleLogging;
};

struct SetBufferedLogging {
  struct In {
    int const max_severity;
  };

  using Message = serialization::SetBufferedLogging;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct GetBufferedLogging {
  using Return = int;

  using Message = serialization::GetBufferedLogging;
  static void Fill(Return const& result, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct SetBufferDuration {
  struct In {
    int const seconds;
  };

  using Message = serialization::SetBufferDuration;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct GetBufferDuration {
  using Return = int;

  using Message = serialization::GetBufferDuration;
  static void Fill(Return const& result, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct SetSuppressedLogging {
  struct In {
    int const min_severity;
  };

  using Message = serialization::SetSuppressedLogging;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct GetSuppressedLogging {
  using Return = int;

  using Message = serialization::GetSuppressedLogging;
  static void Fill(Return const& result, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct SetVerboseLogging {
  struct In {
    int const level;
  };

  using Message = serialization::SetVerboseLogging;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct GetVerboseLogging {
  using Return = int;

  using Message = serialization::GetVerboseLogging;
  static void Fill(Return const& result, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct SetStderrLogging {
  struct In {
    int const min_severity;
  };

  using Message = serialization::SetStderrLogging;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct GetStderrLogging {
  using Return = int;

  using Message = serialization::GetStderrLogging;
  static void Fill(Return const& result, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct LogInfo {
  struct In {
    char const* const message;
  };

  using Message = serialization::LogInfo;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct LogWarning {
  struct In {
    char const* const message;
  };

  using Message = serialization::LogWarning;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct LogError {
  struct In {
    char const* const message;
  };

  using Message = serialization::LogError;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct LogFatal {
  struct In {
    char const* const message;
  };

  using Message = serialization::LogFatal;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct NewPlugin {
  struct In {
    double const initial_time;
    double const planetarium_rotation_in_degrees;
  };
  using Return = Plugin*;

  using Message = serialization::NewPlugin;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Fill(Return const& result, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct DeletePlugin {
  struct In {
    Plugin const* const plugin;
  };
  struct Out {
    Plugin const** const plugin;
  };

  using Message = serialization::DeletePlugin;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Fill(Out const& out, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct DirectlyInsertCelestial {
  struct In {
    Plugin* const plugin;
    int const celestial_index;
    int const* const parent_index;
    char const* const gravitational_parameter;
    char const* const axis_right_ascension;
    char const* const axis_declination;
    char const* const j2;
    char const* const reference_radius;
    char const* const x;
    char const* const y;
    char const* const z;
    char const* const vx;
    char const* const vy;
    char const* const vz;
  };

  using Message = serialization::DirectlyInsertCelestial;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct InsertCelestial {
  struct In {
    Plugin* const plugin;
    int const celestial_index;
    double const gravitational_parameter;
    int const parent_index;
    QP const from_parent;
  };

  using Message = serialization::InsertCelestial;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct InsertSun {
  struct In {
    Plugin* const plugin;
    int const celestial_index;
    double const gravitational_parameter;
  };

  using Message = serialization::InsertSun;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct UpdateCelestialHierarchy {
  struct In {
    Plugin const* const plugin;
    int const celestial_index;
    int const parent_index;
  };

  using Message = serialization::UpdateCelestialHierarchy;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct EndInitialization {
  struct In {
    Plugin const* const plugin;
  };

  using Message = serialization::EndInitialization;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct InsertOrKeepVessel {
  struct In {
    Plugin* const plugin;
    char const* const vessel_guid;
    int const parent_index;
  };
  using Return = bool;

  using Message = serialization::InsertOrKeepVessel;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Fill(Return const& result, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct SetVesselStateOffset {
  struct In {
    Plugin* const plugin;
    char const* const vessel_guid;
    QP const from_parent;
  };

  using Message = serialization::SetVesselStateOffset;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct AdvanceTime {
  struct In {
    Plugin* const plugin;
    double const t;
    double const planetarium_rotation;
  };

  using Message = serialization::AdvanceTime;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct ForgetAllHistoriesBefore {
  struct In {
    Plugin* const plugin;
    double const t;
  };

  using Message = serialization::ForgetAllHistoriesBefore;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct VesselFromParent {
  struct In {
    Plugin const* const plugin;
    char const* const vessel_guid;
  };

  using Message = serialization::VesselFromParent;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct CelestialFromParent {
  struct In {
    Plugin const* const plugin;
    int const celestial_index;
  };

  using Message = serialization::CelestialFromParent;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct NewBodyCentredNonRotatingRenderingFrame {
  struct In {
    Plugin const* const plugin;
    int const reference_body_index;
  };

  using Message = serialization::NewBodyCentredNonRotatingRenderingFrame;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct NewBarycentricRotatingRenderingFrame {
  struct In {
    Plugin const* const plugin;
    int const primary_index;
    int const secondary_index;
  };

  using Message = serialization::NewBarycentricRotatingRenderingFrame;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct DeleteRenderingFrame {
  struct In {
    RenderingFrame* const rendering_frame;
  };

  using Message = serialization::DeleteRenderingFrame;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct UpdatePrediction {
  struct In {
    Plugin const* const plugin;
    char const* const vessel_guid;
  };

  using Message = serialization::UpdatePrediction;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct RenderedVesselTrajectory {
  struct In {
    Plugin const* const plugin;
    char const* const vessel_guid;
    RenderingFrame* const rendering_frame;
    XYZ const sun_world_position;
  };

  using Message = serialization::RenderedVesselTrajectory;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct HasPrediction {
  struct In {
    Plugin const* const plugin;
    char const* const vessel_guid;
  };

  using Message = serialization::HasPrediction;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct RenderedPrediction {
  struct In {
    Plugin* const plugin;
    char const* const vessel_guid;
    RenderingFrame* const rendering_frame;
    XYZ const sun_world_position;
  };

  using Message = serialization::RenderedPrediction;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

class Journal {
 public:
  template<typename Profile>
  class Method {
   public:
    Method();

    // Only declare this constructor if the profile has an |In| type.
    template<typename P = Profile, typename = typename P::In>
    explicit Method(typename P::In const& in);

    // Only declare this constructor if the profile has an |In| and an |Out|
    // type.
    template<typename P = Profile,
             typename = typename P::In, typename = typename P::Out>
    Method(typename P::In const& in, typename P::Out const& out);

    ~Method();

    void Return();

    // Only declare this method if the profile has a |Return| type.
    template<typename P = Profile, typename = typename P::Return>
    typename P::Return Return(typename P::Return const& result);

   private:
    std::unique_ptr<typename Profile::Message> message_;
    std::function<void()> out_filler_;
    bool returned_ = false;
  };

  explicit Journal(std::experimental::filesystem::path const& path);
  ~Journal();

  void Write(serialization::Method const& method);

  static void Activate(base::not_null<Journal*> const journal);
  static void Deactivate();

 private:
  std::ofstream stream_;

  static Journal* active_;

  template<typename>
  friend class Method;
  friend class JournalTest;
};

class Player {
 public:
  explicit Player(std::experimental::filesystem::path const& path);

  // Replays the next message in the journal.  Returns false at end of journal.
  bool Play();

 private:
  // Reads one message from the stream.  Returns a |nullptr| at end of stream.
  std::unique_ptr<serialization::Method> Read();

  template<typename Profile>
  bool RunIfAppropriate(serialization::Method const& method);

  PointerMap pointer_map_;
  std::ifstream stream_;

  friend class JournalTest;
};

}  // namespace ksp_plugin
}  // namespace principia

#include "ksp_plugin/journal_body.hpp"
<commit_msg>Declare all types and functions.<commit_after>#pragma once

#include <experimental/filesystem>
#include <fstream>
#include <functional>
#include <map>
#include <memory>
#include <string>

#include "base/not_null.hpp"
#include "ksp_plugin/interface.hpp"
#include "serialization/journal.pb.h"

namespace principia {

using base::not_null;

namespace ksp_plugin {

using PointerMap = std::map<std::uint64_t, void*>;

struct InitGoogleLogging {
  using Message = serialization::InitGoogleLogging;
};

struct SetBufferedLogging {
  struct In {
    int const max_severity;
  };

  using Message = serialization::SetBufferedLogging;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct GetBufferedLogging {
  using Return = int;

  using Message = serialization::GetBufferedLogging;
  static void Fill(Return const& result, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct SetBufferDuration {
  struct In {
    int const seconds;
  };

  using Message = serialization::SetBufferDuration;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct GetBufferDuration {
  using Return = int;

  using Message = serialization::GetBufferDuration;
  static void Fill(Return const& result, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct SetSuppressedLogging {
  struct In {
    int const min_severity;
  };

  using Message = serialization::SetSuppressedLogging;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct GetSuppressedLogging {
  using Return = int;

  using Message = serialization::GetSuppressedLogging;
  static void Fill(Return const& result, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct SetVerboseLogging {
  struct In {
    int const level;
  };

  using Message = serialization::SetVerboseLogging;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct GetVerboseLogging {
  using Return = int;

  using Message = serialization::GetVerboseLogging;
  static void Fill(Return const& result, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct SetStderrLogging {
  struct In {
    int const min_severity;
  };

  using Message = serialization::SetStderrLogging;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct GetStderrLogging {
  using Return = int;

  using Message = serialization::GetStderrLogging;
  static void Fill(Return const& result, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct LogInfo {
  struct In {
    char const* const message;
  };

  using Message = serialization::LogInfo;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct LogWarning {
  struct In {
    char const* const message;
  };

  using Message = serialization::LogWarning;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct LogError {
  struct In {
    char const* const message;
  };

  using Message = serialization::LogError;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct LogFatal {
  struct In {
    char const* const message;
  };

  using Message = serialization::LogFatal;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct NewPlugin {
  struct In {
    double const initial_time;
    double const planetarium_rotation_in_degrees;
  };
  using Return = Plugin*;

  using Message = serialization::NewPlugin;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Fill(Return const& result, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct DeletePlugin {
  struct In {
    Plugin const* const plugin;
  };
  struct Out {
    Plugin const** const plugin;
  };

  using Message = serialization::DeletePlugin;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Fill(Out const& out, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct DirectlyInsertCelestial {
  struct In {
    Plugin* const plugin;
    int const celestial_index;
    int const* const parent_index;
    char const* const gravitational_parameter;
    char const* const axis_right_ascension;
    char const* const axis_declination;
    char const* const j2;
    char const* const reference_radius;
    char const* const x;
    char const* const y;
    char const* const z;
    char const* const vx;
    char const* const vy;
    char const* const vz;
  };

  using Message = serialization::DirectlyInsertCelestial;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct InsertCelestial {
  struct In {
    Plugin* const plugin;
    int const celestial_index;
    double const gravitational_parameter;
    int const parent_index;
    QP const from_parent;
  };

  using Message = serialization::InsertCelestial;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct InsertSun {
  struct In {
    Plugin* const plugin;
    int const celestial_index;
    double const gravitational_parameter;
  };

  using Message = serialization::InsertSun;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct UpdateCelestialHierarchy {
  struct In {
    Plugin const* const plugin;
    int const celestial_index;
    int const parent_index;
  };

  using Message = serialization::UpdateCelestialHierarchy;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct EndInitialization {
  struct In {
    Plugin const* const plugin;
  };

  using Message = serialization::EndInitialization;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct InsertOrKeepVessel {
  struct In {
    Plugin* const plugin;
    char const* const vessel_guid;
    int const parent_index;
  };
  using Return = bool;

  using Message = serialization::InsertOrKeepVessel;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Fill(Return const& result, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct SetVesselStateOffset {
  struct In {
    Plugin* const plugin;
    char const* const vessel_guid;
    QP const from_parent;
  };

  using Message = serialization::SetVesselStateOffset;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct AdvanceTime {
  struct In {
    Plugin* const plugin;
    double const t;
    double const planetarium_rotation;
  };

  using Message = serialization::AdvanceTime;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct ForgetAllHistoriesBefore {
  struct In {
    Plugin* const plugin;
    double const t;
  };

  using Message = serialization::ForgetAllHistoriesBefore;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct VesselFromParent {
  struct In {
    Plugin const* const plugin;
    char const* const vessel_guid;
  };
  using Return = QP;

  using Message = serialization::VesselFromParent;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Fill(Return const& result, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct CelestialFromParent {
  struct In {
    Plugin const* const plugin;
    int const celestial_index;
  };
  using Return = QP;

  using Message = serialization::CelestialFromParent;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Fill(Return const& result, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct NewBodyCentredNonRotatingRenderingFrame {
  struct In {
    Plugin const* const plugin;
    int const reference_body_index;
  };
  using Return = RenderingFrame*;

  using Message = serialization::NewBodyCentredNonRotatingRenderingFrame;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Fill(Return const& result, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct NewBarycentricRotatingRenderingFrame {
  struct In {
    Plugin const* const plugin;
    int const primary_index;
    int const secondary_index;
  };
  using Return = RenderingFrame*;

  using Message = serialization::NewBarycentricRotatingRenderingFrame;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Fill(Return const& result, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct DeleteRenderingFrame {
  struct In {
    RenderingFrame* const rendering_frame;
  };
  struct Out {
    RenderingFrame** const rendering_frame;
  };

  using Message = serialization::DeleteRenderingFrame;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Fill(Out const& out, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct UpdatePrediction {
  struct In {
    Plugin const* const plugin;
    char const* const vessel_guid;
  };

  using Message = serialization::UpdatePrediction;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct RenderedVesselTrajectory {
  struct In {
    Plugin const* const plugin;
    char const* const vessel_guid;
    RenderingFrame* const rendering_frame;
    XYZ const sun_world_position;
  };
  using Return = LineAndIterator*;

  using Message = serialization::RenderedVesselTrajectory;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Fill(Return const& result, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct HasPrediction {
  struct In {
    Plugin const* const plugin;
    char const* const vessel_guid;
  };
  using Return = bool;

  using Message = serialization::HasPrediction;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Fill(Return const& result, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

struct RenderedPrediction {
  struct In {
    Plugin* const plugin;
    char const* const vessel_guid;
    RenderingFrame* const rendering_frame;
    XYZ const sun_world_position;
  };
  using Return = LineAndIterator*;

  using Message = serialization::RenderedPrediction;
  static void Fill(In const& in, not_null<Message*> const message);
  static void Fill(Return const& result, not_null<Message*> const message);
  static void Run(Message const& message,
                  not_null<PointerMap*> const pointer_map);
};

class Journal {
 public:
  template<typename Profile>
  class Method {
   public:
    Method();

    // Only declare this constructor if the profile has an |In| type.
    template<typename P = Profile, typename = typename P::In>
    explicit Method(typename P::In const& in);

    // Only declare this constructor if the profile has an |In| and an |Out|
    // type.
    template<typename P = Profile,
             typename = typename P::In, typename = typename P::Out>
    Method(typename P::In const& in, typename P::Out const& out);

    ~Method();

    void Return();

    // Only declare this method if the profile has a |Return| type.
    template<typename P = Profile, typename = typename P::Return>
    typename P::Return Return(typename P::Return const& result);

   private:
    std::unique_ptr<typename Profile::Message> message_;
    std::function<void()> out_filler_;
    bool returned_ = false;
  };

  explicit Journal(std::experimental::filesystem::path const& path);
  ~Journal();

  void Write(serialization::Method const& method);

  static void Activate(base::not_null<Journal*> const journal);
  static void Deactivate();

 private:
  std::ofstream stream_;

  static Journal* active_;

  template<typename>
  friend class Method;
  friend class JournalTest;
};

class Player {
 public:
  explicit Player(std::experimental::filesystem::path const& path);

  // Replays the next message in the journal.  Returns false at end of journal.
  bool Play();

 private:
  // Reads one message from the stream.  Returns a |nullptr| at end of stream.
  std::unique_ptr<serialization::Method> Read();

  template<typename Profile>
  bool RunIfAppropriate(serialization::Method const& method);

  PointerMap pointer_map_;
  std::ifstream stream_;

  friend class JournalTest;
};

}  // namespace ksp_plugin
}  // namespace principia

#include "ksp_plugin/journal_body.hpp"
<|endoftext|>


<commit_before>//////////////////////////////////////////////////////////////////////////////
//
// License Agreement:
//
// The following are Copyright  2008, mC2 Team
//
// Sources and Binaries of: mC2, win32cpp
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//    * Redistributions of source code must retain the above copyright notice,
//      this list of conditions and the following disclaimer.
//
//    * Redistributions in binary form must reproduce the above copyright
//      notice, this list of conditions and the following disclaimer in the
//      documentation and/or other materials provided with the distribution.
//
//    * Neither the name of the author nor the names of other contributors may
//      be used to endorse or promote products derived from this software
//      without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////

#include "pch.hpp"
#include <core/Common.h>
#include <cube/dialog/HelpAboutView.hpp>
#include <core/LibraryFactory.h>
#include <win32cpp/Label.hpp>
#include <win32cpp/Button.hpp>
#include <win32cpp/LinearLayout.hpp>
#include <win32cpp/BarLayout.hpp>
#include <win32cpp/EditView.hpp>

// GDI+ for loading the image
#include <atlbase.h>
#include <gdiplus.h>

//////////////////////////////////////////////////////////////////////////////

using namespace musik::cube::dialog;
using namespace win32cpp;

volatile bool anim_running = false;
const int anim_w = 400;
const int anim_h = 300;

#define anim_color(R, G, B) \
    ((unsigned short) ( \
        ( ( (R) >> 3 ) << 11) | \
        ( ( (G) >> 2 ) << 5 ) | \
        ( ( (B) >> 3 )      ) \
    ))

#define extract_r(C) ( (   (C) >> 11  & 0x1F ) << 3 )
#define extract_g(C) ( ( ( (C) >> 5 ) & 0x3F ) << 2 )
#define extract_b(C) ( (   (C)        & 0x1F ) << 3 )

//////////////////////////////////////////////////////////////////////////////

HelpAboutView::HelpAboutView()
: Frame(NULL, FramePadding(6))
, drawingThread(NULL)
{
}

void HelpAboutView::DrawingThread(HWND hwnd, BITMAPINFO* bmi)
{
    // Variable decl
    unsigned short* screen;
    unsigned char   sintable[1024];
    unsigned short  plasmapal[256];
    int             plasmawave[4] = {0, 0, 0, 0};

    // Create surface
    screen = new unsigned short[anim_w * anim_h];

    // Calc sin table for plasma effect
    for(int i=0; i<1024; i++) {
        sintable[i] = 128 + 127.0 * (sin((double)i * 3.1415 / 512.0));
    }

    // Calc color table for plasma effect
    for(int i=0; i<256; i++) {
        int
            r = 20 + 19.0 * sin((double)i * 3.1415 /  40.0),
            g = 40 + 39.0 * sin((double)i * 3.1415 /  40.0),
            b = 120 + 79.0 *  cos((double)i * 3.1415 / 120.0);

        plasmapal[i] = anim_color(r, g, b);
    }

    // Start time of animation
    unsigned long time_start = ::GetTickCount();

    // Init GDI*
    Gdiplus::GdiplusStartupInput gp_si;
    ULONG_PTR gp_tok;
    Gdiplus::GdiplusStartup(&gp_tok, &gp_si, NULL);

    // Load logo
    Gdiplus::Bitmap* gp_logo = Gdiplus::Bitmap::FromFile(
        (musik::core::GetApplicationDirectory() + _T("resources\\logo.png")).c_str()
    );

    // Convert logo to correct format
    unsigned int
        logo_width = gp_logo->GetWidth(),
        logo_height = gp_logo->GetHeight();
    unsigned int
        *logo = new unsigned int[logo_width * logo_height],
        *plogo = logo;
    BYTE
        *logo_alpha = new BYTE[logo_width * logo_height],
        *plogo_alpha = logo_alpha;

    for(int y=0; y<logo_height; y++) {
        for(int x=0; x<logo_width; x++) {
            Gdiplus::Color col;
            gp_logo->GetPixel(x, y, &col);

            *plogo = anim_color(col.GetRed(), col.GetGreen(), col.GetBlue());
            ++plogo;

            *plogo_alpha = col.GetAlpha();
            ++plogo_alpha;
        }
    }

    // Create font for text scroller
    HFONT font = ::CreateFont(
        14,
        0,
        0,
        0,
        FW_NORMAL,
        0,
        0,
        0,
        ANSI_CHARSET,
        OUT_DEFAULT_PRECIS,
        CLIP_DEFAULT_PRECIS,
        ANTIALIASED_QUALITY | CLEARTYPE_QUALITY,
        DEFAULT_PITCH,
        _T("Courier New")
    );

    // Define Texts here, there are played in this order
    uistring texts[] = {
        _T("--+ musikCube 2 | milestone 2 +--"),
        _T("created by"),
        _T("avatar"),
        _T("doep"),
        _T("bjorn"),
        _T("jooles"),
        _T("naaina"),
        _T("mC2 are copyright (c) mC2 Team 2007-2008"),
        _T("win32cpp are copyright (c) Casey Langen 2007-2008"),
        _T("mC2 wouldn't be possible without these projects:"),
        _T("tuniac (http://tuniac.sf.net)"),
        _T("boost (http://www.boost.org)"),
        _T("sqlite3 (http://www.sqlite.org)"),
        _T("taglib (http://developer.kde.org/~wheeler/taglib)")
    };

    RECT cr;
    ::GetClientRect(hwnd, &cr);

    RECT textrect;
    textrect.left = 0;
    textrect.top = 200;
    textrect.right = cr.right;
    textrect.bottom = 220;

    // Start drawing loop
    while(anim_running) {
        // Calc current time
        float time = (float)(::GetTickCount() - time_start) / 1000.0f;

        // Plasma
        {
            // Plasma is done by addition over 4 parametric, circular plasma waves
            int sx[4], sy[4], wx[4], wy[4];

            sx[0] =  600 * sin(time * 2.0  + 2.0);
            sy[0] =  600 * cos(time * 1.9  - 1.3);
            sx[1] =  140 * sin(-time * 1.8 + 2.4);
            sy[1] =  140 * cos(-time * 1.7 + 1.2);
            sx[2] =  560 * sin(time * 1.6  - 0.4);
            sy[2] =  460 * cos(time * 1.5  + 2.5);
            sx[3] =  340 * sin(-time * 1.4 - 1.7);
            sy[3] =  340 * cos(-time * 1.3 + 1.8);

            for(int i=0; i<4; i++) {
                plasmawave[i] += sx[i];
                wy[i] = plasmawave[i];
            }

            // Process scanline-based
            unsigned short* sb = screen;
            for(int y=0; y<anim_h; y++) {
                for(int i=0; i<4; i++) {
                    wx[i] = wy[i];
                }

                for(int x=0; x<anim_w; x++) {
                    *sb = plasmapal[(
                        sintable[(wx[0] >> 8) & 0x3ff] +
                        sintable[(wx[1] >> 8) & 0x3ff] +
                        sintable[(wx[2] >> 8) & 0x3ff] +
                        sintable[(wx[3] >> 8) & 0x3ff]
                    ) >> 2];

                    ++sb;

                    for(int i=0; i<4; i++) {
                        wx[i] += sx[i];
                    }
                }

                for(int i=0; i<4; i++) {
                    wy[i] += sy[i];
                }
            }

            // Display logo
            float alpha = 0.7 + 0.3 * sin(0.3 * time * 3.1415);
            int lx = 127, ly = 40;
            for(int y=0; y<logo_height; y++) {
                // blackit is true in order to create the black noisy stripes
                bool blackit = false;
                if(
                    (
                        (alpha >= 0.4 && alpha <= 0.42) ||
                        (alpha >= 0.71 && alpha <= 0.714)
                    ) && !(y % (1 + (rand() % logo_height)))) {
                    blackit = true;
                }

                for(int x=0; x<logo_width; x++) {
                    unsigned short* cp = &screen[(lx + x) + ((ly + y) * anim_w)];

                    unsigned short
                        c = logo[x + y * logo_width],
                        s = *cp;

                    BYTE a = logo_alpha[x + y * logo_width];

                    if(blackit) c = 0, a = 0;

                    double ac = alpha * ((double)a / 255.0f);

                    unsigned int
                        r = (extract_r(c) * ac) + (extract_r(s) * (1.0 - ac)),
                        g = (extract_g(c) * ac) + (extract_g(s) * (1.0 - ac)),
                        b = (extract_b(c) * ac) + (extract_b(s) * (1.0 - ac));

                    *cp = anim_color(r, g, b);
                }
            }
        }

        // Blit surface
        HDC hdc = ::GetDC(hwnd);
        ::SetDIBitsToDevice(hdc, 0, 0, anim_w, anim_h, 0, 0, 0, anim_h, (void*)screen, bmi, DIB_RGB_COLORS);

        // Draw text
        {
            static unsigned int textidx = 0;

            ::SetBkMode(hdc, TRANSPARENT);
            ::SetTextColor(hdc, 0xDDDDAA);
            ::SelectObject(hdc, font);

            static float tdlast = 0.0f;

            float td = time - tdlast;
            if(td > 2.5f) {

                if(textidx+1 == sizeof(texts) / sizeof(uistring)) {
                    textidx = 0;
                } else {
                    textidx++;
                }

                tdlast = time;
            }

            ::DrawText(
                hdc,
                texts[textidx].c_str(),
                texts[textidx].size() + 1,
                &textrect,
                DT_CENTER
            );
        }

        // Some idle time to give other threads the chance to process
        Sleep(1);
    }

    // Shutdown GDI+
    delete gp_logo; delete logo;
    Gdiplus::GdiplusShutdown(gp_tok);

    // Delete resources
    delete[] screen; screen = NULL;
}

void HelpAboutView::StartDrawingThread()
{
    anim_running = true;

    this->drawingThread = new boost::thread(
        &HelpAboutView::DrawingThread,
        this->Parent()->Handle(),
        this->bitmapinfo
    );
}

void HelpAboutView::OnCreated()
{
    // Initialize bitmap info header for 16-bit GDI graphics
    this->bitmapinfo = (BITMAPINFO*) malloc(sizeof(BITMAPINFOHEADER) + 12);
    ::ZeroMemory(&this->bitmapinfo->bmiHeader, sizeof(BITMAPINFOHEADER));

    bitmapinfo->bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);
    bitmapinfo->bmiHeader.biWidth       = anim_w;
    bitmapinfo->bmiHeader.biHeight      = -anim_h;
    bitmapinfo->bmiHeader.biBitCount    = 16;
    bitmapinfo->bmiHeader.biPlanes      = 1;
    bitmapinfo->bmiHeader.biCompression = BI_BITFIELDS;

    // Color masks. Since we got 16-bit, we have 5-6-5 RGB, so we need to configure
    // the bitmap info header according to this color space.
    *((long*)bitmapinfo->bmiColors +0) = 0xF800;
    *((long*)bitmapinfo->bmiColors +1) = 0x07E0;
    *((long*)bitmapinfo->bmiColors +2) = 0x001F;
}

void HelpAboutView::OnDestroyed()
{
    // Indicate drawing thread to stop
    anim_running = false;

    // Wait for thread exit
    this->drawingThread->join();

    // Delete thread and other stuff
    if(this->drawingThread) {
        delete this->drawingThread;
    }

    if(this->bitmapinfo) {
        free(this->bitmapinfo);
        this->bitmapinfo = NULL;
    }

}<commit_msg>Cleaned up a memory leak in the about box. Removed warnings by explicit casts<commit_after>//////////////////////////////////////////////////////////////////////////////
//
// License Agreement:
//
// The following are Copyright  2008, mC2 Team
//
// Sources and Binaries of: mC2, win32cpp
//
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
//
//    * Redistributions of source code must retain the above copyright notice,
//      this list of conditions and the following disclaimer.
//
//    * Redistributions in binary form must reproduce the above copyright
//      notice, this list of conditions and the following disclaimer in the
//      documentation and/or other materials provided with the distribution.
//
//    * Neither the name of the author nor the names of other contributors may
//      be used to endorse or promote products derived from this software
//      without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
// POSSIBILITY OF SUCH DAMAGE.
//
//////////////////////////////////////////////////////////////////////////////

#include "pch.hpp"
#include <core/Common.h>
#include <cube/dialog/HelpAboutView.hpp>
#include <core/LibraryFactory.h>
#include <win32cpp/Label.hpp>
#include <win32cpp/Button.hpp>
#include <win32cpp/LinearLayout.hpp>
#include <win32cpp/BarLayout.hpp>
#include <win32cpp/EditView.hpp>

// GDI+ for loading the image
#include <atlbase.h>
#include <gdiplus.h>

//////////////////////////////////////////////////////////////////////////////

using namespace musik::cube::dialog;
using namespace win32cpp;

volatile bool anim_running = false;
const int anim_w = 400;
const int anim_h = 300;

#define anim_color(R, G, B) \
    ((unsigned short) ( \
        ( ( (R) >> 3 ) << 11) | \
        ( ( (G) >> 2 ) << 5 ) | \
        ( ( (B) >> 3 )      ) \
    ))

#define extract_r(C) ( (   (C) >> 11  & 0x1F ) << 3 )
#define extract_g(C) ( ( ( (C) >> 5 ) & 0x3F ) << 2 )
#define extract_b(C) ( (   (C)        & 0x1F ) << 3 )

//////////////////////////////////////////////////////////////////////////////

HelpAboutView::HelpAboutView()
: Frame(NULL, FramePadding(6))
, drawingThread(NULL)
{
}

void HelpAboutView::DrawingThread(HWND hwnd, BITMAPINFO* bmi)
{
    // Variable decl
    unsigned short* screen;
    unsigned char   sintable[1024];
    unsigned short  plasmapal[256];
    int             plasmawave[4] = {0, 0, 0, 0};

    // Create surface
    screen = new unsigned short[anim_w * anim_h];

    // Calc sin table for plasma effect
    for(int i=0; i<1024; i++) {
        sintable[i] = 128 + (unsigned char)(127.0 * (sin((double)i * 3.1415 / 512.0)));
    }

    // Calc color table for plasma effect
    for(int i=0; i<256; i++) {
        int
            r =  20 + (int)(19.0 * sin((double)i * 3.1415 /  40.0)),
            g =  40 + (int)(39.0 * sin((double)i * 3.1415 /  40.0)),
            b = 120 + (int)(79.0 * cos((double)i * 3.1415 / 120.0));

        plasmapal[i] = anim_color(r, g, b);
    }

    // Start time of animation
    unsigned long time_start = ::GetTickCount();

    // Init GDI*
    Gdiplus::GdiplusStartupInput gp_si;
    ULONG_PTR gp_tok;
    Gdiplus::GdiplusStartup(&gp_tok, &gp_si, NULL);

    // Load logo
    Gdiplus::Bitmap* gp_logo = Gdiplus::Bitmap::FromFile(
        (musik::core::GetApplicationDirectory() + _T("resources\\logo.png")).c_str()
    );

    // Convert logo to correct format
    unsigned int
        logo_width = gp_logo->GetWidth(),
        logo_height = gp_logo->GetHeight();
    unsigned int
        *logo = new unsigned int[logo_width * logo_height],
        *plogo = logo;
    BYTE
        *logo_alpha = new BYTE[logo_width * logo_height],
        *plogo_alpha = logo_alpha;

    for(int y=0; y<logo_height; y++) {
        for(int x=0; x<logo_width; x++) {
            Gdiplus::Color col;
            gp_logo->GetPixel(x, y, &col);

            *plogo = anim_color(col.GetRed(), col.GetGreen(), col.GetBlue());
            ++plogo;

            *plogo_alpha = col.GetAlpha();
            ++plogo_alpha;
        }
    }

    // Create font for text scroller
    HFONT font = ::CreateFont(
        14,
        0,
        0,
        0,
        FW_NORMAL,
        0,
        0,
        0,
        ANSI_CHARSET,
        OUT_DEFAULT_PRECIS,
        CLIP_DEFAULT_PRECIS,
        ANTIALIASED_QUALITY | CLEARTYPE_QUALITY,
        DEFAULT_PITCH,
        _T("Courier New")
    );

    // Define Texts here, there are played in this order
    uistring texts[] = {
        _T("--+ musikCube 2 | milestone 2 +--"),
        _T("created by"),
        _T("avatar"),
        _T("doep"),
        _T("bjorn"),
        _T("jooles"),
        _T("naaina"),
        _T("mC2 are copyright (c) mC2 Team 2007-2008"),
        _T("win32cpp are copyright (c) Casey Langen 2007-2008"),
        _T("mC2 wouldn't be possible without these projects:"),
        _T("tuniac (http://tuniac.sf.net)"),
        _T("boost (http://www.boost.org)"),
        _T("sqlite3 (http://www.sqlite.org)"),
        _T("taglib (http://developer.kde.org/~wheeler/taglib)")
    };

    RECT cr;
    ::GetClientRect(hwnd, &cr);

    RECT textrect;
    textrect.left = 0;
    textrect.top = 200;
    textrect.right = cr.right;
    textrect.bottom = 220;

    // Start drawing loop
    while(anim_running) {
        // Calc current time
        double time = (double)(::GetTickCount() - time_start) / 1000.0;

        // Plasma
        {
            // Plasma is done by addition over 4 parametric, circular plasma waves
            int sx[4], sy[4], wx[4], wy[4];

            sx[0] =  (int)(600.0 * sin(time * 2.0  + 2.0));
            sy[0] =  (int)(600.0 * cos(time * 1.9  - 1.3));
            sx[1] =  (int)(140.0 * sin(-time * 1.8 + 2.4));
            sy[1] =  (int)(140.0 * cos(-time * 1.7 + 1.2));
            sx[2] =  (int)(560.0 * sin(time * 1.6  - 0.4));
            sy[2] =  (int)(460.0 * cos(time * 1.5  + 2.5));
            sx[3] =  (int)(340.0 * sin(-time * 1.4 - 1.7));
            sy[3] =  (int)(340.0 * cos(-time * 1.3 + 1.8));

            for(int i=0; i<4; i++) {
                plasmawave[i] += sx[i];
                wy[i] = plasmawave[i];
            }

            // Process scanline-based
            unsigned short* sb = screen;
            for(int y=0; y<anim_h; y++) {
                for(int i=0; i<4; i++) {
                    wx[i] = wy[i];
                }

                for(int x=0; x<anim_w; x++) {
                    *sb = plasmapal[(
                        sintable[(wx[0] >> 8) & 0x3ff] +
                        sintable[(wx[1] >> 8) & 0x3ff] +
                        sintable[(wx[2] >> 8) & 0x3ff] +
                        sintable[(wx[3] >> 8) & 0x3ff]
                    ) >> 2];

                    ++sb;

                    for(int i=0; i<4; i++) {
                        wx[i] += sx[i];
                    }
                }

                for(int i=0; i<4; i++) {
                    wy[i] += sy[i];
                }
            }

            // Display logo
            double alpha = 0.7 + 0.3 * sin(0.3 * time * 3.1415);
            int lx = 127, ly = 40;
            for(int y=0; y<logo_height; y++) {
                // blackit is true in order to create the black noisy stripes
                bool blackit = false;
                if(
                    (
                        (alpha >= 0.4 && alpha <= 0.42) ||
                        (alpha >= 0.71 && alpha <= 0.714)
                    ) && !(y % (1 + (rand() % logo_height)))) {
                    blackit = true;
                }

                for(int x=0; x<logo_width; x++) {
                    unsigned short* cp = &screen[(lx + x) + ((ly + y) * anim_w)];

                    unsigned short
                        c = logo[x + y * logo_width],
                        s = *cp;

                    BYTE a = logo_alpha[x + y * logo_width];

                    if(blackit) c = 0, a = 0;

                    double ac = alpha * ((double)a / 255.0f);

                    unsigned int
                        r = (unsigned int)((extract_r(c) * ac) + (extract_r(s) * (1.0 - ac))),
                        g = (unsigned int)((extract_g(c) * ac) + (extract_g(s) * (1.0 - ac))),
                        b = (unsigned int)((extract_b(c) * ac) + (extract_b(s) * (1.0 - ac)));

                    *cp = anim_color(r, g, b);
                }
            }
        }

        // Blit surface
        HDC hdc = ::GetDC(hwnd);
        ::SetDIBitsToDevice(hdc, 0, 0, anim_w, anim_h, 0, 0, 0, anim_h, (void*)screen, bmi, DIB_RGB_COLORS);

        // Draw text
        {
            static unsigned int textidx = 0;

            ::SetBkMode(hdc, TRANSPARENT);
            ::SetTextColor(hdc, 0xDDDDAA);
            ::SelectObject(hdc, font);

            static double tdlast = 0.0f;

            double td = time - tdlast;
            if(td > 2.5) {

                if(textidx+1 == sizeof(texts) / sizeof(uistring)) {
                    textidx = 0;
                } else {
                    textidx++;
                }

                tdlast = time;
            }

            ::DrawText(
                hdc,
                texts[textidx].c_str(),
                (int)texts[textidx].size() + 1,
                &textrect,
                DT_CENTER
            );
        }

        // Some idle time to give other threads the chance to process
        Sleep(5);
    }

    // Delete GDI Objects
    DeleteObject(font);

    // Delete resources
    delete gp_logo; gp_logo = NULL;
    delete logo; logo = NULL;
    delete logo_alpha; logo_alpha = NULL;
    delete[] screen; screen = NULL;

    // Shutdown GDI+
    Gdiplus::GdiplusShutdown(gp_tok);
}

void HelpAboutView::StartDrawingThread()
{
    anim_running = true;

    this->drawingThread = new boost::thread(
        &HelpAboutView::DrawingThread,
        this->Parent()->Handle(),
        this->bitmapinfo
    );
}

void HelpAboutView::OnCreated()
{
    // Initialize bitmap info header for 16-bit GDI graphics
    this->bitmapinfo = (BITMAPINFO*) malloc(sizeof(BITMAPINFOHEADER) + 12);
    ::ZeroMemory(&this->bitmapinfo->bmiHeader, sizeof(BITMAPINFOHEADER));

    bitmapinfo->bmiHeader.biSize        = sizeof(BITMAPINFOHEADER);
    bitmapinfo->bmiHeader.biWidth       = anim_w;
    bitmapinfo->bmiHeader.biHeight      = -anim_h;
    bitmapinfo->bmiHeader.biBitCount    = 16;
    bitmapinfo->bmiHeader.biPlanes      = 1;
    bitmapinfo->bmiHeader.biCompression = BI_BITFIELDS;

    // Color masks. Since we got 16-bit, we have 5-6-5 RGB, so we need to configure
    // the bitmap info header according to this color space.
    *((long*)bitmapinfo->bmiColors +0) = 0xF800;
    *((long*)bitmapinfo->bmiColors +1) = 0x07E0;
    *((long*)bitmapinfo->bmiColors +2) = 0x001F;
}

void HelpAboutView::OnDestroyed()
{
    // Indicate drawing thread to stop
    anim_running = false;

    // Wait for thread exit
    this->drawingThread->join();

    // Delete thread and other stuff
    if(this->drawingThread) {
        delete this->drawingThread;
    }

    if(this->bitmapinfo) {
        free(this->bitmapinfo);
        this->bitmapinfo = NULL;
    }

}<|endoftext|>


<commit_before>#include <map>
#include <vector>
#include <string>
#include <sstream>
#include <lua.hpp>
#include "src/debug.h"
#include "src/animatedimage.h"
#include "src/button.h"
#include "src/camera.h"
#include "src/color.h"
#include "src/entity.h"
#include "src/input.h"
#include "src/math.h"
#include "src/motionstate.h"
#include "src/physics.h"
#include "src/rect.h"
#include "src/state.h"
#include "src/statemanager.h"
#include "src/text.h"
#include "src/timer.h"
#include "src/vectors.h"
#include "src/window.h"
#include "src/luascript.h"
#include "luac/luacvector2f.h"
#include "luac/luacrectf.h"
#include "luac/luacphysics.h"
#include "luac/luacentity.h"
#include "luac/luacdebug.h"
#include "luac/luaccolor.h"
#include "luac/luactimer.h"
#include "luac/luacinput.h"
#include "luac/luacstate.h"
#include "luacscript.h"

const LuaC::LuaScriptLib::TLuaLibs LuaC::LuaScriptLib::sLuaLibs = LuaC::LuaScriptLib::CreateLibMap();
const LuaC::LuaScriptLib::TTableAdders LuaC::LuaScriptLib::sTableAdders = LuaC::LuaScriptLib::CreateAdderMap();
const LuaC::LuaScriptLib::TUdataCopiers LuaC::LuaScriptLib::sUdataCopiers = LuaC::LuaScriptLib::CreateCopierMap();

int LuaC::LuaScriptLib::StackDump(lua_State *l, bool toLog){
    std::stringstream ss;
    ss << "Stack: ";
    for (int i = 1, top = lua_gettop(l); i <= top; ++i){
        int t = lua_type(l, i);
        ss << "@" << i << ": ";
        switch (t) {
            //Strings
            case LUA_TSTRING:
                ss << lua_tostring(l, i);
                break;
            //Bools
            case LUA_TBOOLEAN:
                ss << (lua_toboolean(l, i) ? "True" : "False");
                break;
            //Numbers
            case LUA_TNUMBER:
                ss << lua_tonumber(l, i);
                break;
            //Userdata
            case LUA_TUSERDATA:
                ss << lua_typename(l, t) << " (" << readType(l, i) << ")";
                break;
            //Other (tables/etc)
            default:
                ss << lua_typename(l, t);
                break;
        }
        ss << ", ";
    }
    if (toLog)
        Debug::Log(ss.str());
    else
        std::cout << ss.str() << std::endl;
    return 0;
}
std::string LuaC::LuaScriptLib::readType(lua_State *l, int i){
    //Stack: some # of params, i corresponds to the udata we want to identify
    std::string type = "";
    //Get the metatable of udata at index i
    if (lua_getmetatable(l, i)){
        //Stack: stuff, udata's metatable
        //Get the "type" field
        lua_getfield(l, -1, "type");
        //Stack: stuff, udata metatable, typename
        //Get the type from the stack
        if (lua_isstring(l, -1))
            type = luaL_checkstring(l, -1);
        //Stack: stuff, udata metatable, typename
        //Stack contains the typename and the metatable, pop them off
        lua_pop(l, 2);
    }
    return type;
}
int LuaC::LuaScriptLib::requireLib(lua_State *l){
    //Try to look up the module desired, if it's one of ours load it, if not error
    std::string module = lua_tostring(l, -1);
    TLuaLibs::const_iterator fnd = sLuaLibs.find(module);
    if (fnd != sLuaLibs.end())
        lua_pushcfunction(l, fnd->second);
    else {
        std::string err = "requireLib Error: Failed to find: "
            + module + "\n";
        lua_pushstring(l, err.c_str());
    }
    return 1;
}
int LuaC::LuaScriptLib::requireScript(lua_State *l){
    //Check if the script is an engine script, if yes push DoScript, if no error
    std::string script = lua_tostring(l, -1);
    if (script.substr(0, 7) == "scripts"){
        std::string scriptFile = "../res/" + script;
        std::ifstream checkFile(scriptFile.c_str());
        if (checkFile.good()){
            checkFile.close();
            lua_pushstring(l, scriptFile.c_str());
            lua_pushcfunction(l, LuaC::LuaScriptLib::doScript);
        }
        else {
            std::string err = "LuaCScript::RequireScript Error: Failed to find: "
                + scriptFile + "\n";
            std::cout << err << std::endl;
            lua_pushstring(l, err.c_str());
        }
    }
    //If not an engine script, nothing to return
    else
        return 0;
    //If we found script or failed to load engine script we've got a result to return
    return 1;
}
std::vector<std::string> LuaC::LuaScriptLib::checkUserData(lua_State *l){
    //l stack: params
    //We want to step through and record the typenames of the userdata
    std::vector<std::string> udata;
    for (int i = 1, top = lua_gettop(l); i <= top; ++i){
        int t = lua_type(l, i);
        std::string luaTName = lua_typename(l, t);
        //If we find some userdata, read the type and store it
        if (luaTName == "userdata"){
            udata.push_back(readType(l, i));
        }
    }
    return udata;
}
void LuaC::LuaScriptLib::setUserData(lua_State *l, const std::vector<std::string> &types){
    //l stack: params
    //Step through and find udata, and register it according to the value at the vector
    //after each registration, increment vector pos
    std::vector<std::string>::const_iterator iter = types.begin();
    for (int i = 1, top = lua_gettop(l); i <= top; ++i && iter != types.end()){
        int t = lua_type(l, i);
        std::string luaTName = lua_typename(l, t);
        //If we find some userdata, read the type and register it accordingly
        if (luaTName == "userdata"){
            //function not being called?
            TTableAdders::const_iterator fnd = sTableAdders.find(*iter);
            if (fnd != sTableAdders.end()){
                fnd->second(l, (i - top - 1));
                ++iter;
            }
            else
                Debug::Log("Failed to find adder: " + *iter);
        }
    }
}
void LuaC::LuaScriptLib::CopyStack(lua_State *sender, lua_State *reciever, int numVals){
    /*
    *  Description of how we properly loop through the stack to preserver
    *  the ordering of the data
    *  stack: 10, "string", udata, 45
    *  numVals = 2
    *  top = 4
    *  45 @ -1 ie. @ 4
    *  want to pass 4 & 3 starting at 3
    *  so loop from top - (numVals - 1) to top
    */
    int top = lua_gettop(sender);
    for (int i = top - (numVals - 1); i < top + 1; ++i)
        CopyData(sender, i, reciever);
}
void LuaC::LuaScriptLib::CopyData(lua_State *sender, int idx, lua_State *reciever){
    int t = lua_type(sender, idx);
    switch (t) {
        //Strings
        case LUA_TSTRING:
            lua_pushstring(reciever, lua_tostring(sender, idx));
            break;
        //Bools
        case LUA_TBOOLEAN:
            lua_pushboolean(reciever, lua_toboolean(sender, idx));
            break;
        //Numbers
        case LUA_TNUMBER:
            lua_pushnumber(reciever, lua_tonumber(sender, idx));
            break;
        //Userdata
        case LUA_TUSERDATA:
            CopyUdata(sender, idx, reciever);
            break;
        //Other (tables/etc)
        //How to copy tables?
        default:
            break;
    }
}
void LuaC::LuaScriptLib::CopyUdata(lua_State *sender, int idx, lua_State *reciever){
    std::string type = readType(sender, idx);
    TUdataCopiers::const_iterator fnd = sUdataCopiers.find(type);
    if (fnd != sUdataCopiers.end())
        fnd->second(sender, idx, reciever);
    else
        Debug::Log("LuaScriptLib::CopyUdata: Failed to find userdata copier for type: " + type);
}
int LuaC::LuaScriptLib::LuaOpenLib(lua_State *l, const std::string &metatable,
    const std::string &className, const luaL_reg *lib, int (*call)(lua_State*))
{
    //Stack: lib name
    //Push the metatable to contain the fcns onto the stack
    luaL_newmetatable(l, metatable.c_str());
    //Copy metatable from -1 to the top
    lua_pushvalue(l, -1);
    //Set table at -2 key of __index = top of stack
    //ie. LPC.LuaRect.__index = table containing luaRectLib_m
    lua_setfield(l, -2, "__index");
    //Register the lib to the metatable at top of stack
    luaL_register(l, NULL, lib);
    //Stack: lib name, metatable
    //Add type identifier to the metatable
    lua_pushstring(l, className.c_str());
    lua_setfield(l, -2, "type");
    //Stack: lib name, metatable
    //Setup the LuaRect table, for making LuaRects
    lua_newtable(l);
    //Stack: lib name, metatable, table
    //Push the new fcn
    lua_pushcfunction(l, call);
    //Stack: lib name, metatable, table, newLuaRect fcn
    //Now newLuaRect fcn is @ key __call in the table
    lua_setfield(l, -2, "__call");
    //Stack: lib name, metatable, table
    //We want to set the table containing __call to be the metatable
    //of the LuaRect metatable
    lua_setmetatable(l, -2);
    //Stack: lib name, metatable
    //Name our metatable and make it global
    lua_setglobal(l, className.c_str());
    //Stack: lib name
    return 0;
}
void LuaC::LuaScriptLib::Add(lua_State *l, int i, const std::string &metatable){
    //Given stack containing unknown amount of things along with the udata
    //udata is at index i
    luaL_getmetatable(l, metatable.c_str());
    //Now stack is ??? with the metatable at top
    //So we know the index of our rect is bumped down 1 more so we adjust
    //and set the table
    lua_setmetatable(l, i - 1);
}
int LuaC::LuaScriptLib::doScript(lua_State *l){
    std::string script = lua_tostring(l, 0);
    luaL_dofile(l, script.c_str());
    return 0;
}
LuaC::LuaScriptLib::TLuaLibs LuaC::LuaScriptLib::CreateLibMap(){
    TLuaLibs map;
    map["AnimatedImage"] = &AnimatedImage::RegisterLua;
    map["Button"]        = &Button::RegisterLua;
    map["Camera"]        = &Camera::RegisterLua;
    map["Color"]         = &Color::RegisterLua;
    map["Debug"]         = &Debug::RegisterLua;
    map["Entity"]        = &Entity::RegisterLua;
    map["Image"]         = &Image::RegisterLua;
    map["Input"]         = &Input::RegisterLua;
    map["Math"]          = &Math::RegisterLua;
    map["MotionState"]   = &MotionState::RegisterLua;
    map["Physics"]       = &Physics::RegisterLua;
    map["Rect"]          = &Rectf::RegisterLua;
    map["State"]         = &State::RegisterLua;
    map["StateManager"]  = &StateManager::RegisterLua;
    map["Text"]          = &Text::RegisterLua;
    map["Timer"]         = &Timer::RegisterLua;
    map["Vector2"]       = &Vector2f::RegisterLua;
    map["Window"]        = &Window::RegisterLua;
    //Debug testing of libs
    map["TestEntity"]   = &EntityLib::luaopen_entity;
    map["TestRectf"]    = &RectfLib::luaopen_rectf;
    map["TestPhysics"]  = &PhysicsLib::luaopen_physics;
    map["TestVector2f"] = &Vector2fLib::luaopen_vector2f;
    map["TestDebug"]    = &DebugLib::luaopen_debug;
    map["TestColor"]    = &ColorLib::luaopen_color;
    map["TestTimer"]    = &TimerLib::luaopen_timer;
    map["TestInput"]    = &InputLib::luaopen_input;
    map["TestState"]    = &StateLib::luaopen_state;
    map["TestLuaScript"] = LuaScriptLib::luaopen_luascript;
    return map;
}
LuaC::LuaScriptLib::TTableAdders LuaC::LuaScriptLib::CreateAdderMap(){
    TTableAdders map;
    map[entityClass]    = &EntityLib::addEntity;
    map[rectfClass]     = &RectfLib::addRectf;
    map[physicsClass]   = &PhysicsLib::addPhysics;
    map[vector2fClass]  = &Vector2fLib::addVector2f;
    map[colorClass]     = &ColorLib::addColor;
    map[timerClass]     = &TimerLib::addTimer;
    return map;
}
LuaC::LuaScriptLib::TUdataCopiers LuaC::LuaScriptLib::CreateCopierMap(){
    TUdataCopiers map;
    map[vector2fClass] = &Vector2fLib::CopyVector2f;
    return map;
}
const luaL_reg LuaC::LuaScriptLib::luaScriptLib[] = {
    { "stackDump", luaStackDump },
    { NULL, NULL}
};
int LuaC::LuaScriptLib::luaopen_luascript(lua_State *l){
    luaL_register(l, luaScriptClass.c_str(), luaScriptLib);
    return 0;
}
int LuaC::LuaScriptLib::luaStackDump(lua_State *l){
    //Stack: the lua script table, bool of whether to
    //dump to file, and the data to check
    bool toLog = true;
    //If a bool flag for toLog is passed, get it and remove it
    //so it won't show up in the stack dump
    if (lua_isboolean(l, 1)){
        toLog = lua_toboolean(l, 1);
        lua_remove(l, 1);
    }
    StackDump(l, toLog);
    return 0;
}
<commit_msg>making the CopyData function switch statement a bit<commit_after>#include <map>
#include <vector>
#include <string>
#include <sstream>
#include <lua.hpp>
#include "src/debug.h"
#include "src/animatedimage.h"
#include "src/button.h"
#include "src/camera.h"
#include "src/color.h"
#include "src/entity.h"
#include "src/input.h"
#include "src/math.h"
#include "src/motionstate.h"
#include "src/physics.h"
#include "src/rect.h"
#include "src/state.h"
#include "src/statemanager.h"
#include "src/text.h"
#include "src/timer.h"
#include "src/vectors.h"
#include "src/window.h"
#include "src/luascript.h"
#include "luac/luacvector2f.h"
#include "luac/luacrectf.h"
#include "luac/luacphysics.h"
#include "luac/luacentity.h"
#include "luac/luacdebug.h"
#include "luac/luaccolor.h"
#include "luac/luactimer.h"
#include "luac/luacinput.h"
#include "luac/luacstate.h"
#include "luacscript.h"

const LuaC::LuaScriptLib::TLuaLibs LuaC::LuaScriptLib::sLuaLibs = LuaC::LuaScriptLib::CreateLibMap();
const LuaC::LuaScriptLib::TTableAdders LuaC::LuaScriptLib::sTableAdders = LuaC::LuaScriptLib::CreateAdderMap();
const LuaC::LuaScriptLib::TUdataCopiers LuaC::LuaScriptLib::sUdataCopiers = LuaC::LuaScriptLib::CreateCopierMap();

int LuaC::LuaScriptLib::StackDump(lua_State *l, bool toLog){
    std::stringstream ss;
    ss << "Stack: ";
    for (int i = 1, top = lua_gettop(l); i <= top; ++i){
        int t = lua_type(l, i);
        ss << "@" << i << ": ";
        switch (t) {
            //Strings
            case LUA_TSTRING:
                ss << lua_tostring(l, i);
                break;
            //Bools
            case LUA_TBOOLEAN:
                ss << (lua_toboolean(l, i) ? "True" : "False");
                break;
            //Numbers
            case LUA_TNUMBER:
                ss << lua_tonumber(l, i);
                break;
            //Userdata
            case LUA_TUSERDATA:
                ss << lua_typename(l, t) << " (" << readType(l, i) << ")";
                break;
            //Other (tables/etc)
            default:
                ss << lua_typename(l, t);
                break;
        }
        ss << ", ";
    }
    if (toLog)
        Debug::Log(ss.str());
    else
        std::cout << ss.str() << std::endl;
    return 0;
}
std::string LuaC::LuaScriptLib::readType(lua_State *l, int i){
    //Stack: some # of params, i corresponds to the udata we want to identify
    std::string type = "";
    //Get the metatable of udata at index i
    if (lua_getmetatable(l, i)){
        //Stack: stuff, udata's metatable
        //Get the "type" field
        lua_getfield(l, -1, "type");
        //Stack: stuff, udata metatable, typename
        //Get the type from the stack
        if (lua_isstring(l, -1))
            type = luaL_checkstring(l, -1);
        //Stack: stuff, udata metatable, typename
        //Stack contains the typename and the metatable, pop them off
        lua_pop(l, 2);
    }
    return type;
}
int LuaC::LuaScriptLib::requireLib(lua_State *l){
    //Try to look up the module desired, if it's one of ours load it, if not error
    std::string module = lua_tostring(l, -1);
    TLuaLibs::const_iterator fnd = sLuaLibs.find(module);
    if (fnd != sLuaLibs.end())
        lua_pushcfunction(l, fnd->second);
    else {
        std::string err = "requireLib Error: Failed to find: "
            + module + "\n";
        lua_pushstring(l, err.c_str());
    }
    return 1;
}
int LuaC::LuaScriptLib::requireScript(lua_State *l){
    //Check if the script is an engine script, if yes push DoScript, if no error
    std::string script = lua_tostring(l, -1);
    if (script.substr(0, 7) == "scripts"){
        std::string scriptFile = "../res/" + script;
        std::ifstream checkFile(scriptFile.c_str());
        if (checkFile.good()){
            checkFile.close();
            lua_pushstring(l, scriptFile.c_str());
            lua_pushcfunction(l, LuaC::LuaScriptLib::doScript);
        }
        else {
            std::string err = "LuaCScript::RequireScript Error: Failed to find: "
                + scriptFile + "\n";
            std::cout << err << std::endl;
            lua_pushstring(l, err.c_str());
        }
    }
    //If not an engine script, nothing to return
    else
        return 0;
    //If we found script or failed to load engine script we've got a result to return
    return 1;
}
std::vector<std::string> LuaC::LuaScriptLib::checkUserData(lua_State *l){
    //l stack: params
    //We want to step through and record the typenames of the userdata
    std::vector<std::string> udata;
    for (int i = 1, top = lua_gettop(l); i <= top; ++i){
        int t = lua_type(l, i);
        std::string luaTName = lua_typename(l, t);
        //If we find some userdata, read the type and store it
        if (luaTName == "userdata"){
            udata.push_back(readType(l, i));
        }
    }
    return udata;
}
void LuaC::LuaScriptLib::setUserData(lua_State *l, const std::vector<std::string> &types){
    //l stack: params
    //Step through and find udata, and register it according to the value at the vector
    //after each registration, increment vector pos
    std::vector<std::string>::const_iterator iter = types.begin();
    for (int i = 1, top = lua_gettop(l); i <= top; ++i && iter != types.end()){
        int t = lua_type(l, i);
        std::string luaTName = lua_typename(l, t);
        //If we find some userdata, read the type and register it accordingly
        if (luaTName == "userdata"){
            //function not being called?
            TTableAdders::const_iterator fnd = sTableAdders.find(*iter);
            if (fnd != sTableAdders.end()){
                fnd->second(l, (i - top - 1));
                ++iter;
            }
            else
                Debug::Log("Failed to find adder: " + *iter);
        }
    }
}
void LuaC::LuaScriptLib::CopyStack(lua_State *sender, lua_State *reciever, int numVals){
    /*
    *  Description of how we properly loop through the stack to preserver
    *  the ordering of the data
    *  stack: 10, "string", udata, 45
    *  numVals = 2
    *  top = 4
    *  45 @ -1 ie. @ 4
    *  want to pass 4 & 3 starting at 3
    *  so loop from top - (numVals - 1) to top
    */
    int top = lua_gettop(sender);
    for (int i = top - (numVals - 1); i < top + 1; ++i)
        CopyData(sender, i, reciever);
}
void LuaC::LuaScriptLib::CopyData(lua_State *sender, int idx, lua_State *reciever){
    switch (lua_type(sender, idx)) {
        //Strings
        case LUA_TSTRING:
            lua_pushstring(reciever, lua_tostring(sender, idx));
            break;
        //Bools
        case LUA_TBOOLEAN:
            lua_pushboolean(reciever, lua_toboolean(sender, idx));
            break;
        //Numbers
        case LUA_TNUMBER:
            lua_pushnumber(reciever, lua_tonumber(sender, idx));
            break;
        //Userdata
        case LUA_TUSERDATA:
            CopyUdata(sender, idx, reciever);
            break;
        //Other (tables/etc)
        //How to copy tables?
        default:
            break;
    }
}
void LuaC::LuaScriptLib::CopyUdata(lua_State *sender, int idx, lua_State *reciever){
    std::string type = readType(sender, idx);
    TUdataCopiers::const_iterator fnd = sUdataCopiers.find(type);
    if (fnd != sUdataCopiers.end())
        fnd->second(sender, idx, reciever);
    else
        Debug::Log("LuaScriptLib::CopyUdata: Failed to find userdata copier for type: " + type);
}
int LuaC::LuaScriptLib::LuaOpenLib(lua_State *l, const std::string &metatable,
    const std::string &className, const luaL_reg *lib, int (*call)(lua_State*))
{
    //Stack: lib name
    //Push the metatable to contain the fcns onto the stack
    luaL_newmetatable(l, metatable.c_str());
    //Copy metatable from -1 to the top
    lua_pushvalue(l, -1);
    //Set table at -2 key of __index = top of stack
    //ie. LPC.LuaRect.__index = table containing luaRectLib_m
    lua_setfield(l, -2, "__index");
    //Register the lib to the metatable at top of stack
    luaL_register(l, NULL, lib);
    //Stack: lib name, metatable
    //Add type identifier to the metatable
    lua_pushstring(l, className.c_str());
    lua_setfield(l, -2, "type");
    //Stack: lib name, metatable
    //Setup the LuaRect table, for making LuaRects
    lua_newtable(l);
    //Stack: lib name, metatable, table
    //Push the new fcn
    lua_pushcfunction(l, call);
    //Stack: lib name, metatable, table, newLuaRect fcn
    //Now newLuaRect fcn is @ key __call in the table
    lua_setfield(l, -2, "__call");
    //Stack: lib name, metatable, table
    //We want to set the table containing __call to be the metatable
    //of the LuaRect metatable
    lua_setmetatable(l, -2);
    //Stack: lib name, metatable
    //Name our metatable and make it global
    lua_setglobal(l, className.c_str());
    //Stack: lib name
    return 0;
}
void LuaC::LuaScriptLib::Add(lua_State *l, int i, const std::string &metatable){
    //Given stack containing unknown amount of things along with the udata
    //udata is at index i
    luaL_getmetatable(l, metatable.c_str());
    //Now stack is ??? with the metatable at top
    //So we know the index of our rect is bumped down 1 more so we adjust
    //and set the table
    lua_setmetatable(l, i - 1);
}
int LuaC::LuaScriptLib::doScript(lua_State *l){
    std::string script = lua_tostring(l, 0);
    luaL_dofile(l, script.c_str());
    return 0;
}
LuaC::LuaScriptLib::TLuaLibs LuaC::LuaScriptLib::CreateLibMap(){
    TLuaLibs map;
    map["AnimatedImage"] = &AnimatedImage::RegisterLua;
    map["Button"]        = &Button::RegisterLua;
    map["Camera"]        = &Camera::RegisterLua;
    map["Color"]         = &Color::RegisterLua;
    map["Debug"]         = &Debug::RegisterLua;
    map["Entity"]        = &Entity::RegisterLua;
    map["Image"]         = &Image::RegisterLua;
    map["Input"]         = &Input::RegisterLua;
    map["Math"]          = &Math::RegisterLua;
    map["MotionState"]   = &MotionState::RegisterLua;
    map["Physics"]       = &Physics::RegisterLua;
    map["Rect"]          = &Rectf::RegisterLua;
    map["State"]         = &State::RegisterLua;
    map["StateManager"]  = &StateManager::RegisterLua;
    map["Text"]          = &Text::RegisterLua;
    map["Timer"]         = &Timer::RegisterLua;
    map["Vector2"]       = &Vector2f::RegisterLua;
    map["Window"]        = &Window::RegisterLua;
    //Debug testing of libs
    map["TestEntity"]   = &EntityLib::luaopen_entity;
    map["TestRectf"]    = &RectfLib::luaopen_rectf;
    map["TestPhysics"]  = &PhysicsLib::luaopen_physics;
    map["TestVector2f"] = &Vector2fLib::luaopen_vector2f;
    map["TestDebug"]    = &DebugLib::luaopen_debug;
    map["TestColor"]    = &ColorLib::luaopen_color;
    map["TestTimer"]    = &TimerLib::luaopen_timer;
    map["TestInput"]    = &InputLib::luaopen_input;
    map["TestState"]    = &StateLib::luaopen_state;
    map["TestLuaScript"] = LuaScriptLib::luaopen_luascript;
    return map;
}
LuaC::LuaScriptLib::TTableAdders LuaC::LuaScriptLib::CreateAdderMap(){
    TTableAdders map;
    map[entityClass]    = &EntityLib::addEntity;
    map[rectfClass]     = &RectfLib::addRectf;
    map[physicsClass]   = &PhysicsLib::addPhysics;
    map[vector2fClass]  = &Vector2fLib::addVector2f;
    map[colorClass]     = &ColorLib::addColor;
    map[timerClass]     = &TimerLib::addTimer;
    return map;
}
LuaC::LuaScriptLib::TUdataCopiers LuaC::LuaScriptLib::CreateCopierMap(){
    TUdataCopiers map;
    map[vector2fClass] = &Vector2fLib::CopyVector2f;
    return map;
}
const luaL_reg LuaC::LuaScriptLib::luaScriptLib[] = {
    { "stackDump", luaStackDump },
    { NULL, NULL}
};
int LuaC::LuaScriptLib::luaopen_luascript(lua_State *l){
    luaL_register(l, luaScriptClass.c_str(), luaScriptLib);
    return 0;
}
int LuaC::LuaScriptLib::luaStackDump(lua_State *l){
    //Stack: the lua script table, bool of whether to
    //dump to file, and the data to check
    bool toLog = true;
    //If a bool flag for toLog is passed, get it and remove it
    //so it won't show up in the stack dump
    if (lua_isboolean(l, 1)){
        toLog = lua_toboolean(l, 1);
        lua_remove(l, 1);
    }
    StackDump(l, toLog);
    return 0;
}
<|endoftext|>


<commit_before>/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * LXDE-Qt - a lightweight, Qt based, desktop toolset
 * http://razor-qt.org
 *
 * Copyright: 2010-2011 Razor team
 * Authors:
 *   Petr Vanek <petr@scribus.info>
 *
 * This program or library is free software; you can redistribute it
 * and/or modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301 USA
 *
 * END_COMMON_COPYRIGHT_HEADER */

#include <LXQt/SingleApplication>
#include <LXQt/PowerManager>
#include <LXQt/ScreenSaver>
#include <LXQt/Translator>
#include <QDesktopWidget>
#include <QCommandLineParser>
#include <QCoreApplication>

#include "leavedialog.h"

int main(int argc, char *argv[])
{
    LXQt::SingleApplication a(argc, argv);
    LXQt::Translator::translateApplication();

    LXQt::PowerManager powermanager(&a);
    LXQt::ScreenSaver screensaver(&a);

    QCommandLineParser parser;
    parser.setApplicationDescription(QStringLiteral("lxqt-leave"));
    parser.addHelpOption();
    parser.addVersionOption();

    QCommandLineOption logoutOption(QStringLiteral("logout"), QCoreApplication::translate("main", "Logout."));
    parser.addOption(logoutOption);

    QCommandLineOption lockscreenOption(QStringLiteral("lockscreen"), QCoreApplication::translate("main", "Lockscreen."));
    parser.addOption(lockscreenOption);

    QCommandLineOption suspendOption(QStringLiteral("suspend"), QCoreApplication::translate("main", "Suspend."));
    parser.addOption(suspendOption);

    QCommandLineOption hibernateOption(QStringLiteral("hibernate"), QCoreApplication::translate("main", "Hibernate."));
    parser.addOption(hibernateOption);

    QCommandLineOption shutdownOption(QStringLiteral("shutdown"), QCoreApplication::translate("main", "Shutdown."));
    parser.addOption(shutdownOption);

    QCommandLineOption rebootOption(QStringLiteral("reboot"), QCoreApplication::translate("main", "Reboot."));
    parser.addOption(rebootOption);

    parser.process(a);

    if (parser.isSet(logoutOption)) {
        powermanager.logout();
        return 0;
    }

    if (parser.isSet(lockscreenOption)) {
        a.connect(&screensaver, &LXQt::ScreenSaver::done, &a, &LXQt::Application::quit);
        screensaver.lockScreen();
        a.exec();
        return 0;
    }

    if (parser.isSet(suspendOption)) {
        powermanager.suspend();
        return 0;
    }

    if (parser.isSet(hibernateOption)) {
        powermanager.hibernate();
        return 0;
    }

    if (parser.isSet(shutdownOption)) {
        powermanager.shutdown();
        return 0;
    }

    if (parser.isSet(rebootOption)) {
        powermanager.reboot();
        return 0;
    }

    LeaveDialog dialog;
    a.setActivationWindow(&dialog);
    dialog.setGeometry(QStyle::alignedRect(Qt::LeftToRight,
                Qt::AlignCenter,
                dialog.size(),
                qApp->desktop()->screenGeometry(QCursor::pos())));
    dialog.setMaximumSize(dialog.minimumSize());
    return dialog.exec();
}
<commit_msg>leave: do not set maximum size as minimum size<commit_after>/* BEGIN_COMMON_COPYRIGHT_HEADER
 * (c)LGPL2+
 *
 * LXDE-Qt - a lightweight, Qt based, desktop toolset
 * http://razor-qt.org
 *
 * Copyright: 2010-2011 Razor team
 * Authors:
 *   Petr Vanek <petr@scribus.info>
 *
 * This program or library is free software; you can redistribute it
 * and/or modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.

 * You should have received a copy of the GNU Lesser General
 * Public License along with this library; if not, write to the
 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
 * Boston, MA 02110-1301 USA
 *
 * END_COMMON_COPYRIGHT_HEADER */

#include <LXQt/SingleApplication>
#include <LXQt/PowerManager>
#include <LXQt/ScreenSaver>
#include <LXQt/Translator>
#include <QDesktopWidget>
#include <QCommandLineParser>
#include <QCoreApplication>

#include "leavedialog.h"

int main(int argc, char *argv[])
{
    LXQt::SingleApplication a(argc, argv);
    LXQt::Translator::translateApplication();

    LXQt::PowerManager powermanager(&a);
    LXQt::ScreenSaver screensaver(&a);

    QCommandLineParser parser;
    parser.setApplicationDescription(QStringLiteral("lxqt-leave"));
    parser.addHelpOption();
    parser.addVersionOption();

    QCommandLineOption logoutOption(QStringLiteral("logout"), QCoreApplication::translate("main", "Logout."));
    parser.addOption(logoutOption);

    QCommandLineOption lockscreenOption(QStringLiteral("lockscreen"), QCoreApplication::translate("main", "Lockscreen."));
    parser.addOption(lockscreenOption);

    QCommandLineOption suspendOption(QStringLiteral("suspend"), QCoreApplication::translate("main", "Suspend."));
    parser.addOption(suspendOption);

    QCommandLineOption hibernateOption(QStringLiteral("hibernate"), QCoreApplication::translate("main", "Hibernate."));
    parser.addOption(hibernateOption);

    QCommandLineOption shutdownOption(QStringLiteral("shutdown"), QCoreApplication::translate("main", "Shutdown."));
    parser.addOption(shutdownOption);

    QCommandLineOption rebootOption(QStringLiteral("reboot"), QCoreApplication::translate("main", "Reboot."));
    parser.addOption(rebootOption);

    parser.process(a);

    if (parser.isSet(logoutOption)) {
        powermanager.logout();
        return 0;
    }

    if (parser.isSet(lockscreenOption)) {
        a.connect(&screensaver, &LXQt::ScreenSaver::done, &a, &LXQt::Application::quit);
        screensaver.lockScreen();
        a.exec();
        return 0;
    }

    if (parser.isSet(suspendOption)) {
        powermanager.suspend();
        return 0;
    }

    if (parser.isSet(hibernateOption)) {
        powermanager.hibernate();
        return 0;
    }

    if (parser.isSet(shutdownOption)) {
        powermanager.shutdown();
        return 0;
    }

    if (parser.isSet(rebootOption)) {
        powermanager.reboot();
        return 0;
    }

    LeaveDialog dialog;
    a.setActivationWindow(&dialog);
    dialog.setMinimumSize(dialog.sizeHint());
    dialog.setGeometry(QStyle::alignedRect(Qt::LeftToRight,
                Qt::AlignCenter,
                dialog.size(),
                qApp->desktop()->screenGeometry(QCursor::pos())));
    dialog.setMaximumSize(dialog.size());
    return dialog.exec();
}
<|endoftext|>