Skip to content

Commit

Permalink
base architecture (wip)
Browse files Browse the repository at this point in the history
  • Loading branch information
gavrilaf committed Nov 19, 2018
1 parent 9ea401c commit 5ca0e63
Show file tree
Hide file tree
Showing 9 changed files with 143 additions and 34 deletions.
26 changes: 23 additions & 3 deletions MiniTerm.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,11 @@
46078DC421A1D5BD0084334F /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 46078DC221A1D5BD0084334F /* LaunchScreen.storyboard */; };
4651DC4121A1E12300D7F732 /* ScreenBuffer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4651DC4021A1E12300D7F732 /* ScreenBuffer.swift */; };
4651DC4421A1E7D400D7F732 /* ScreenBufferSpec.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4651DC4321A1E7D400D7F732 /* ScreenBufferSpec.swift */; };
4651DC4621A2894400D7F732 /* CommandProcessor.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4651DC4521A2894400D7F732 /* CommandProcessor.swift */; };
4651DC4821A28C3800D7F732 /* StreamWriter.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4651DC4721A28C3800D7F732 /* StreamWriter.swift */; };
4651DC4A21A290AE00D7F732 /* InteractionHandler.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4651DC4921A290AE00D7F732 /* InteractionHandler.swift */; };
4651DC4C21A2911A00D7F732 /* ScreenBufferProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4651DC4B21A2911A00D7F732 /* ScreenBufferProtocol.swift */; };
4651DC4E21A291DA00D7F732 /* InteractionHandlerProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4651DC4D21A291DA00D7F732 /* InteractionHandlerProtocol.swift */; };
/* End PBXBuildFile section */

/* Begin PBXContainerItemProxy section */
Expand All @@ -42,6 +47,11 @@
46078DD021A1D5BD0084334F /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
4651DC4021A1E12300D7F732 /* ScreenBuffer.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenBuffer.swift; sourceTree = "<group>"; };
4651DC4321A1E7D400D7F732 /* ScreenBufferSpec.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenBufferSpec.swift; sourceTree = "<group>"; };
4651DC4521A2894400D7F732 /* CommandProcessor.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = CommandProcessor.swift; sourceTree = "<group>"; };
4651DC4721A28C3800D7F732 /* StreamWriter.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StreamWriter.swift; sourceTree = "<group>"; };
4651DC4921A290AE00D7F732 /* InteractionHandler.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InteractionHandler.swift; sourceTree = "<group>"; };
4651DC4B21A2911A00D7F732 /* ScreenBufferProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ScreenBufferProtocol.swift; sourceTree = "<group>"; };
4651DC4D21A291DA00D7F732 /* InteractionHandlerProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = InteractionHandlerProtocol.swift; sourceTree = "<group>"; };
73D00DD269ABC033B402153B /* Pods-MiniTermTests.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MiniTermTests.debug.xcconfig"; path = "Pods/Target Support Files/Pods-MiniTermTests/Pods-MiniTermTests.debug.xcconfig"; sourceTree = "<group>"; };
76C608A921D52B58975A69EB /* Pods_MiniTerm.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Pods_MiniTerm.framework; sourceTree = BUILT_PRODUCTS_DIR; };
78795FFD745D2A3A8D018A3A /* Pods-MiniTerm.debug.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-MiniTerm.debug.xcconfig"; path = "Pods/Target Support Files/Pods-MiniTerm/Pods-MiniTerm.debug.xcconfig"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -103,7 +113,7 @@
isa = PBXGroup;
children = (
4651DC3F21A1DFD900D7F732 /* AppDelegate */,
4651DC3D21A1DD7000D7F732 /* Utils */,
4651DC3D21A1DD7000D7F732 /* Protocols */,
4651DC3C21A1DD6900D7F732 /* Logic */,
4651DC3A21A1DD5900D7F732 /* UI */,
);
Expand Down Expand Up @@ -131,15 +141,20 @@
isa = PBXGroup;
children = (
4651DC4021A1E12300D7F732 /* ScreenBuffer.swift */,
4651DC4521A2894400D7F732 /* CommandProcessor.swift */,
4651DC4921A290AE00D7F732 /* InteractionHandler.swift */,
);
path = Logic;
sourceTree = "<group>";
};
4651DC3D21A1DD7000D7F732 /* Utils */ = {
4651DC3D21A1DD7000D7F732 /* Protocols */ = {
isa = PBXGroup;
children = (
4651DC4721A28C3800D7F732 /* StreamWriter.swift */,
4651DC4B21A2911A00D7F732 /* ScreenBufferProtocol.swift */,
4651DC4D21A291DA00D7F732 /* InteractionHandlerProtocol.swift */,
);
path = Utils;
path = Protocols;
sourceTree = "<group>";
};
4651DC3E21A1DD9800D7F732 /* Terminal */ = {
Expand Down Expand Up @@ -342,9 +357,14 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
4651DC4621A2894400D7F732 /* CommandProcessor.swift in Sources */,
4651DC4121A1E12300D7F732 /* ScreenBuffer.swift in Sources */,
46078DBC21A1D5BC0084334F /* TerminalViewController.swift in Sources */,
4651DC4821A28C3800D7F732 /* StreamWriter.swift in Sources */,
46078DBA21A1D5BC0084334F /* AppDelegate.swift in Sources */,
4651DC4A21A290AE00D7F732 /* InteractionHandler.swift in Sources */,
4651DC4E21A291DA00D7F732 /* InteractionHandlerProtocol.swift in Sources */,
4651DC4C21A2911A00D7F732 /* ScreenBufferProtocol.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
Expand Down
8 changes: 8 additions & 0 deletions MiniTerm/Logic/CommandProcessor.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
import Foundation

class CommandProcessor {

func run(command: String, with stdout: StreamWriter) {
stdout.Write(string: "\(command): command not found!")
}
}
40 changes: 40 additions & 0 deletions MiniTerm/Logic/InteractionHandler.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import Foundation

class InteractionHandler: InteractionHandlerProtocol {

weak var updateDelegate: ScreenBufferUpdateDelegate?

func symbol(_ c: String) {
screenBuffer.addChar(c)
updateDelegate?.didScreenUpdate(with: screenBuffer)
}

func delete() {
screenBuffer.delete()
updateDelegate?.didScreenUpdate(with: screenBuffer)
}

func newLine() {
let command = screenBuffer.currentLine

screenBuffer.Open()
commandProcessor.run(command: command, with: screenBuffer)
screenBuffer.Close()

updateDelegate?.didScreenUpdate(with: screenBuffer)
}

func start() {
updateDelegate?.didScreenUpdate(with: screenBuffer)
}

init() {
screenBuffer = ScreenBuffer()
commandProcessor = CommandProcessor()
}

// MARK: - private

private let screenBuffer: ScreenBuffer
private let commandProcessor: CommandProcessor
}
33 changes: 21 additions & 12 deletions MiniTerm/Logic/ScreenBuffer.swift
Original file line number Diff line number Diff line change
@@ -1,24 +1,12 @@
import Foundation

protocol ScreenBufferDelegate: class {
func didBufferUpdate()
}


class ScreenBuffer {

enum Constant {
static let defaultPrompt = "> "
}

var prompt: String

weak var delegate: ScreenBufferDelegate?

var text: String {
return lines.joined(separator: "\n")
}

var currentLine: String {
let s = lines[lastIndex]
return String(s.suffix(from: s.index(s.startIndex, offsetBy: prompt.count)))
Expand Down Expand Up @@ -49,3 +37,24 @@ class ScreenBuffer {
return lines.count - 1
}
}

// MARK: -
extension ScreenBuffer: ScreenBufferProtocol {
var content: String {
return lines.joined(separator: "\n")
}
}

extension ScreenBuffer: StreamWriter {
func Write(string: String) {
lines[lastIndex].append(string)
}

func Open() {
lines.append("")
}

func Close() {
newLine()
}
}
13 changes: 13 additions & 0 deletions MiniTerm/Protocols/InteractionHandlerProtocol.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import Foundation

protocol InteractionHandlerProtocol {

func start()

func symbol(_ c: String)
func delete()
func newLine()

var updateDelegate: ScreenBufferUpdateDelegate? { get set }
}

9 changes: 9 additions & 0 deletions MiniTerm/Protocols/ScreenBufferProtocol.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Foundation

protocol ScreenBufferProtocol {
var content: String { get }
}

protocol ScreenBufferUpdateDelegate: class {
func didScreenUpdate(with buffer: ScreenBufferProtocol)
}
9 changes: 9 additions & 0 deletions MiniTerm/Protocols/StreamWriter.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
import Foundation


protocol StreamWriter {
func Open()
func Close()

func Write(string: String)
}
27 changes: 14 additions & 13 deletions MiniTerm/UI/Terminal/TerminalViewController.swift
Original file line number Diff line number Diff line change
Expand Up @@ -16,31 +16,32 @@ class TerminalViewController: UIViewController {
super.viewDidLoad()

textView.delegate = self
reloadContent()

textView.becomeFirstResponder()

handler = InteractionHandler()

handler.updateDelegate = self
handler.start()
}

private func reloadContent() {
textView.text = buffer.text
}

private let buffer = ScreenBuffer()
private var handler: InteractionHandlerProtocol!
}

extension TerminalViewController: UITextViewDelegate {
func textView(_ textView: UITextView, shouldChangeTextIn range: NSRange, replacementText text: String) -> Bool {
if text == "\n" {
buffer.newLine()
handler.newLine()
} else if text.count != 0 {
buffer.addChar(text)
handler.symbol(text)
} else if range.length == 1 {
buffer.delete()
handler.delete()
}

reloadContent()

return false
}
}

extension TerminalViewController: ScreenBufferUpdateDelegate {
func didScreenUpdate(with buffer: ScreenBufferProtocol) {
textView.text = buffer.content
}
}
12 changes: 6 additions & 6 deletions MiniTermTests/Logic/ScreenBufferSpec.swift
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class ScreenBufferSpec: QuickSpec {

describe("buffer init state") {
it("buffer text should contain default prompt") {
expect(subject.text).to(equal(ScreenBuffer.Constant.defaultPrompt))
expect(subject.content).to(equal(ScreenBuffer.Constant.defaultPrompt))
}

it("current line should be empty") {
Expand All @@ -31,7 +31,7 @@ class ScreenBufferSpec: QuickSpec {

it("buffer should contain correct text") {
let expected = ScreenBuffer.Constant.defaultPrompt + "A"
expect(subject.text).to(equal(expected))
expect(subject.content).to(equal(expected))
}

it("current line should contain one symbol") {
Expand All @@ -46,7 +46,7 @@ class ScreenBufferSpec: QuickSpec {

it("buffer should contain correct text") {
let expected = ScreenBuffer.Constant.defaultPrompt + "\n" + ScreenBuffer.Constant.defaultPrompt
expect(subject.text).to(equal(expected))
expect(subject.content).to(equal(expected))
}

it("current line should be empty") {
Expand All @@ -61,7 +61,7 @@ class ScreenBufferSpec: QuickSpec {
}

it("buffer text should contain default prompt") {
expect(subject.text).to(equal(ScreenBuffer.Constant.defaultPrompt))
expect(subject.content).to(equal(ScreenBuffer.Constant.defaultPrompt))
}

it("current line should be empty") {
Expand All @@ -77,7 +77,7 @@ class ScreenBufferSpec: QuickSpec {
}

it("buffer text should contain default prompt") {
expect(subject.text).to(equal(ScreenBuffer.Constant.defaultPrompt))
expect(subject.content).to(equal(ScreenBuffer.Constant.defaultPrompt))
}

it("current line should be empty") {
Expand All @@ -98,7 +98,7 @@ class ScreenBufferSpec: QuickSpec {

it("buffer should contain correct text") {
let expected = ScreenBuffer.Constant.defaultPrompt + "AB\n" + ScreenBuffer.Constant.defaultPrompt + "CD"
expect(subject.text).to(equal(expected))
expect(subject.content).to(equal(expected))
}

it("current line should contain correct text") {
Expand Down

0 comments on commit 5ca0e63

Please sign in to comment.