Skip to content

Commit

Permalink
Update
Browse files Browse the repository at this point in the history
  • Loading branch information
JustinFincher committed May 13, 2020
1 parent 2adaf1a commit 6fec818
Show file tree
Hide file tree
Showing 17 changed files with 192 additions and 52 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import SwiftUI
import UserModule

final class ContentViewStore: ObservableObject {
var audioPermissionEnabled = AudioUniformProviderManager.shared.hasRecordPermission() {
@Published var audioPermissionEnabled = AudioUniformProviderManager.shared.hasRecordPermission() {
didSet {
if audioPermissionEnabled {
AudioUniformProviderManager.shared.requestPermission()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//: **Follow these steps:**
//: - Add a uv center atan generator [Menu - Generator - UV Center Atan (atan(uv-vec2(0.5)))]
//: - Add a audio db generator [Menu - Generator - Audio DB (float u_audiodb)]
//: - Add a disc ray consumer [Menu - Consumer - Float Disc Ray]
//: - Add a disc ray consumer [Menu - Consumer - Float Disc Ray] and connect audio db node to its fill rate knot
//: - Add a circle outline consumer [Menu - Consumer - Float Circle Outline]
//: - Add several float generator nodes, either a float value node [Menu - Generator - Float Generator] or a float slider node [Menu - Generator - Float Slider], and assign them to these fields: Ray Num 1, Ray Num 2 in Disc Ray node and In Radius, Out Radius in Circle Outline node.
//:
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
FloatTimeNodeData
FloatAudioDBNodeData
FloatAtanNodeData
Vec2RulerGeneratorNodeData
FloatGeneratorNodeData
FloatSliderGeneratorNodeData
Vec2RulerGeneratorNodeData
Vec2GeneratorNodeData
FloatRayDiscNodeData
FloatCircleOutlineNodeData
FloatCircleNodeData
Vec2ChannelCombineNodeData
FloatAddNodeData
FloatAddWithValueNodeData
FloatMinusNodeData
FloatMultiplyNodeData
FloatMultiplyWithValueNodeData
FloatAtanNodeData
Vec2AddNodeData
FloatSmoothStepNodeData
Vec2MinusNodeData
Vec2TexCoordNodeData
FloatAddNodeData
Vec2ChannelSplitNodeData
FloatSinNodeData
Vec2GeneratorNodeData
Vec2LengthNodeData
FloatMinusNodeData
Vec2ChannelCombineNodeData
Vec2ChannelSplitNodeData
Vec4ChannelCombineNodeData
FloatSmoothStepWithRangeNodeData
FloatMultiplyWithValueNodeData
FloatAddWithValueNodeData
FloatStepNodeData
FloatMultiplyNodeData
FloatRayDiscNodeData
FloatCircleOutlineNodeData
Vec2MinusNodeData
FloatSmoothStepNodeData
FloatSmoothStepWithRangeNodeData
FloatSinNodeData
FloatUVCenterAtanNodeData
FloatSliderGeneratorNodeData
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//
// Binding.swift
// UserModule
//
// Created by fincher on 5/13/20.
//

import Foundation
import Combine
import UIKit
/// A custom subscription to capture UIControl target events.
final class UIControlSubscription<SubscriberType: Subscriber, Control: UIControl>: Subscription where SubscriberType.Input == Control {
private var subscriber: SubscriberType?
private let control: Control

init(subscriber: SubscriberType, control: Control, event: UIControl.Event) {
self.subscriber = subscriber
self.control = control
control.addTarget(self, action: #selector(eventHandler), for: event)
}

func request(_ demand: Subscribers.Demand) {
// We do nothing here as we only want to send events when they occur.
// See, for more info: https://developer.apple.com/documentation/combine/subscribers/demand
}

func cancel() {
subscriber = nil
}

@objc private func eventHandler() {
_ = subscriber?.receive(control)
}
}

struct UIControlPublisher<Control: UIControl>: Publisher {

typealias Output = Control
typealias Failure = Never

let control: Control
let controlEvents: UIControl.Event

init(control: Control, events: UIControl.Event) {
self.control = control
self.controlEvents = events
}

func receive<S>(subscriber: S) where S : Subscriber, S.Failure == UIControlPublisher.Failure, S.Input == UIControlPublisher.Output {
let subscription = UIControlSubscription(subscriber: subscriber, control: control, event: controlEvents)
subscriber.receive(subscription: subscription)
}
}

protocol CombineCompatible { }
extension UIControl: CombineCompatible { }
extension CombineCompatible where Self: UIControl {
func publisher(for events: UIControl.Event) -> UIControlPublisher<UIControl> {
return UIControlPublisher(control: self, events: events)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public extension CGPoint
return CGPoint.init(x: self.x + x, y: self.y + y)
}
}

public extension NSObject
{
class func getClassHierarchy() -> [AnyClass] {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import UIKit
import Combine

@objc(FloatSliderGeneratorNodeData) public class FloatSliderGeneratorNodeData: NodeData
{
var value : Dynamic<Float> = Dynamic<Float>(0)
var valueSub : AnyCancellable?

override class var defaultTitle: String { return "Float Slider (float a)" }
override class var customViewHeight: CGFloat { return 60 }
Expand Down Expand Up @@ -47,19 +49,21 @@ import UIKit
slider.minimumValueImage = UIImage.init(systemName: "0.square")
slider.isContinuous = true
slider.tintColor = UIColor.secondarySystemFill
slider.addTarget(self, action: #selector(sliderValueChanged(sender:)), for: .touchUpOutside)
slider.addTarget(self, action: #selector(sliderValueChanged(sender:)), for: .touchUpInside)
slider.value = value.value

valueSub = slider.publisher(for: .valueChanged)
.map { ($0 as! UISlider).value }
.debounce(for: .milliseconds(100), scheduler: RunLoop.main)
.receive(on: RunLoop.main)
.sink { (f) in
self.value.value = f
}

value.bind { (newValue) in
NotificationCenter.default.post(name: NSNotification.Name( Constant.notificationNameShaderModified), object: nil)
}
}

@objc func sliderValueChanged(sender: UISlider){
value.value = sender.value
}

override class func nodeType() -> NodeType
{
return NodeType.Generator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ public class NodeListTableViewController: UIViewController, UIPopoverPresentatio
let data : Array<NodeData.Type> = NodeInfoCacheManager.shared.getNodeClasses()

tableViewDataSource = Dictionary(grouping: data, by: { nodeData in nodeData.nodeType() })
tableViewSectionDataSource = Array(tableViewDataSource.keys)
tableViewSectionDataSource = Array(tableViewDataSource.keys).sorted(by: { (a, b) -> Bool in
return a.rawValue < b.rawValue
})

tableView.reloadData()
}
Expand Down
4 changes: 4 additions & 0 deletions PlaygroundBook.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
0D5F84E8246B66A900050D49 /* FloatUVCenterAtanNodeData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D5F84E7246B66A800050D49 /* FloatUVCenterAtanNodeData.swift */; };
0D5F84EB246B683B00050D49 /* FloatSliderGeneratorNodeData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0D5F84EA246B683B00050D49 /* FloatSliderGeneratorNodeData.swift */; };
0D5F84ED246B703500050D49 /* AudioShader.jpg in Resources */ = {isa = PBXBuildFile; fileRef = 0D5F84EC246B703500050D49 /* AudioShader.jpg */; };
0DB9E24C246BBD4100897A36 /* Binding.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0DB9E24B246BBD4100897A36 /* Binding.swift */; };
5E086DD32051E3A3004D8D25 /* Manifest.plist in Copy Book Contents */ = {isa = PBXBuildFile; fileRef = 5E086DCF2051DF0F004D8D25 /* Manifest.plist */; };
5E551EC52371FC3F00784365 /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 5E551EC42371FC3F00784365 /* Assets.xcassets */; };
5E6F7E592367B529008CC191 /* UserModules in Copy Book Contents */ = {isa = PBXBuildFile; fileRef = 5E6F7E582367B51E008CC191 /* UserModules */; };
Expand Down Expand Up @@ -216,6 +217,7 @@
0D5F84E7246B66A800050D49 /* FloatUVCenterAtanNodeData.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = FloatUVCenterAtanNodeData.swift; sourceTree = "<group>"; };
0D5F84EA246B683B00050D49 /* FloatSliderGeneratorNodeData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = FloatSliderGeneratorNodeData.swift; sourceTree = "<group>"; };
0D5F84EC246B703500050D49 /* AudioShader.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; path = AudioShader.jpg; sourceTree = "<group>"; };
0DB9E24B246BBD4100897A36 /* Binding.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Binding.swift; sourceTree = "<group>"; };
5E086DC02051C5A7004D8D25 /* ShaderNodeEditor.playgroundbook */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = ShaderNodeEditor.playgroundbook; sourceTree = BUILT_PRODUCTS_DIR; };
5E086DC72051DD03004D8D25 /* BookOverridingBuildSettings.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = BookOverridingBuildSettings.xcconfig; sourceTree = "<group>"; };
5E086DCF2051DF0F004D8D25 /* Manifest.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Manifest.plist; sourceTree = "<group>"; };
Expand Down Expand Up @@ -368,6 +370,7 @@
0D5F84E7246B66A800050D49 /* FloatUVCenterAtanNodeData.swift */,
0D18D793246723DA000B0EBD /* Constant.swift */,
0D18D794246723DA000B0EBD /* Dynamic.swift */,
0DB9E24B246BBD4100897A36 /* Binding.swift */,
0D18D795246723DA000B0EBD /* Extensions.swift */,
0D0A359A246869E500585F70 /* Helper.swift */,
0D18D7CC246723DB000B0EBD /* AudioUniformProviderManager.swift */,
Expand Down Expand Up @@ -689,6 +692,7 @@
0D5F84E1246B662600050D49 /* NodePortKnotView.swift in Sources */,
0D5F84E2246B662600050D49 /* NodePortView.swift in Sources */,
0D5F84E3246B662600050D49 /* NodeValueCustomView.swift in Sources */,
0DB9E24C246BBD4100897A36 /* Binding.swift in Sources */,
0D5F84E4246B662600050D49 /* NodeView.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import SwiftUI
import UserModule

final class ContentViewStore: ObservableObject {
var audioPermissionEnabled = AudioUniformProviderManager.shared.hasRecordPermission() {
@Published var audioPermissionEnabled = AudioUniformProviderManager.shared.hasRecordPermission() {
didSet {
if audioPermissionEnabled {
AudioUniformProviderManager.shared.requestPermission()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
//: **Follow these steps:**
//: - Add a uv center atan generator [Menu - Generator - UV Center Atan (atan(uv-vec2(0.5)))]
//: - Add a audio db generator [Menu - Generator - Audio DB (float u_audiodb)]
//: - Add a disc ray consumer [Menu - Consumer - Float Disc Ray]
//: - Add a disc ray consumer [Menu - Consumer - Float Disc Ray] and connect audio db node to its fill rate knot
//: - Add a circle outline consumer [Menu - Consumer - Float Circle Outline]
//: - Add several float generator nodes, either a float value node [Menu - Generator - Float Generator] or a float slider node [Menu - Generator - Float Slider], and assign them to these fields: Ray Num 1, Ray Num 2 in Disc Ray node and In Radius, Out Radius in Circle Outline node.
//:
Expand Down
Binary file modified PlaygroundBook/PrivateResources/AudioShader.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
34 changes: 17 additions & 17 deletions PlaygroundBook/PrivateResources/NodeList.txt
Original file line number Diff line number Diff line change
@@ -1,27 +1,27 @@
FloatTimeNodeData
FloatAudioDBNodeData
FloatAtanNodeData
Vec2RulerGeneratorNodeData
FloatGeneratorNodeData
FloatSliderGeneratorNodeData
Vec2RulerGeneratorNodeData
Vec2GeneratorNodeData
FloatRayDiscNodeData
FloatCircleOutlineNodeData
FloatCircleNodeData
Vec2ChannelCombineNodeData
FloatAddNodeData
FloatAddWithValueNodeData
FloatMinusNodeData
FloatMultiplyNodeData
FloatMultiplyWithValueNodeData
FloatAtanNodeData
Vec2AddNodeData
FloatSmoothStepNodeData
Vec2MinusNodeData
Vec2TexCoordNodeData
FloatAddNodeData
Vec2ChannelSplitNodeData
FloatSinNodeData
Vec2GeneratorNodeData
Vec2LengthNodeData
FloatMinusNodeData
Vec2ChannelCombineNodeData
Vec2ChannelSplitNodeData
Vec4ChannelCombineNodeData
FloatSmoothStepWithRangeNodeData
FloatMultiplyWithValueNodeData
FloatAddWithValueNodeData
FloatStepNodeData
FloatMultiplyNodeData
FloatRayDiscNodeData
FloatCircleOutlineNodeData
Vec2MinusNodeData
FloatSmoothStepNodeData
FloatSmoothStepWithRangeNodeData
FloatSinNodeData
FloatUVCenterAtanNodeData
FloatSliderGeneratorNodeData
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
//
// Binding.swift
// UserModule
//
// Created by fincher on 5/13/20.
//

import Foundation
import Combine
import UIKit
/// A custom subscription to capture UIControl target events.
final class UIControlSubscription<SubscriberType: Subscriber, Control: UIControl>: Subscription where SubscriberType.Input == Control {
private var subscriber: SubscriberType?
private let control: Control

init(subscriber: SubscriberType, control: Control, event: UIControl.Event) {
self.subscriber = subscriber
self.control = control
control.addTarget(self, action: #selector(eventHandler), for: event)
}

func request(_ demand: Subscribers.Demand) {
// We do nothing here as we only want to send events when they occur.
// See, for more info: https://developer.apple.com/documentation/combine/subscribers/demand
}

func cancel() {
subscriber = nil
}

@objc private func eventHandler() {
_ = subscriber?.receive(control)
}
}

struct UIControlPublisher<Control: UIControl>: Publisher {

typealias Output = Control
typealias Failure = Never

let control: Control
let controlEvents: UIControl.Event

init(control: Control, events: UIControl.Event) {
self.control = control
self.controlEvents = events
}

func receive<S>(subscriber: S) where S : Subscriber, S.Failure == UIControlPublisher.Failure, S.Input == UIControlPublisher.Output {
let subscription = UIControlSubscription(subscriber: subscriber, control: control, event: controlEvents)
subscriber.receive(subscription: subscription)
}
}

protocol CombineCompatible { }
extension UIControl: CombineCompatible { }
extension CombineCompatible where Self: UIControl {
func publisher(for events: UIControl.Event) -> UIControlPublisher<UIControl> {
return UIControlPublisher(control: self, events: events)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ public extension CGPoint
return CGPoint.init(x: self.x + x, y: self.y + y)
}
}

public extension NSObject
{
class func getClassHierarchy() -> [AnyClass] {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import UIKit
import Combine

@objc(FloatSliderGeneratorNodeData) public class FloatSliderGeneratorNodeData: NodeData
{
var value : Dynamic<Float> = Dynamic<Float>(0)
var valueSub : AnyCancellable?

override class var defaultTitle: String { return "Float Slider (float a)" }
override class var customViewHeight: CGFloat { return 60 }
Expand Down Expand Up @@ -47,19 +49,21 @@ import UIKit
slider.minimumValueImage = UIImage.init(systemName: "0.square")
slider.isContinuous = true
slider.tintColor = UIColor.secondarySystemFill
slider.addTarget(self, action: #selector(sliderValueChanged(sender:)), for: .touchUpOutside)
slider.addTarget(self, action: #selector(sliderValueChanged(sender:)), for: .touchUpInside)
slider.value = value.value

valueSub = slider.publisher(for: .valueChanged)
.map { ($0 as! UISlider).value }
.debounce(for: .milliseconds(100), scheduler: RunLoop.main)
.receive(on: RunLoop.main)
.sink { (f) in
self.value.value = f
}

value.bind { (newValue) in
NotificationCenter.default.post(name: NSNotification.Name( Constant.notificationNameShaderModified), object: nil)
}
}

@objc func sliderValueChanged(sender: UISlider){
value.value = sender.value
}

override class func nodeType() -> NodeType
{
return NodeType.Generator
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ public class NodeListTableViewController: UIViewController, UIPopoverPresentatio
let data : Array<NodeData.Type> = NodeInfoCacheManager.shared.getNodeClasses()

tableViewDataSource = Dictionary(grouping: data, by: { nodeData in nodeData.nodeType() })
tableViewSectionDataSource = Array(tableViewDataSource.keys)
tableViewSectionDataSource = Array(tableViewDataSource.keys).sorted(by: { (a, b) -> Bool in
return a.rawValue < b.rawValue
})

tableView.reloadData()
}
Expand Down

0 comments on commit 6fec818

Please sign in to comment.