Commit 83ea0d2a authored by Paul Asmuth's avatar Paul Asmuth
Browse files

hide context implementation internals

parent 4db23960
Loading
Loading
Loading
Loading
+0 −1
Original line number Diff line number Diff line
@@ -28,7 +28,6 @@ add_library(signaltk STATIC
    graphics/rasterize.cc
    graphics/png.cc
    elements/context.cc
    elements/element.cc
    elements/plot/gridlines.cc
    elements/plot/axes.cc
    elements/plot/plot_domain.cc
+77 −0
Original line number Diff line number Diff line
@@ -7,9 +7,86 @@
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include <memory>
#include "context.h"

namespace signaltk {

struct Element {
  ~Element();
  void* config;
  std::function<void (void* config)> config_destroy;
};

using ElementRef = std::unique_ptr<Element>;

Element::~Element() {
  if (config_destroy) {
    config_destroy(config);
  }
}

struct context {
  std::unique_ptr<Layer> frame;
  std::stack<Element*> element_stack;
  std::vector<ElementRef> elements;
};

context* context_create_image(uint32_t width, uint32_t height) {
  return new context {
    .frame = std::make_unique<Layer>(width, height),
  };
}

void context_reset(context* ctx) {
}

void context_destroy(context* ctx) {
  context_reset(ctx);
  delete ctx;
}

uint32_t context_width(const context* ctx) {
  return ctx->frame->width;
}

uint32_t context_height(const context* ctx) {
  return ctx->frame->height;
}

Layer* context_frame(context* ctx) {
  return ctx->frame.get();
}

Status element_config(const context* ctx, const void** elem) {
  if (ctx->elements.empty()) {
    return Status::ERROR_INVALID_ELEM;
  }

  *elem = ctx->element_stack.top()->config;
  return OK;
}

Status element_config(context* ctx, void** elem) {
  if (ctx->elements.empty()) {
    return Status::ERROR_INVALID_ELEM;
  }

  *elem = ctx->element_stack.top()->config;
  return OK;
}

Status element_add(
    context* ctx,
    void* config,
    std::function<void(void*)> config_destroy) {
  auto e = std::make_unique<Element>();
  e->config = config;
  e->config_destroy = config_destroy;
  ctx->element_stack.emplace(e.get());
  ctx->elements.emplace_back(std::move(e));
  return OK;
}

} // namespace signaltk
+13 −13
Original line number Diff line number Diff line
@@ -9,28 +9,28 @@
 */
#pragma once
#include <stack>
#include "element.h"
#include "graphics/layer.h"

namespace signaltk {

class Context {
public:
struct context;

  template <typename T>
  Status element_config(T** elem);
context* context_create_image(uint32_t width, uint32_t height);
void context_reset(context* ctx);
void context_destroy(context* ctx);

  template <typename T>
  Status element_config(T const** elem) const;
uint32_t context_width(const context* ctx);
uint32_t context_height(const context* ctx);
Layer* context_frame(context* ctx);

  template <typename T>
  Status element_add();
Status element_config(context* ctx, void** elem);

  std::unique_ptr<Layer> frame;
Status element_config(const context* ctx, const void** elem);

protected:
  std::stack<ElementRef> elements;
};
Status element_add(
    context* ctx,
    void* config,
    std::function<void(void* config)> config_destroy);

} // namespace signaltk

+15 −15
Original line number Diff line number Diff line
@@ -12,33 +12,33 @@
namespace signaltk {

template <typename T>
Status Context::element_config(T** elem) {
  if (elements.empty()) {
    return Status::ERROR_INVALID_ELEM;
Status element_config_as(context* ctx, T** elem) {
  void* e;
  if (auto rc = element_config(ctx, &e); rc) {
    return rc;
  }

  *elem = static_cast<T*>(elements.top()->config);
  *elem = static_cast<T*>(e);
  return OK;
}

template <typename T>
Status Context::element_config(T const** elem) const {
  if (elements.empty()) {
    return Status::ERROR_INVALID_ELEM;
Status element_config_as(const context* ctx, T const** elem) {
  const void* e;
  if (auto rc = element_config(ctx, &e); rc) {
    return rc;
  }

  *elem = static_cast<const T*>(elements.top()->config);
  *elem = static_cast<const T*>(e);
  return OK;
}

template <typename T>
Status Context::element_add() {
  auto e = std::make_unique<Element>();
  e->config = new T();
  e->destroy = [] (Element* e) { delete static_cast<T*>(e->config); };

  elements.emplace(std::move(e));
  return OK;
Status element_add(context* ctx) {
  return element_add(
      ctx,
      new T(),
      [] (void* c) { delete static_cast<T*>(c); });
}

} // namespace signaltk

elements/element.cc

deleted100644 → 0
+0 −21
Original line number Diff line number Diff line
/**
 * This file is part of the "signaltk" project
 *   Copyright (c) 2018 Paul Asmuth
 *
 * libstx is free software: you can redistribute it and/or modify it under
 * the terms of the GNU General Public License v3.0. You should have received a
 * copy of the GNU General Public License along with this program. If not, see
 * <http://www.gnu.org/licenses/>.
 */
#include "element.h"

namespace signaltk {

Element::~Element() {
  if (destroy) {
    destroy(this);
  }
}

} // namespace signaltk
Loading