Skip to content

Commit

Permalink
Merge pull request #12 from j0tunn/feat/prj.05
Browse files Browse the repository at this point in the history
ДЗ-05. Editor
  • Loading branch information
j0tunn authored Dec 1, 2022
2 parents 1ac0509 + be37d51 commit 611bf5a
Show file tree
Hide file tree
Showing 10 changed files with 400 additions and 2 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ jobs:
submodules: true
- run: cmake . -DPATCH_VERSION=${{ github.run_number }}
- run: cmake --build .
- run: cmake --build . --target test && ./test
- run: '! test -f ./test || ./test'
- run: cmake --build . --target package
- name: Get package filename
id: get_pkg_filename
Expand Down
12 changes: 12 additions & 0 deletions projects/05/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
cmake_minimum_required(VERSION 3.10)

include(${CMAKE_CURRENT_SOURCE_DIR}/../../common/CMakeLists.txt)

project(editor VERSION ${PROJECT_VERSION})

add_executable(editor
main.cpp
)

# Package
setupCPack(editor)
53 changes: 53 additions & 0 deletions projects/05/controller.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
#pragma once

#include <memory>
#include <iostream>
#include "model.h"
#include "view.h"

class Controller {
public:
Controller()
: pModel_(nullptr)
, pView_(nullptr)
{}

~Controller() = default;

void NewDocument() {
pModel_ = std::make_unique<Model::Document>();
pView_ = std::make_unique<View::Document>(*pModel_);
}

void AddSquare(const unsigned int side) {
pModel_->AddObject<Model::Square>(side);
}

void AddCircle(const unsigned int radius) {
pModel_->AddObject<Model::Circle>(radius);
}

void DeleteLastObject() {
pModel_->RmLastObject();
}

void ExportDocument(const std::string& file) const {
const std::string documentContent = pModel_->Serialize();

std::cout << "Exporting document content '" << documentContent << "' into file '" << file << "'" << std::endl;
}

void ImportDocument(const std::string& file) {
std::cout << "Importing document content from file '" << file << "'" << std::endl;

// TODO: read file content
const std::string fileContent = "";

pModel_ = std::unique_ptr<Model::Document>(Model::Document::Deserialize(fileContent));
pView_ = std::make_unique<View::Document>(*pModel_);
}

private:
std::unique_ptr<Model::Document> pModel_;
std::unique_ptr<View::Document> pView_;
};
28 changes: 28 additions & 0 deletions projects/05/main.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#include <iostream>
#include <exception>
#include "controller.h"

using namespace std;

int main(int, char **) {
Controller app;

try {
app.NewDocument();

app.AddSquare(2);
app.AddCircle(3);
app.AddSquare(4);

app.DeleteLastObject();

app.ExportDocument("foo/bar.baz");

app.ImportDocument("foo/bar.baz");
} catch(exception& e) {
cout << e.what() << endl;
return 1;
}

return 0;
}
85 changes: 85 additions & 0 deletions projects/05/model.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
#pragma once

#include <memory>
#include <string>
#include <list>
#include <numeric>
#include "observer.h"

namespace Model {

///
class IObject {
public:
virtual ~IObject() = default;
virtual std::string Serialize() const = 0;
};

///
class Square : public IObject {
public:
Square(const unsigned int side) : side_(side) {}

std::string Serialize() const override {
return "square:" + std::to_string(side_);
}

unsigned int GetSide() const {
return side_;
}

private:
unsigned int side_;
};

///
class Circle : public IObject {
public:
Circle(const unsigned int radius) : radius_(radius) {}

std::string Serialize() const override {
return "circle:" + std::to_string(radius_);
}

unsigned int GetRadius() const {
return radius_;
}

private:
unsigned int radius_;
};

///
class Document : public Observable {
public:
static std::unique_ptr<Document> Deserialize(const std::string& str) {
std::unique_ptr<Document> pDoc(new Document());

// TODO: parse string, for each obj call pDoc->AddObject()

return pDoc;
}

template <typename T, typename... Args>
void AddObject(Args... args) {
auto pObj = new T(args...);
objects_.push_back(std::unique_ptr<IObject>(pObj));

NotifyNewObject(*pObj);
}

void RmLastObject() {
objects_.pop_back();

NotifyRmLastObject();
}

std::string Serialize() const {
return std::accumulate(objects_.begin(), objects_.end(), std::string(""), [](auto res, const auto& o) { return res + o->Serialize() + ";"; });
}

private:
std::list<std::unique_ptr<IObject> > objects_;
};

}
46 changes: 46 additions & 0 deletions projects/05/observer.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
#pragma once

#include <vector>
#include <stdexcept>

namespace Model {

class Square;
class Circle;

///
class IObserver {
public:
virtual ~IObserver() = default;

virtual void OnNewObject(const Square&) = 0;
virtual void OnNewObject(const Circle&) = 0;

virtual void OnRmLastObject() = 0;
};

///
class Observable {
public:
void AddObserver(IObserver* observer) {
observers_.push_back(observer);
}

void NotifyRmLastObject() {
for (auto observer : observers_) {
observer->OnRmLastObject();
}
}

template <typename T>
void NotifyNewObject(const T& obj) {
for (auto observer : observers_) {
observer->OnNewObject(obj);
}
}

private:
std::vector<IObserver*> observers_;
};

}
Binary file added projects/05/project-struct.jpeg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
92 changes: 92 additions & 0 deletions projects/05/project-struct.wsd
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
@startuml

class Controller {
-pModel_: Model::Document
-pView_: View::Document
+NewDocument()
+AddSquare(number)
+AddCircle(number)
+DeleteLastObject()
+ExportDocument(string)
+ImportDocument(string)
}

Controller o-- Model.Document
Controller o-- View.Document

namespace Model {
interface IObject {
+Serialize(): string
}
class Square {
-side_: number
+Square(number)
+Serialize()
+GetSide(): number
}
class Circle {
-radius_: number
+Circle(number)
+Serialize()
+GetRadius(): number
}
class Document {
-objects_: List<IObject>
+{static} Deserialize(string): Document
+AddObject<T, Args...>(Args...)
+RmLastObject()
+Serialize(): string
}
interface IObserver {
+OnNewObject(Square)
+OnNewObject(Circle)
+OnRmLastObject()
}
class Observable {
-observers_: List<IObserver>
+AddObserver(IObserver)
+NotifyNewObject<T>(T)
+NotifyRmLastObject()
}

IObject <|-- Square
IObject <|-- Circle
Observable <|-- Document
IObserver <.. Observable
Document o-- IObject

Square <.. .View.Square
Circle <.. .View.Circle
IObserver <|-- .View.Document
}

namespace View {
interface IDrawable {
+Draw()
}
class Square {
-model_: Model::Square
+Square(Model::Square)
+Draw()
}
class Circle {
-model_: Model::Circle
+Circle(Model::Circle)
+Draw()
}
class Document {
-subViews_: List<IDrawable>
+Document(Model::Document)
+OnRmLastObject()
+OnNewObject(Model::Square)
+OnNewObject(Model::Circle)
-AddSubView_<T, Model::U>(Model::U)
-Draw()
}

IDrawable <|-- Square
IDrawable <|-- Circle
Document o-- IDrawable
}

@enduml
Loading

0 comments on commit 611bf5a

Please sign in to comment.