<commit_before>package main

import ("pnmmodules")

func main() {
    var pixels[][] int
    var xmin, xmax, ymin, ymax, rmax, x0, y0, x, y, xt float64
    var xres, yres, max_iter, iter, px, py int

    xmax = 2.0
    xmin = -2.0

    ymax = 2.0
    ymin = -2.0

    xres = 2048
    yres = 2048

    max_iter = 256

    rmax = 2.0

    pixels = make([][]int, xres)
    for px = 0; px < xres; px++ {
        pixels[px] = make([]int, yres)

        x0 = ((float64(px)/float64(xres)) * float64(xmax - xmin)) + xmin

        for py = 0; py < yres; py++ {
            y0 = ((float64(py)/float64(yres)) * float64(ymax - ymin)) + ymin

            iter = 0
            x = 0.0
            y = 0.0

            for (((x*x + y*y) < (rmax * rmax)) && (iter < max_iter)) {
                xt = (x*x) - (y*y) + x0
                y = 2.0 * x * y + y0
                x = xt
                iter = iter + 1
            }
            pixels[px][py] = max_iter - iter
        }

    }
    pnmmodules.Writepgm(pixels, max_iter - 1, "mandel.pgm")

}<commit_msg>Add some comments.<commit_after>// Simple mandelbrot generator in Go
// Owain Kenway

package main

import ("pnmmodules")

func main() {
    var pixels[][] int
    var xmin, xmax, ymin, ymax, rmax, x0, y0, x, y, xt float64
    var xres, yres, max_iter, iter, px, py int

    xmax = 2.0
    xmin = -2.0

    ymax = 2.0
    ymin = -2.0

    xres = 2048
    yres = 2048

    max_iter = 256

    rmax = 2.0

// Allocate slice of slices.
// A 2D slice is a slice of slices.
    pixels = make([][]int, xres)
    for px = 0; px < xres; px++ {

// Allocate slice in slice of slices
        pixels[px] = make([]int, yres)

        x0 = ((float64(px)/float64(xres)) * float64(xmax - xmin)) + xmin

        for py = 0; py < yres; py++ {
            y0 = ((float64(py)/float64(yres)) * float64(ymax - ymin)) + ymin

            iter = 0
            x = 0.0
            y = 0.0

            for (((x*x + y*y) < (rmax * rmax)) && (iter < max_iter)) {
                xt = (x*x) - (y*y) + x0
                y = 2.0 * x * y + y0
                x = xt
                iter = iter + 1
            }
            pixels[px][py] = max_iter - iter
        }

    }

// Call our Writepgm routine from pgmmodules.
    pnmmodules.Writepgm(pixels, max_iter - 1, "mandel.pgm")

}<|endoftext|>


<commit_before>// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file implements LinkifyText which introduces
// links for identifiers pointing to their declarations.
// The approach does not cover all cases because godoc
// doesn't have complete type information, but it's
// reasonably good for browsing.

package godoc

import (
	"fmt"
	"go/ast"
	"go/token"
	"io"
	"strconv"
)

// LinkifyText HTML-escapes source text and writes it to w.
// Identifiers that are in a "use" position (i.e., that are
// not being declared), are wrapped with HTML links pointing
// to the respective declaration, if possible. Comments are
// formatted the same way as with FormatText.
//
func LinkifyText(w io.Writer, text []byte, n ast.Node) {
	links := linksFor(n)

	i := 0     // links index
	prev := "" // prev HTML tag
	linkWriter := func(w io.Writer, _ int, start bool) {
		// end tag
		if !start {
			if prev != "" {
				fmt.Fprintf(w, `</%s>`, prev)
				prev = ""
			}
			return
		}

		// start tag
		prev = ""
		if i < len(links) {
			switch info := links[i]; {
			case info.path != "" && info.name == "":
				// package path
				fmt.Fprintf(w, `<a href="/pkg/%s/">`, info.path)
				prev = "a"
			case info.path != "" && info.name != "":
				// qualified identifier
				fmt.Fprintf(w, `<a href="/pkg/%s/#%s">`, info.path, info.name)
				prev = "a"
			case info.path == "" && info.name != "":
				// local identifier
				if info.isVal {
					fmt.Fprintf(w, `<span id="%s">`, info.name)
					prev = "span"
				} else if ast.IsExported(info.name) {
					fmt.Fprintf(w, `<a href="#%s">`, info.name)
					prev = "a"
				}
			}
			i++
		}
	}

	idents := tokenSelection(text, token.IDENT)
	comments := tokenSelection(text, token.COMMENT)
	FormatSelections(w, text, linkWriter, idents, selectionTag, comments)
}

// A link describes the (HTML) link information for an identifier.
// The zero value of a link represents "no link".
//
type link struct {
	path, name string // package path, identifier name
	isVal      bool   // identifier is defined in a const or var declaration
}

// linksFor returns the list of links for the identifiers used
// by node in the same order as they appear in the source.
//
func linksFor(node ast.Node) (links []link) {
	// linkMap tracks link information for each ast.Ident node. Entries may
	// be created out of source order (for example, when we visit a parent
	// definition node). These links are appended to the returned slice when
	// their ast.Ident nodes are visited.
	linkMap := make(map[*ast.Ident]link)

	ast.Inspect(node, func(node ast.Node) bool {
		switch n := node.(type) {
		case *ast.Field:
			for _, n := range n.Names {
				linkMap[n] = link{}
			}
		case *ast.ImportSpec:
			if name := n.Name; name != nil {
				linkMap[name] = link{}
			}
		case *ast.ValueSpec:
			for _, n := range n.Names {
				linkMap[n] = link{name: n.Name, isVal: true}
			}
		case *ast.FuncDecl:
			linkMap[n.Name] = link{}
		case *ast.TypeSpec:
			linkMap[n.Name] = link{}
		case *ast.AssignStmt:
			// Short variable declarations only show up if we apply
			// this code to all source code (as opposed to exported
			// declarations only).
			if n.Tok == token.DEFINE {
				// Some of the lhs variables may be re-declared,
				// so technically they are not defs. We don't
				// care for now.
				for _, x := range n.Lhs {
					// Each lhs expression should be an
					// ident, but we are conservative and check.
					if n, _ := x.(*ast.Ident); n != nil {
						linkMap[n] = link{isVal: true}
					}
				}
			}
		case *ast.SelectorExpr:
			// Detect qualified identifiers of the form pkg.ident.
			// If anything fails we return true and collect individual
			// identifiers instead.
			if x, _ := n.X.(*ast.Ident); x != nil {
				// Create links only if x is a qualified identifier.
				if obj := x.Obj; obj != nil && obj.Kind == ast.Pkg {
					if spec, _ := obj.Decl.(*ast.ImportSpec); spec != nil {
						// spec.Path.Value is the import path
						if path, err := strconv.Unquote(spec.Path.Value); err == nil {
							// Register two links, one for the package
							// and one for the qualified identifier.
							linkMap[x] = link{path: path}
							linkMap[n.Sel] = link{path: path, name: n.Sel.Name}
						}
					}
				}
			}
		case *ast.CompositeLit:
			// Detect field names within composite literals. These links should
			// be prefixed by the type name.
			fieldPath := ""
			prefix := ""
			switch typ := n.Type.(type) {
			case *ast.Ident:
				prefix = typ.Name + "."
			case *ast.SelectorExpr:
				if x, _ := typ.X.(*ast.Ident); x != nil {
					// Create links only if x is a qualified identifier.
					if obj := x.Obj; obj != nil && obj.Kind == ast.Pkg {
						if spec, _ := obj.Decl.(*ast.ImportSpec); spec != nil {
							// spec.Path.Value is the import path
							if path, err := strconv.Unquote(spec.Path.Value); err == nil {
								// Register two links, one for the package
								// and one for the qualified identifier.
								linkMap[x] = link{path: path}
								linkMap[typ.Sel] = link{path: path, name: typ.Sel.Name}
								fieldPath = path
								prefix = typ.Sel.Name + "."
							}
						}
					}
				}
			}
			for _, e := range n.Elts {
				if kv, ok := e.(*ast.KeyValueExpr); ok {
					if k, ok := kv.Key.(*ast.Ident); ok {
						// Note: there is some syntactic ambiguity here. We cannot determine
						// if this is a struct literal or a map literal without type
						// information. We assume struct literal.
						name := prefix + k.Name
						linkMap[k] = link{path: fieldPath, name: name}
					}
				}
			}
		case *ast.Ident:
			if l, ok := linkMap[n]; ok {
				links = append(links, l)
			} else {
				l := link{name: n.Name}
				if n.Obj == nil && predeclared[n.Name] {
					l.path = builtinPkgPath
				}
				links = append(links, l)
			}
		}
		return true
	})
	return
}

// The predeclared map represents the set of all predeclared identifiers.
// TODO(gri) This information is also encoded in similar maps in go/doc,
//           but not exported. Consider exporting an accessor and using
//           it instead.
var predeclared = map[string]bool{
	"bool":       true,
	"byte":       true,
	"complex64":  true,
	"complex128": true,
	"error":      true,
	"float32":    true,
	"float64":    true,
	"int":        true,
	"int8":       true,
	"int16":      true,
	"int32":      true,
	"int64":      true,
	"rune":       true,
	"string":     true,
	"uint":       true,
	"uint8":      true,
	"uint16":     true,
	"uint32":     true,
	"uint64":     true,
	"uintptr":    true,
	"true":       true,
	"false":      true,
	"iota":       true,
	"nil":        true,
	"append":     true,
	"cap":        true,
	"close":      true,
	"complex":    true,
	"copy":       true,
	"delete":     true,
	"imag":       true,
	"len":        true,
	"make":       true,
	"new":        true,
	"panic":      true,
	"print":      true,
	"println":    true,
	"real":       true,
	"recover":    true,
}
<commit_msg>godoc: use "IsPredeclared" of go/doc<commit_after>// Copyright 2013 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

// This file implements LinkifyText which introduces
// links for identifiers pointing to their declarations.
// The approach does not cover all cases because godoc
// doesn't have complete type information, but it's
// reasonably good for browsing.

package godoc

import (
	"fmt"
	"go/ast"
	"go/doc"
	"go/token"
	"io"
	"strconv"
)

// LinkifyText HTML-escapes source text and writes it to w.
// Identifiers that are in a "use" position (i.e., that are
// not being declared), are wrapped with HTML links pointing
// to the respective declaration, if possible. Comments are
// formatted the same way as with FormatText.
//
func LinkifyText(w io.Writer, text []byte, n ast.Node) {
	links := linksFor(n)

	i := 0     // links index
	prev := "" // prev HTML tag
	linkWriter := func(w io.Writer, _ int, start bool) {
		// end tag
		if !start {
			if prev != "" {
				fmt.Fprintf(w, `</%s>`, prev)
				prev = ""
			}
			return
		}

		// start tag
		prev = ""
		if i < len(links) {
			switch info := links[i]; {
			case info.path != "" && info.name == "":
				// package path
				fmt.Fprintf(w, `<a href="/pkg/%s/">`, info.path)
				prev = "a"
			case info.path != "" && info.name != "":
				// qualified identifier
				fmt.Fprintf(w, `<a href="/pkg/%s/#%s">`, info.path, info.name)
				prev = "a"
			case info.path == "" && info.name != "":
				// local identifier
				if info.isVal {
					fmt.Fprintf(w, `<span id="%s">`, info.name)
					prev = "span"
				} else if ast.IsExported(info.name) {
					fmt.Fprintf(w, `<a href="#%s">`, info.name)
					prev = "a"
				}
			}
			i++
		}
	}

	idents := tokenSelection(text, token.IDENT)
	comments := tokenSelection(text, token.COMMENT)
	FormatSelections(w, text, linkWriter, idents, selectionTag, comments)
}

// A link describes the (HTML) link information for an identifier.
// The zero value of a link represents "no link".
//
type link struct {
	path, name string // package path, identifier name
	isVal      bool   // identifier is defined in a const or var declaration
}

// linksFor returns the list of links for the identifiers used
// by node in the same order as they appear in the source.
//
func linksFor(node ast.Node) (links []link) {
	// linkMap tracks link information for each ast.Ident node. Entries may
	// be created out of source order (for example, when we visit a parent
	// definition node). These links are appended to the returned slice when
	// their ast.Ident nodes are visited.
	linkMap := make(map[*ast.Ident]link)

	ast.Inspect(node, func(node ast.Node) bool {
		switch n := node.(type) {
		case *ast.Field:
			for _, n := range n.Names {
				linkMap[n] = link{}
			}
		case *ast.ImportSpec:
			if name := n.Name; name != nil {
				linkMap[name] = link{}
			}
		case *ast.ValueSpec:
			for _, n := range n.Names {
				linkMap[n] = link{name: n.Name, isVal: true}
			}
		case *ast.FuncDecl:
			linkMap[n.Name] = link{}
		case *ast.TypeSpec:
			linkMap[n.Name] = link{}
		case *ast.AssignStmt:
			// Short variable declarations only show up if we apply
			// this code to all source code (as opposed to exported
			// declarations only).
			if n.Tok == token.DEFINE {
				// Some of the lhs variables may be re-declared,
				// so technically they are not defs. We don't
				// care for now.
				for _, x := range n.Lhs {
					// Each lhs expression should be an
					// ident, but we are conservative and check.
					if n, _ := x.(*ast.Ident); n != nil {
						linkMap[n] = link{isVal: true}
					}
				}
			}
		case *ast.SelectorExpr:
			// Detect qualified identifiers of the form pkg.ident.
			// If anything fails we return true and collect individual
			// identifiers instead.
			if x, _ := n.X.(*ast.Ident); x != nil {
				// Create links only if x is a qualified identifier.
				if obj := x.Obj; obj != nil && obj.Kind == ast.Pkg {
					if spec, _ := obj.Decl.(*ast.ImportSpec); spec != nil {
						// spec.Path.Value is the import path
						if path, err := strconv.Unquote(spec.Path.Value); err == nil {
							// Register two links, one for the package
							// and one for the qualified identifier.
							linkMap[x] = link{path: path}
							linkMap[n.Sel] = link{path: path, name: n.Sel.Name}
						}
					}
				}
			}
		case *ast.CompositeLit:
			// Detect field names within composite literals. These links should
			// be prefixed by the type name.
			fieldPath := ""
			prefix := ""
			switch typ := n.Type.(type) {
			case *ast.Ident:
				prefix = typ.Name + "."
			case *ast.SelectorExpr:
				if x, _ := typ.X.(*ast.Ident); x != nil {
					// Create links only if x is a qualified identifier.
					if obj := x.Obj; obj != nil && obj.Kind == ast.Pkg {
						if spec, _ := obj.Decl.(*ast.ImportSpec); spec != nil {
							// spec.Path.Value is the import path
							if path, err := strconv.Unquote(spec.Path.Value); err == nil {
								// Register two links, one for the package
								// and one for the qualified identifier.
								linkMap[x] = link{path: path}
								linkMap[typ.Sel] = link{path: path, name: typ.Sel.Name}
								fieldPath = path
								prefix = typ.Sel.Name + "."
							}
						}
					}
				}
			}
			for _, e := range n.Elts {
				if kv, ok := e.(*ast.KeyValueExpr); ok {
					if k, ok := kv.Key.(*ast.Ident); ok {
						// Note: there is some syntactic ambiguity here. We cannot determine
						// if this is a struct literal or a map literal without type
						// information. We assume struct literal.
						name := prefix + k.Name
						linkMap[k] = link{path: fieldPath, name: name}
					}
				}
			}
		case *ast.Ident:
			if l, ok := linkMap[n]; ok {
				links = append(links, l)
			} else {
				l := link{name: n.Name}
				if n.Obj == nil && doc.IsPredeclared(n.Name) {
					l.path = builtinPkgPath
				}
				links = append(links, l)
			}
		}
		return true
	})
	return
}
<|endoftext|>


<commit_before>package godot

/*
#include <stdio.h>
#include <stdlib.h>
#include <godot/gdnative.h>
#include <godot_nativescript.h>
*/
import "C"

// Duplication of enumerated constants from godot.
type Vec3Axis int

const (
	VECTOR3_AXIS_X = iota // 0
	VECTOR3_AXIS_Y        // 1
	VECTOR3_AXIS_Z        // 2
)

// NewVector3 constructs a new Vector3 from the given x and y.
func NewVector3(x float64, y float64, z float64) *Vector3 {
	vector3 := &Vector3{}

	// Create our godot vector3 object
	var godotVector3 C.godot_vector3

	// Create our vector3
	C.godot_vector3_new(
		&godotVector3,
		realAsGodotReal(x),
		realAsGodotReal(y),
		realAsGodotReal(z),
	)

	// Internally set our vector3
	vector3.vector3 = &godotVector3

	return vector3
}

type Vector3 struct {
	vector3 *C.godot_vector3
}

func (v *Vector3) Abs() *Vector3 {
	return godotVec3AsVec3(C.godot_vector3_abs(v.vector3))
}

// AngleTo returns the angle in radians between the two vectors.
func (v *Vector3) AngleTo(to Vector3) float64 {
	angleTo := C.godot_vector3_angle_to(v.vector3, to.vector3)
	return godotRealAsReal(angleTo)
}

// AsString returns a string.
func (v *Vector3) AsString() string {
	asString := C.godot_vector3_as_string(v.vector3)
	return godotStringAsString(&asString)
}

// Bounce is not documented in the godot library yet.
func (v *Vector3) Bounce(with Vector3) *Vector3 {
	return godotVec3AsVec3(C.godot_vector3_bounce(v.vector3, with.vector3))
}

// Ceil returns a new vector with all components rounded up.
func (v *Vector3) Ceil() *Vector3 {
	return godotVec3AsVec3(C.godot_vector3_ceil(v.vector3))
}

// Cross returns the cross product with b.
func (v *Vector3) Cross(b Vector3) *Vector3 {
	return godotVec3AsVec3(C.godot_vector3_cross(v.vector3, b.vector3))
}

// CubicInterpolate Cubicly interpolates between this Vector and “b”, using “pre_a”
// and “post_b” as handles, and returning the result at position “t”.
func (v *Vector3) CubicInterpolate(b Vector3, preA Vector3, postB Vector3, t float64) *Vector3 {
	return godotVec3AsVec3(C.godot_vector3_cubic_interpolate(
		v.vector3,
		b.vector3,
		preA.vector3,
		postB.vector3,
		realAsGodotReal(t),
	),
	)
}

// DistanceSquaredTo returns the squared distance to vector “b”. Prefer this
// function over “distance_to” if you need to sort vectors or need the squared
// distance for some formula.
func (v *Vector3) DistanceSquaredTo(to Vector3) float64 {
	distSqrTo := C.godot_vector3_distance_squared_to(v.vector3, to.vector3)
	return godotRealAsReal(distSqrTo)
}

// DistanceTo returns the distance to vector “b”.
func (v *Vector3) DistanceTo(to Vector3) float64 {
	distTo := C.godot_vector3_distance_to(v.vector3, to.vector3)
	return godotRealAsReal(distTo)
}

// Dot returns the dot product with vector “b”.
func (v *Vector3) Dot(with Vector3) float64 {
	dot := C.godot_vector3_dot(v.vector3, with.vector3)
	return godotRealAsReal(dot)
}

// Floor removes the fractional part of x and y.
func (v *Vector3) Floor() *Vector3 {
	return godotVec3AsVec3(C.godot_vector3_floor(v.vector3))
}

// GetAxis returns the value of the supplied axis
func (v *Vector3) GetAxis(axis Vec3Axis) float64 {
	return godotRealAsReal(
		C.godot_vector3_get_axis(
			v.vector3,
			vec3AxisAsGodotVec3Axis(axis),
		),
	)
}

// Inverse returns the inverse of the vector. This is the same as i
// Vector3( 1.0 / x, 1.0 / y, 1.0 / z )
func (v *Vector3) Inverse() *Vector3 {
	return godotVec3AsVec3(C.godot_vector3_inverse(v.vector3))
}

// IsNormalized
func (v *Vector3) IsNormalized() bool {
	isNormalized := C.godot_vector3_is_normalized(v.vector3)
	return godotBoolAsBool(isNormalized)
}

// Length returns the length of the vector.
func (v *Vector3) Length() float64 {
	return godotRealAsReal(C.godot_vector3_length(v.vector3))
}

// LengthSquared returns the squared length of the vector. Prefer this function
// over “length” if you need to sort vectors or need the squared length for some formula.
func (v *Vector3) LengthSquared() float64 {
	return godotRealAsReal(C.godot_vector3_length_squared(v.vector3))
}

// LinearInterpolate returns the result of the linear interpolation between this
// vector and “b”, by amount “t”.
func (v *Vector3) LinearInterpolate(b Vector3, t float64) *Vector3 {
	return godotVec3AsVec3(C.godot_vector3_linear_interpolate(
		v.vector3,
		b.vector3,
		realAsGodotReal(t),
	),
	)
}

// MaxAxis returns VECTOR3_AXIS_X, VECTOR3_AXIS_Y or VECTOR3_AXIS_Z depending on
// which axis is the largest.
func (v *Vector3) MaxAxis() int {
	return godotIntAsInt(C.godot_vector3_max_axis(v.vector3))
}

// MinAxis returns VECTOR3_AXIS_X, VECTOR3_AXIS_Y or VECTOR3_AXIS_Z depending on
// which axis is the smallest.
func (v *Vector3) MinAxis() int {
	return godotIntAsInt(C.godot_vector3_min_axis(v.vector3))
}

// Normalized returns a normalized vector to unit length.
func (v *Vector3) Normalized() *Vector3 {
	return godotVec3AsVec3(C.godot_vector3_normalized(v.vector3))
}

// OperatorAdd adds the current vector and with.
func (v *Vector3) OperatorAdd(with Vector3) *Vector3 {
	return godotVec3AsVec3(C.godot_vector3_operator_add(v.vector3, with.vector3))
}

// OperatorDivideScalar divides the current vector by with.
func (v *Vector3) OperatorDivideScalar(with float64) *Vector3 {
	return godotVec3AsVec3(
		C.godot_vector3_operator_divide_scalar(
			v.vector3,
			realAsGodotReal(with),
		),
	)
}

// OperatorDivideVector multiplys the current vector and with.
func (v *Vector3) OperatorDivideVector(with Vector3) *Vector3 {
	return godotVec3AsVec3(
		C.godot_vector3_operator_divide_vector(
			v.vector3,
			with.vector3,
		),
	)
}

// OperatorEqual compares the current vector and with. Returns true if equal
func (v *Vector3) OperatorEqual(with Vector3) bool {
	operatorEqual := C.godot_vector3_operator_equal(v.vector3, with.vector3)
	return godotBoolAsBool(operatorEqual)
}

// OperatorLess compares the current vector and with. Returns true if v.vector3 < with.vector
func (v *Vector3) OperatorLess(with Vector3) bool {
	operatorEqual := C.godot_vector3_operator_less(v.vector3, with.vector3)
	return godotBoolAsBool(operatorEqual)
}

// OperatorMultiplyScalar multiplys the current vector by with.
func (v *Vector3) OperatorMultiplyScalar(with float64) *Vector3 {
	return godotVec3AsVec3(
		C.godot_vector3_operator_multiply_scalar(
			v.vector3,
			realAsGodotReal(with),
		),
	)
}

// OperatorMultiplyVector multiplys the current vector and with.
func (v *Vector3) OperatorMultiplyVector(with Vector3) *Vector3 {
	return godotVec3AsVec3(
		C.godot_vector3_operator_multiply_vector(
			v.vector3,
			with.vector3,
		),
	)
}

// OperatorNeg returns -v.vector3.
func (v *Vector3) OperatorNeg() *Vector3 {
	return godotVec3AsVec3(C.godot_vector3_operator_neg(v.vector3))
}

// OperatorSubtract subtracts the current vector and with.
func (v *Vector3) OperatorSubtract(with Vector3) *Vector3 {
	return godotVec3AsVec3(
		C.godot_vector3_operator_substract(
			v.vector3,
			with.vector3,
		),
	)
}

// Outer
func (v *Vector3) Outer(with Vector3) *Basis {
	return godotBasisAsBasis(C.godot_vector3_outer(v.vector3, with.vector3))
}

// Reflect is like “slide”, but reflects the Vector instead of continuing along the wall.
func (v *Vector3) Reflect(vec Vector3) *Vector3 {
	return godotVec3AsVec3(C.godot_vector3_reflect(v.vector3, vec.vector3))
}

// Rotated rotates the vector by “phi” radians.
func (v *Vector3) Rotated(by Vector3, phi float64) *Vector3 {
	return godotVec3AsVec3(
		C.godot_vector3_rotated(
			v.vector3,
			by.vector3,
			realAsGodotReal(phi),
		),
	)
}

// SetAxis changes the specified axis to the specified value.
func (v *Vector3) SetAxis(axis Vec3Axis, val float64) {
	C.godot_vector3_set_axis(
		v.vector3,
		vec3AxisAsGodotVec3Axis(axis),
		realAsGodotReal(val),
	)
}

// Slide slides the vector by the other vector.
func (v *Vector3) Slide(by Vector3) *Vector3 {
	return godotVec3AsVec3(C.godot_vector3_slide(v.vector3, by.vector3))
}

// Snapped snaps the vector to a grid with the given size.
func (v *Vector3) Snapped(by Vector3) *Vector3 {
	return godotVec3AsVec3(C.godot_vector3_snapped(v.vector3, by.vector3))
}

// ToDiagonalMatrix
func (v *Vector3) ToDiagonalMatrix() *Basis {
	return godotBasisAsBasis(C.godot_vector3_to_diagonal_matrix(v.vector3))
}
<commit_msg>Additional bug in build brought on by fix from previous commit.<commit_after>package godot

/*
#include <stdio.h>
#include <stdlib.h>
#include <godot/gdnative.h>
#include <godot_nativescript.h>
*/
import "C"

// Duplication of enumerated constants from godot.
type Vec3Axis int

const (
	VECTOR3_AXIS_X = iota // 0
	VECTOR3_AXIS_Y        // 1
	VECTOR3_AXIS_Z        // 2
)

// NewVector3 constructs a new Vector3 from the given x and y.
func NewVector3(x float64, y float64, z float64) *Vector3 {
	vector3 := &Vector3{}

	// Create our godot vector3 object
	var godotVector3 C.godot_vector3

	// Create our vector3
	C.godot_vector3_new(
		&godotVector3,
		realAsGodotReal(x),
		realAsGodotReal(y),
		realAsGodotReal(z),
	)

	// Internally set our vector3
	vector3.vector3 = &godotVector3

	return vector3
}

type Vector3 struct {
	vector3 *C.godot_vector3
}

func (v *Vector3) Abs() *Vector3 {
	return godotVec3AsVec3(C.godot_vector3_abs(v.vector3))
}

// AngleTo returns the angle in radians between the two vectors.
func (v *Vector3) AngleTo(to Vector3) float64 {
	angleTo := C.godot_vector3_angle_to(v.vector3, to.vector3)
	return godotRealAsReal(angleTo)
}

// AsString returns a string.
func (v *Vector3) AsString() string {
	asString := C.godot_vector3_as_string(v.vector3)
	return godotStringAsString(&asString)
}

// Bounce is not documented in the godot library yet.
func (v *Vector3) Bounce(with Vector3) *Vector3 {
	return godotVec3AsVec3(C.godot_vector3_bounce(v.vector3, with.vector3))
}

// Ceil returns a new vector with all components rounded up.
func (v *Vector3) Ceil() *Vector3 {
	return godotVec3AsVec3(C.godot_vector3_ceil(v.vector3))
}

// Cross returns the cross product with b.
func (v *Vector3) Cross(b Vector3) *Vector3 {
	return godotVec3AsVec3(C.godot_vector3_cross(v.vector3, b.vector3))
}

// CubicInterpolate Cubicly interpolates between this Vector and “b”, using “pre_a”
// and “post_b” as handles, and returning the result at position “t”.
func (v *Vector3) CubicInterpolate(b Vector3, preA Vector3, postB Vector3, t float64) *Vector3 {
	return godotVec3AsVec3(C.godot_vector3_cubic_interpolate(
		v.vector3,
		b.vector3,
		preA.vector3,
		postB.vector3,
		realAsGodotReal(t),
	),
	)
}

// DistanceSquaredTo returns the squared distance to vector “b”. Prefer this
// function over “distance_to” if you need to sort vectors or need the squared
// distance for some formula.
func (v *Vector3) DistanceSquaredTo(to Vector3) float64 {
	distSqrTo := C.godot_vector3_distance_squared_to(v.vector3, to.vector3)
	return godotRealAsReal(distSqrTo)
}

// DistanceTo returns the distance to vector “b”.
func (v *Vector3) DistanceTo(to Vector3) float64 {
	distTo := C.godot_vector3_distance_to(v.vector3, to.vector3)
	return godotRealAsReal(distTo)
}

// Dot returns the dot product with vector “b”.
func (v *Vector3) Dot(with Vector3) float64 {
	dot := C.godot_vector3_dot(v.vector3, with.vector3)
	return godotRealAsReal(dot)
}

// Floor removes the fractional part of x and y.
func (v *Vector3) Floor() *Vector3 {
	return godotVec3AsVec3(C.godot_vector3_floor(v.vector3))
}

// GetAxis returns the value of the supplied axis
func (v *Vector3) GetAxis(axis Vec3Axis) float64 {
	return godotRealAsReal(
		C.godot_vector3_get_axis(
			v.vector3,
			vec3AxisAsGodotVec3Axis(axis),
		),
	)
}

// Inverse returns the inverse of the vector. This is the same as i
// Vector3( 1.0 / x, 1.0 / y, 1.0 / z )
func (v *Vector3) Inverse() *Vector3 {
	return godotVec3AsVec3(C.godot_vector3_inverse(v.vector3))
}

// IsNormalized
func (v *Vector3) IsNormalized() bool {
	isNormalized := C.godot_vector3_is_normalized(v.vector3)
	return godotBoolAsBool(isNormalized)
}

// Length returns the length of the vector.
func (v *Vector3) Length() float64 {
	return godotRealAsReal(C.godot_vector3_length(v.vector3))
}

// LengthSquared returns the squared length of the vector. Prefer this function
// over “length” if you need to sort vectors or need the squared length for some formula.
func (v *Vector3) LengthSquared() float64 {
	return godotRealAsReal(C.godot_vector3_length_squared(v.vector3))
}

// LinearInterpolate returns the result of the linear interpolation between this
// vector and “b”, by amount “t”.
func (v *Vector3) LinearInterpolate(b Vector3, t float64) *Vector3 {
	return godotVec3AsVec3(C.godot_vector3_linear_interpolate(
		v.vector3,
		b.vector3,
		realAsGodotReal(t),
	),
	)
}

// MaxAxis returns VECTOR3_AXIS_X, VECTOR3_AXIS_Y or VECTOR3_AXIS_Z depending on
// which axis is the largest.
func (v *Vector3) MaxAxis() int64 {
	return godotIntAsInt(C.godot_vector3_max_axis(v.vector3))
}

// MinAxis returns VECTOR3_AXIS_X, VECTOR3_AXIS_Y or VECTOR3_AXIS_Z depending on
// which axis is the smallest.
func (v *Vector3) MinAxis() int64 {
	return godotIntAsInt(C.godot_vector3_min_axis(v.vector3))
}

// Normalized returns a normalized vector to unit length.
func (v *Vector3) Normalized() *Vector3 {
	return godotVec3AsVec3(C.godot_vector3_normalized(v.vector3))
}

// OperatorAdd adds the current vector and with.
func (v *Vector3) OperatorAdd(with Vector3) *Vector3 {
	return godotVec3AsVec3(C.godot_vector3_operator_add(v.vector3, with.vector3))
}

// OperatorDivideScalar divides the current vector by with.
func (v *Vector3) OperatorDivideScalar(with float64) *Vector3 {
	return godotVec3AsVec3(
		C.godot_vector3_operator_divide_scalar(
			v.vector3,
			realAsGodotReal(with),
		),
	)
}

// OperatorDivideVector multiplys the current vector and with.
func (v *Vector3) OperatorDivideVector(with Vector3) *Vector3 {
	return godotVec3AsVec3(
		C.godot_vector3_operator_divide_vector(
			v.vector3,
			with.vector3,
		),
	)
}

// OperatorEqual compares the current vector and with. Returns true if equal
func (v *Vector3) OperatorEqual(with Vector3) bool {
	operatorEqual := C.godot_vector3_operator_equal(v.vector3, with.vector3)
	return godotBoolAsBool(operatorEqual)
}

// OperatorLess compares the current vector and with. Returns true if v.vector3 < with.vector
func (v *Vector3) OperatorLess(with Vector3) bool {
	operatorEqual := C.godot_vector3_operator_less(v.vector3, with.vector3)
	return godotBoolAsBool(operatorEqual)
}

// OperatorMultiplyScalar multiplys the current vector by with.
func (v *Vector3) OperatorMultiplyScalar(with float64) *Vector3 {
	return godotVec3AsVec3(
		C.godot_vector3_operator_multiply_scalar(
			v.vector3,
			realAsGodotReal(with),
		),
	)
}

// OperatorMultiplyVector multiplys the current vector and with.
func (v *Vector3) OperatorMultiplyVector(with Vector3) *Vector3 {
	return godotVec3AsVec3(
		C.godot_vector3_operator_multiply_vector(
			v.vector3,
			with.vector3,
		),
	)
}

// OperatorNeg returns -v.vector3.
func (v *Vector3) OperatorNeg() *Vector3 {
	return godotVec3AsVec3(C.godot_vector3_operator_neg(v.vector3))
}

// OperatorSubtract subtracts the current vector and with.
func (v *Vector3) OperatorSubtract(with Vector3) *Vector3 {
	return godotVec3AsVec3(
		C.godot_vector3_operator_substract(
			v.vector3,
			with.vector3,
		),
	)
}

// Outer
func (v *Vector3) Outer(with Vector3) *Basis {
	return godotBasisAsBasis(C.godot_vector3_outer(v.vector3, with.vector3))
}

// Reflect is like “slide”, but reflects the Vector instead of continuing along the wall.
func (v *Vector3) Reflect(vec Vector3) *Vector3 {
	return godotVec3AsVec3(C.godot_vector3_reflect(v.vector3, vec.vector3))
}

// Rotated rotates the vector by “phi” radians.
func (v *Vector3) Rotated(by Vector3, phi float64) *Vector3 {
	return godotVec3AsVec3(
		C.godot_vector3_rotated(
			v.vector3,
			by.vector3,
			realAsGodotReal(phi),
		),
	)
}

// SetAxis changes the specified axis to the specified value.
func (v *Vector3) SetAxis(axis Vec3Axis, val float64) {
	C.godot_vector3_set_axis(
		v.vector3,
		vec3AxisAsGodotVec3Axis(axis),
		realAsGodotReal(val),
	)
}

// Slide slides the vector by the other vector.
func (v *Vector3) Slide(by Vector3) *Vector3 {
	return godotVec3AsVec3(C.godot_vector3_slide(v.vector3, by.vector3))
}

// Snapped snaps the vector to a grid with the given size.
func (v *Vector3) Snapped(by Vector3) *Vector3 {
	return godotVec3AsVec3(C.godot_vector3_snapped(v.vector3, by.vector3))
}

// ToDiagonalMatrix
func (v *Vector3) ToDiagonalMatrix() *Basis {
	return godotBasisAsBasis(C.godot_vector3_to_diagonal_matrix(v.vector3))
}
<|endoftext|>


<commit_before>package grafana

/*
 Copyleft 2016 Alexander I.Grafov <grafov@gmail.com>

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program 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 General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.

 ॐ तारे तुत्तारे तुरे स्व
*/

import (
	"bytes"
	"encoding/json"
	"strings"

	"github.com/gosimple/slug"
)

var (
	boardID uint
)

type (
	// Board represents Grafana dashboard.
	Board struct {
		ID              uint     `json:"id"`
		Slug            string   `json:"-"`
		Title           string   `json:"title"`
		OriginalTitle   string   `json:"originalTitle"`
		Tags            []string `json:"tags"`
		Style           string   `json:"style"`
		Timezone        string   `json:"timezone"`
		Editable        bool     `json:"editable"`
		HideControls    bool     `json:"hideControls" graf:"hide-controls"`
		SharedCrosshair bool     `json:"sharedCrosshair" graf:"shared-crosshair"`
		Rows            []*Row   `json:"rows"`
		Templating      struct {
			List []templateVar `json:"list"`
		} `json:"templating"`
		Annotations struct {
			List []annotation `json:"list"`
		} `json:"annotations"`
		Refresh       *BoolString `json:"refresh,omitempty"`
		SchemaVersion uint        `json:"schemiaVersion"`
		Version       uint        `json:"version"`
		Links         []link      `json:"links"`
		Time          struct {
			From string `json:"from"`
			To   string `json:"to"`
		} `json:"time"`
		Timepicker struct {
			Now              *bool    `json:"now,omitempty"`
			RefreshIntervals []string `json:"refresh_intervals"`
			TimeOptions      []string `json:"time_options"`
		} `json:"timepicker"`
		lastPanelID uint
	}
	templateVar struct {
		Name        string   `json:"name"`
		Type        string   `json:"type"`
		AutoCount   *int     `json:"auto_count,omitempty"`
		Datasource  *string  `json:"datasource"`
		Refresh     bool     `json:"refresh"`
		Options     []option `json:"options"`
		IncludeAll  bool     `json:"includeAll"`
		AllFormat   string   `json:"allFormat"`
		Multi       bool     `json:"multi"`
		MultiFormat string   `json:"multiFormat"`
		Query       string   `json:"query"`
		Current     current  `json:"current"`
		Label       string   `json:"label"`
	}
	// for templateVar
	option struct {
		Text     string `json:"text"`
		Value    string `json:"value"`
		Selected bool   `json:"selected"`
	}
	// for templateVar
	current struct {
		Tags  []*string   `json:"tags,omitempty"`
		Text  string      `json:"text"`
		Value interface{} `json:"value"` // TODO select more precise type
	}
	annotation struct {
		Name       string  `json:"name"`
		Datasource *string `json:"datasource"`
		ShowLine   bool    `json:"showLine"`
		IconColor  string  `json:"iconColor"`
		LineColor  string  `json:"lineColor"`
		IconSize   uint    `json:"iconSize"`
		Enable     bool    `json:"enable"`
	}
)

// link represents link to another dashboard or external weblink
type link struct {
	Title       string   `json:"title"`
	Type        string   `json:"type"`
	AsDropdown  *bool    `json:"asDropdown,omitempty"`
	DashURI     *string  `json:"dashUri,omitempty"`
	Dashboard   *string  `json:"dashboard,omitempty"`
	Icon        *string  `json:"icon,omitempty"`
	IncludeVars bool     `json:"includeVars"`
	KeepTime    *bool    `json:"keepTime,omitempty"`
	Params      *string  `json:"params,omitempty"`
	Tags        []string `json:"tags,omitempty"`
	TargetBlank *bool    `json:"targetBlank,omitempty"`
	Tooltip     *string  `json:"tooltip,omitempty"`
	URL         *string  `json:"url,omitempty"`
}

// height of rows maybe passed as number (ex 200) or
// as string (ex "200px") or empty string
type height string

func (h *height) UnmarshalJSON(raw []byte) error {
	if raw == nil || bytes.Compare(raw, []byte(`"null"`)) == 0 {
		return nil
	}
	if raw[0] != '"' {
		tmp := []byte{'"'}
		raw = append(tmp, raw...)
		raw = append(raw, byte('"'))
	}
	var tmp string
	err := json.Unmarshal(raw, &tmp)
	*h = height(tmp)
	return err
}

func NewBoard(title string) *Board {
	boardID++
	return &Board{
		ID:           boardID,
		Title:        title,
		Style:        "dark",
		Timezone:     "browser",
		Editable:     true,
		HideControls: false,
		Rows:         []*Row{}}
}

func (b *Board) RemoveTags(tags ...string) {
	tagFound := make(map[string]int, len(b.Tags))
	for i, tag := range b.Tags {
		tagFound[tag] = i
	}
	for _, removeTag := range tags {
		if i, ok := tagFound[removeTag]; ok {
			b.Tags = append(b.Tags[:i], b.Tags[i+1:]...)
		}
	}
}

func (b *Board) AddTags(tags ...string) {
	tagFound := make(map[string]bool, len(b.Tags))
	for _, tag := range b.Tags {
		tagFound[tag] = true
	}
	for _, tag := range tags {
		if tagFound[tag] {
			continue
		}
		b.Tags = append(b.Tags, tag)
	}
}

func (b *Board) HasTag(tag string) bool {
	for _, t := range b.Tags {
		if t == tag {
			return true
		}
	}
	return false
}

func (b *Board) AddRow(title string) *Row {
	if title == "" {
		title = "New row"
	}
	row := &Row{
		Title:    title,
		Collapse: false,
		Editable: true,
		Height:   "250px",
		board:    b}
	b.Rows = append(b.Rows, row)
	return row
}

func (b *Board) UpdateSlug() string {
	b.Slug = strings.ToLower(slug.Make(b.Title))
	return b.Slug
}
<commit_msg>Fix missed regex field in board type.<commit_after>package grafana

/*
 Copyleft 2016 Alexander I.Grafov <grafov@gmail.com>

 This program is free software: you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
 the Free Software Foundation, either version 3 of the License, or
 (at your option) any later version.

 This program 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 General Public License for more details.

 You should have received a copy of the GNU General Public License
 along with this program.  If not, see <http://www.gnu.org/licenses/>.

 ॐ तारे तुत्तारे तुरे स्व
*/

import (
	"bytes"
	"encoding/json"
	"strings"

	"github.com/gosimple/slug"
)

var (
	boardID uint
)

type (
	// Board represents Grafana dashboard.
	Board struct {
		ID              uint     `json:"id"`
		Slug            string   `json:"-"`
		Title           string   `json:"title"`
		OriginalTitle   string   `json:"originalTitle"`
		Tags            []string `json:"tags"`
		Style           string   `json:"style"`
		Timezone        string   `json:"timezone"`
		Editable        bool     `json:"editable"`
		HideControls    bool     `json:"hideControls" graf:"hide-controls"`
		SharedCrosshair bool     `json:"sharedCrosshair" graf:"shared-crosshair"`
		Rows            []*Row   `json:"rows"`
		Templating      struct {
			List []templateVar `json:"list"`
		} `json:"templating"`
		Annotations struct {
			List []annotation `json:"list"`
		} `json:"annotations"`
		Refresh       *BoolString `json:"refresh,omitempty"`
		SchemaVersion uint        `json:"schemiaVersion"`
		Version       uint        `json:"version"`
		Links         []link      `json:"links"`
		Time          struct {
			From string `json:"from"`
			To   string `json:"to"`
		} `json:"time"`
		Timepicker struct {
			Now              *bool    `json:"now,omitempty"`
			RefreshIntervals []string `json:"refresh_intervals"`
			TimeOptions      []string `json:"time_options"`
		} `json:"timepicker"`
		lastPanelID uint
	}
	templateVar struct {
		Name        string   `json:"name"`
		Type        string   `json:"type"`
		AutoCount   *int     `json:"auto_count,omitempty"`
		Datasource  *string  `json:"datasource"`
		Refresh     bool     `json:"refresh"`
		Options     []option `json:"options"`
		IncludeAll  bool     `json:"includeAll"`
		AllFormat   string   `json:"allFormat"`
		Multi       bool     `json:"multi"`
		MultiFormat string   `json:"multiFormat"`
		Query       string   `json:"query"`
		Regex       string   `json:"regex"`
		Current     current  `json:"current"`
		Label       string   `json:"label"`
	}
	// for templateVar
	option struct {
		Text     string `json:"text"`
		Value    string `json:"value"`
		Selected bool   `json:"selected"`
	}
	// for templateVar
	current struct {
		Tags  []*string   `json:"tags,omitempty"`
		Text  string      `json:"text"`
		Value interface{} `json:"value"` // TODO select more precise type
	}
	annotation struct {
		Name       string  `json:"name"`
		Datasource *string `json:"datasource"`
		ShowLine   bool    `json:"showLine"`
		IconColor  string  `json:"iconColor"`
		LineColor  string  `json:"lineColor"`
		IconSize   uint    `json:"iconSize"`
		Enable     bool    `json:"enable"`
	}
)

// link represents link to another dashboard or external weblink
type link struct {
	Title       string   `json:"title"`
	Type        string   `json:"type"`
	AsDropdown  *bool    `json:"asDropdown,omitempty"`
	DashURI     *string  `json:"dashUri,omitempty"`
	Dashboard   *string  `json:"dashboard,omitempty"`
	Icon        *string  `json:"icon,omitempty"`
	IncludeVars bool     `json:"includeVars"`
	KeepTime    *bool    `json:"keepTime,omitempty"`
	Params      *string  `json:"params,omitempty"`
	Tags        []string `json:"tags,omitempty"`
	TargetBlank *bool    `json:"targetBlank,omitempty"`
	Tooltip     *string  `json:"tooltip,omitempty"`
	URL         *string  `json:"url,omitempty"`
}

// height of rows maybe passed as number (ex 200) or
// as string (ex "200px") or empty string
type height string

func (h *height) UnmarshalJSON(raw []byte) error {
	if raw == nil || bytes.Compare(raw, []byte(`"null"`)) == 0 {
		return nil
	}
	if raw[0] != '"' {
		tmp := []byte{'"'}
		raw = append(tmp, raw...)
		raw = append(raw, byte('"'))
	}
	var tmp string
	err := json.Unmarshal(raw, &tmp)
	*h = height(tmp)
	return err
}

func NewBoard(title string) *Board {
	boardID++
	return &Board{
		ID:           boardID,
		Title:        title,
		Style:        "dark",
		Timezone:     "browser",
		Editable:     true,
		HideControls: false,
		Rows:         []*Row{}}
}

func (b *Board) RemoveTags(tags ...string) {
	tagFound := make(map[string]int, len(b.Tags))
	for i, tag := range b.Tags {
		tagFound[tag] = i
	}
	for _, removeTag := range tags {
		if i, ok := tagFound[removeTag]; ok {
			b.Tags = append(b.Tags[:i], b.Tags[i+1:]...)
		}
	}
}

func (b *Board) AddTags(tags ...string) {
	tagFound := make(map[string]bool, len(b.Tags))
	for _, tag := range b.Tags {
		tagFound[tag] = true
	}
	for _, tag := range tags {
		if tagFound[tag] {
			continue
		}
		b.Tags = append(b.Tags, tag)
	}
}

func (b *Board) HasTag(tag string) bool {
	for _, t := range b.Tags {
		if t == tag {
			return true
		}
	}
	return false
}

func (b *Board) AddRow(title string) *Row {
	if title == "" {
		title = "New row"
	}
	row := &Row{
		Title:    title,
		Collapse: false,
		Editable: true,
		Height:   "250px",
		board:    b}
	b.Rows = append(b.Rows, row)
	return row
}

func (b *Board) UpdateSlug() string {
	b.Slug = strings.ToLower(slug.Make(b.Title))
	return b.Slug
}
<|endoftext|>


<commit_before>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"gopkg.in/dougEfresh/gtoggl.v8"
	"gopkg.in/dougEfresh/gworkspace.v8"
	"gopkg.in/dougEfresh/gclient.v8"
	"gopkg.in/dougEfresh/guser.v8"
	"os"
	"strconv"
)

type debugger struct {
	debug bool
}

func (l *debugger) Printf(format string, v ...interface{}) {
	if l.debug {
		fmt.Printf(format, v)
	}
}

func main() {
	var debug = flag.Bool("d", false, "Debug")
	var token = flag.String("t", "", "Toggl API token: https://www.toggl.com/app/profile")
	var command = flag.String("c", "workspace", "command: workspace,client,project...etc ")
	flag.Parse()
	tc, err := gtoggl.NewClient(*token, gtoggl.SetTraceLogger(&debugger{debug: *debug}))
	if err != nil {
		fmt.Fprint(os.Stderr, "A token is required\n")
		flag.Usage()
		os.Exit(-1)
	}
	if *command == "workspace" {
		workspace(tc, flag.Args())
	}
	if *command == "client" {
		client(tc, flag.Args())
	}
	if *command == "user" {
		user(tc, flag.Args())
	}
}

func handleError(error error) {
	if error != nil {
		fmt.Fprintln(os.Stderr, error)
		os.Exit(-1)
	}
}

func client(tc *gtoggl.TogglHttpClient, args []string) {
	c, err := gclient.NewClient(tc)
	var client gclient.Client
	handleError(err)
	if len(args) == 0 || args[0] == "list" {
		clients, err := c.List()
		handleError(err)
		fmt.Printf("%+v\n", clients)
	}

	if args[0] == "create" && len(args) > 1 {
		err = json.Unmarshal([]byte(args[1]), &client)
		handleError(err)
		nClient, err := c.Create(&client)
		handleError(err)
		fmt.Printf("%+v\n", nClient)
	}

	if args[0] == "update" && len(args) > 1 {
		err = json.Unmarshal([]byte(args[1]), &client)
		handleError(err)
		_, err = c.Get(client.Id)
		handleError(err)
		nClient, err := c.Update(&client)
		handleError(err)
		fmt.Printf("%+v\n", nClient)
	}

	if args[0] == "get" && len(args) > 1 {
		i, err := strconv.ParseUint(args[1], 0, 64)
		handleError(err)
		nClient, err := c.Get(i)
		handleError(err)
		fmt.Printf("%+v\n", nClient)
	}

	if args[0] == "delete" && len(args) > 1 {
		i, err := strconv.ParseUint(args[1], 0, 64)
		handleError(err)
		err = c.Delete(i)
		handleError(err)
		fmt.Printf("%+v  deleted\n", i)
	}

}

func workspace(tc *gtoggl.TogglHttpClient, args []string) {
	wsc, err := gworkspace.NewClient(tc)
	handleError(err)
	if len(args) == 0 || args[0] == "list" {
		w, err := wsc.List()
		handleError(err)
		fmt.Printf("%+v\n", w)
		return
	}

	if args[0] == "get" && len(args) > 1 {
		i, err := strconv.ParseUint(args[1], 0, 64)
		handleError(err)
		w, err := wsc.Get(i)
		fmt.Printf("%+v\n", w)
		return
	}

	if args[0] == "update" && len(args) > 1 {
		var uWs gworkspace.Workspace
		handleError(err)
		err = json.Unmarshal([]byte(args[1]), &uWs)
		handleError(err)
		_, err := wsc.Get(uWs.Id)
		handleError(err)
		nWs, err := wsc.Update(&uWs)
		handleError(err)
		fmt.Printf("%+v\n", nWs)
		return
	}
}

func user(tc *gtoggl.TogglHttpClient, args []string) {
	wsc, err := guser.NewClient(tc)
	handleError(err)
	if len(args) == 0 || args[0] == "get" {
		w, err := wsc.Get(false)
		handleError(err)
		js, err := json.Marshal(w)
		handleError(err)
		fmt.Printf("%+s\n", js)
		return
	}

	if args[0] == "reset" {
		w, err := wsc.ResetToken()
		handleError(err)
		fmt.Printf("%+v\n", w)
		return
	}

	if args[0] == "update" && len(args) > 1 {
		var uWs guser.User
		handleError(err)
		err = json.Unmarshal([]byte(args[1]), &uWs)
		handleError(err)
		_, err := wsc.Get(true)
		handleError(err)
		nWs, err := wsc.Update(&uWs)
		handleError(err)
		fmt.Printf("%+v\n", nWs)
		return
	}
	if args[0] == "create" && len(args) > 2 {
		var uWs *guser.User
		uWs, err = wsc.Create(args[1], args[2], args[3])
		handleError(err)
		js, err := json.Marshal(uWs)
		handleError(err)
		fmt.Printf("%+s\n", js)
		return
	}

}
<commit_msg>rename import package<commit_after>package main

import (
	"encoding/json"
	"flag"
	"fmt"
	"gopkg.in/dougEfresh/gtoggl.v8"
	"gopkg.in/dougEfresh/toggl-workspace.v8"
	"gopkg.in/dougEfresh/toggl-client.v8"
	"gopkg.in/dougEfresh/toggl-user.v8"
	"os"
	"strconv"
)

type debugger struct {
	debug bool
}

func (l *debugger) Printf(format string, v ...interface{}) {
	if l.debug {
		fmt.Printf(format, v)
	}
}

func main() {
	var debug = flag.Bool("d", false, "Debug")
	var token = flag.String("t", "", "Toggl API token: https://www.toggl.com/app/profile")
	var command = flag.String("c", "workspace", "command: workspace,client,project...etc ")
	flag.Parse()
	tc, err := gtoggl.NewClient(*token, gtoggl.SetTraceLogger(&debugger{debug: *debug}))
	if err != nil {
		fmt.Fprint(os.Stderr, "A token is required\n")
		flag.Usage()
		os.Exit(-1)
	}
	if *command == "workspace" {
		workspace(tc, flag.Args())
	}
	if *command == "client" {
		client(tc, flag.Args())
	}
	if *command == "user" {
		user(tc, flag.Args())
	}
}

func handleError(error error) {
	if error != nil {
		fmt.Fprintln(os.Stderr, error)
		os.Exit(-1)
	}
}

func client(tc *gtoggl.TogglHttpClient, args []string) {
	c, err := gclient.NewClient(tc)
	var client gclient.Client
	handleError(err)
	if len(args) == 0 || args[0] == "list" {
		clients, err := c.List()
		handleError(err)
		fmt.Printf("%+v\n", clients)
	}

	if args[0] == "create" && len(args) > 1 {
		err = json.Unmarshal([]byte(args[1]), &client)
		handleError(err)
		nClient, err := c.Create(&client)
		handleError(err)
		fmt.Printf("%+v\n", nClient)
	}

	if args[0] == "update" && len(args) > 1 {
		err = json.Unmarshal([]byte(args[1]), &client)
		handleError(err)
		_, err = c.Get(client.Id)
		handleError(err)
		nClient, err := c.Update(&client)
		handleError(err)
		fmt.Printf("%+v\n", nClient)
	}

	if args[0] == "get" && len(args) > 1 {
		i, err := strconv.ParseUint(args[1], 0, 64)
		handleError(err)
		nClient, err := c.Get(i)
		handleError(err)
		fmt.Printf("%+v\n", nClient)
	}

	if args[0] == "delete" && len(args) > 1 {
		i, err := strconv.ParseUint(args[1], 0, 64)
		handleError(err)
		err = c.Delete(i)
		handleError(err)
		fmt.Printf("%+v  deleted\n", i)
	}

}

func workspace(tc *gtoggl.TogglHttpClient, args []string) {
	wsc, err := gworkspace.NewClient(tc)
	handleError(err)
	if len(args) == 0 || args[0] == "list" {
		w, err := wsc.List()
		handleError(err)
		fmt.Printf("%+v\n", w)
		return
	}

	if args[0] == "get" && len(args) > 1 {
		i, err := strconv.ParseUint(args[1], 0, 64)
		handleError(err)
		w, err := wsc.Get(i)
		fmt.Printf("%+v\n", w)
		return
	}

	if args[0] == "update" && len(args) > 1 {
		var uWs gworkspace.Workspace
		handleError(err)
		err = json.Unmarshal([]byte(args[1]), &uWs)
		handleError(err)
		_, err := wsc.Get(uWs.Id)
		handleError(err)
		nWs, err := wsc.Update(&uWs)
		handleError(err)
		fmt.Printf("%+v\n", nWs)
		return
	}
}

func user(tc *gtoggl.TogglHttpClient, args []string) {
	wsc, err := guser.NewClient(tc)
	handleError(err)
	if len(args) == 0 || args[0] == "get" {
		w, err := wsc.Get(false)
		handleError(err)
		js, err := json.Marshal(w)
		handleError(err)
		fmt.Printf("%+s\n", js)
		return
	}

	if args[0] == "reset" {
		w, err := wsc.ResetToken()
		handleError(err)
		fmt.Printf("%+v\n", w)
		return
	}

	if args[0] == "update" && len(args) > 1 {
		var uWs guser.User
		handleError(err)
		err = json.Unmarshal([]byte(args[1]), &uWs)
		handleError(err)
		_, err := wsc.Get(true)
		handleError(err)
		nWs, err := wsc.Update(&uWs)
		handleError(err)
		fmt.Printf("%+v\n", nWs)
		return
	}
	if args[0] == "create" && len(args) > 2 {
		var uWs *guser.User
		uWs, err = wsc.Create(args[1], args[2], args[3])
		handleError(err)
		js, err := json.Marshal(uWs)
		handleError(err)
		fmt.Printf("%+s\n", js)
		return
	}

}
<|endoftext|>


<commit_before>package gubled

import (
	"github.com/alexflint/go-arg"
	"github.com/caarlos0/env"
	"github.com/smancke/guble/gcm"
	"github.com/smancke/guble/metrics"
	"github.com/smancke/guble/protocol"
	"github.com/smancke/guble/server"
	"github.com/smancke/guble/server/auth"
	"github.com/smancke/guble/server/rest"
	"github.com/smancke/guble/server/webserver"
	"github.com/smancke/guble/server/websocket"
	"github.com/smancke/guble/store"

	"expvar"
	"fmt"
	"os"
	"os/signal"
	"path"
	"runtime"
	"syscall"
)

const (
	healthEndpointPrefix = "/_health"
)

type Args struct {
	Listen      string `arg:"-l,help: [Host:]Port the address to listen on (:8080)" env:"GUBLE_LISTEN"`
	LogInfo     bool   `arg:"--log-info,help: Log on INFO level (false)" env:"GUBLE_LOG_INFO"`
	LogDebug    bool   `arg:"--log-debug,help: Log on DEBUG level (false)" env:"GUBLE_LOG_DEBUG"`
	StoragePath string `arg:"--storage-path,help: The path for storing messages and key value data if 'file' is enabled (/var/lib/guble)" env:"GUBLE_STORAGE_PATH"`
	KVBackend   string `arg:"--kv-backend,help: The storage backend for the key value store to use: file|memory (file)" env:"GUBLE_KV_BACKEND"`
	MSBackend   string `arg:"--ms-backend,help: The message storage backend : file|memory (file)" env:"GUBLE_MS_BACKEND"`
	GcmEnable   bool   `arg:"--gcm-enable: Enable the Google Cloud Messaging Connector (false)" env:"GUBLE_GCM_ENABLE"`
	GcmApiKey   string `arg:"--gcm-api-key: The Google API Key for Google Cloud Messaging" env:"GUBLE_GCM_API_KEY"`
	GcmWorkers  int    `arg:"--gcm-workers: The number of workers handling traffic with Google Cloud Messaging (default: GOMAXPROCS)" env:"GUBLE_GCM_WORKERS"`
	Health      string `arg:"--health: The health endpoint (default: /_health; value for disabling it: \"\" )" env:"GUBLE_HEALTH_ENDPOINT"`
	Metrics     string `arg:"--metrics: The metrics endpoint (disabled by default; a possible value for enabling it: /_metrics )" env:"GUBLE_METRICS_ENDPOINT"`
}

var ValidateStoragePath = func(args Args) error {
	if args.KVBackend == "file" || args.MSBackend == "file" {
		testfile := path.Join(args.StoragePath, "write-test-file")
		f, err := os.Create(testfile)
		if err != nil {
			protocol.ErrWithoutTrace("Storage path not present/writeable %q: %v", args.StoragePath, err)
			if args.StoragePath == "/var/lib/guble" {
				protocol.ErrWithoutTrace("Use --storage-path=<path> to override the default location, or create the directory with RW rights.")
			}
			return err
		}
		f.Close()
		os.Remove(testfile)
	}
	return nil
}

var CreateKVStore = func(args Args) store.KVStore {
	switch args.KVBackend {
	case "memory":
		return store.NewMemoryKVStore()
	case "file":
		db := store.NewSqliteKVStore(path.Join(args.StoragePath, "kv-store.db"), true)
		if err := db.Open(); err != nil {
			panic(err)
		}
		return db
	default:
		panic(fmt.Errorf("unknown key-value backend: %q", args.KVBackend))
	}
}

var CreateMessageStore = func(args Args) store.MessageStore {
	switch args.MSBackend {
	case "none", "":
		return store.NewDummyMessageStore(store.NewMemoryKVStore())
	case "file":
		protocol.Info("using FileMessageStore in directory: %q", args.StoragePath)
		return store.NewFileMessageStore(args.StoragePath)
	default:
		panic(fmt.Errorf("unknown message-store backend: %q", args.MSBackend))
	}
}

var CreateModules = func(router server.Router, args Args) []interface{} {
	modules := make([]interface{}, 0, 3)

	if wsHandler, err := websocket.NewWSHandler(router, "/stream/"); err != nil {
		protocol.Err("Error loading WSHandler module: %s", err)
	} else {
		modules = append(modules, wsHandler)
	}

	modules = append(modules, rest.NewRestMessageAPI(router, "/api/"))

	if args.GcmEnable {
		if args.GcmApiKey == "" {
			panic("GCM API Key has to be provided, if GCM is enabled")
		}
		protocol.Info("Google Cloud Messaging: enabled")
		protocol.Debug("gcm: %v workers", args.GcmWorkers)
		if gcm, err := gcm.NewGCMConnector(router, "/gcm/", args.GcmApiKey, args.GcmWorkers); err != nil {
			protocol.Err("Error loading GCM Connector: ", err)
		} else {
			modules = append(modules, gcm)
		}
	} else {
		protocol.Info("Google Cloud Messaging: disabled")
	}

	return modules
}

func Main() {
	defer func() {
		if p := recover(); p != nil {
			protocol.Err("%v", p)
			os.Exit(1)
		}
	}()

	args := loadArgs()
	if args.LogInfo {
		protocol.LogLevel = protocol.LEVEL_INFO
	}
	if args.LogDebug {
		protocol.LogLevel = protocol.LEVEL_DEBUG
	}

	if err := ValidateStoragePath(args); err != nil {
		os.Exit(1)
	}

	service := StartService(args)

	waitForTermination(func() {
		err := service.Stop()
		if err != nil {
			protocol.Err("service: error when stopping: ", err)
		}
	})
}

func StartService(args Args) *server.Service {
	accessManager := auth.NewAllowAllAccessManager(true)
	messageStore := CreateMessageStore(args)
	kvStore := CreateKVStore(args)

	router := server.NewRouter(accessManager, messageStore, kvStore)
	webserver := webserver.New(args.Listen)

	service := server.NewService(router, webserver).HealthEndpointPrefix(args.Health).MetricsEndpointPrefix(args.Metrics)

	service.RegisterModules(CreateModules(router, args)...)

	if err := service.Start(); err != nil {
		protocol.Err(err.Error())
		if err := service.Stop(); err != nil {
			protocol.Err(err.Error())
		}
		os.Exit(1)
	}
	expvar.Publish("guble.args", expvar.Func(func() interface{} {
		return args
	}))

	return service
}

func loadArgs() Args {
	args := Args{
		Listen:      ":8080",
		KVBackend:   "file",
		MSBackend:   "file",
		StoragePath: "/var/lib/guble",
		GcmWorkers:  runtime.GOMAXPROCS(0),
		Health:      healthEndpointPrefix,
	}

	env.Parse(&args)
	arg.MustParse(&args)
	return args
}

func waitForTermination(callback func()) {
	signalC := make(chan os.Signal)
	signal.Notify(signalC, syscall.SIGINT, syscall.SIGTERM)
	protocol.Info("Got signal '%v' .. trying to stop and exit", <-signalC)
	callback()
	metrics.LogOnDebugLevel()
	protocol.Info("Exiting...")
	os.Exit(0)
}
<commit_msg>Added params<commit_after>package gubled

import (
	"github.com/alexflint/go-arg"
	"github.com/caarlos0/env"
	"github.com/smancke/guble/gcm"
	"github.com/smancke/guble/metrics"
	"github.com/smancke/guble/protocol"
	"github.com/smancke/guble/server"
	"github.com/smancke/guble/server/auth"
	"github.com/smancke/guble/server/rest"
	"github.com/smancke/guble/server/webserver"
	"github.com/smancke/guble/server/websocket"
	"github.com/smancke/guble/store"

	"expvar"
	"fmt"
	"os"
	"os/signal"
	"path"
	"runtime"
	"syscall"
)

const (
	healthEndpointPrefix = "/_health"
)

type Args struct {
	Listen      string `arg:"-l,help: [Host:]Port the address to listen on (:8080)" env:"GUBLE_LISTEN"`
	LogInfo     bool   `arg:"--log-info,help: Log on INFO level (false)" env:"GUBLE_LOG_INFO"`
	LogDebug    bool   `arg:"--log-debug,help: Log on DEBUG level (false)" env:"GUBLE_LOG_DEBUG"`
	StoragePath string `arg:"--storage-path,help: The path for storing messages and key value data if 'file' is enabled (/var/lib/guble)" env:"GUBLE_STORAGE_PATH"`
	KVBackend   string `arg:"--kv-backend,help: The storage backend for the key value store to use: file|memory (file)" env:"GUBLE_KV_BACKEND"`
	MSBackend   string `arg:"--ms-backend,help: The message storage backend : file|memory (file)" env:"GUBLE_MS_BACKEND"`
	GcmEnable   bool   `arg:"--gcm-enable: Enable the Google Cloud Messaging Connector (false)" env:"GUBLE_GCM_ENABLE"`
	GcmApiKey   string `arg:"--gcm-api-key: The Google API Key for Google Cloud Messaging" env:"GUBLE_GCM_API_KEY"`
	GcmWorkers  int    `arg:"--gcm-workers: The number of workers handling traffic with Google Cloud Messaging (default: GOMAXPROCS)" env:"GUBLE_GCM_WORKERS"`
	Health      string `arg:"--health: The health endpoint (default: /_health; value for disabling it: \"\" )" env:"GUBLE_HEALTH_ENDPOINT"`
	Metrics     string `arg:"--metrics: The metrics endpoint (disabled by default; a possible value for enabling it: /_metrics )" env:"GUBLE_METRICS_ENDPOINT"`
	NodeId      string `arg:"--node-id: The metrics endpoint (node id for guble node in cluster mode)" env:"GUBLE_NODE_ID"`
	NodeUrls[]  string `arg:"positional,help: The list of urls for other guble nodes"`
}

var ValidateStoragePath = func(args Args) error {
	if args.KVBackend == "file" || args.MSBackend == "file" {
		testfile := path.Join(args.StoragePath, "write-test-file")
		f, err := os.Create(testfile)
		if err != nil {
			protocol.ErrWithoutTrace("Storage path not present/writeable %q: %v", args.StoragePath, err)
			if args.StoragePath == "/var/lib/guble" {
				protocol.ErrWithoutTrace("Use --storage-path=<path> to override the default location, or create the directory with RW rights.")
			}
			return err
		}
		f.Close()
		os.Remove(testfile)
	}
	return nil
}

var CreateKVStore = func(args Args) store.KVStore {
	switch args.KVBackend {
	case "memory":
		return store.NewMemoryKVStore()
	case "file":
		db := store.NewSqliteKVStore(path.Join(args.StoragePath, "kv-store.db"), true)
		if err := db.Open(); err != nil {
			panic(err)
		}
		return db
	default:
		panic(fmt.Errorf("unknown key-value backend: %q", args.KVBackend))
	}
}

var CreateMessageStore = func(args Args) store.MessageStore {
	switch args.MSBackend {
	case "none", "":
		return store.NewDummyMessageStore(store.NewMemoryKVStore())
	case "file":
		protocol.Info("using FileMessageStore in directory: %q", args.StoragePath)
		return store.NewFileMessageStore(args.StoragePath)
	default:
		panic(fmt.Errorf("unknown message-store backend: %q", args.MSBackend))
	}
}

var CreateModules = func(router server.Router, args Args) []interface{} {
	modules := make([]interface{}, 0, 3)

	if wsHandler, err := websocket.NewWSHandler(router, "/stream/"); err != nil {
		protocol.Err("Error loading WSHandler module: %s", err)
	} else {
		modules = append(modules, wsHandler)
	}

	modules = append(modules, rest.NewRestMessageAPI(router, "/api/"))

	if args.GcmEnable {
		if args.GcmApiKey == "" {
			panic("GCM API Key has to be provided, if GCM is enabled")
		}
		protocol.Info("Google Cloud Messaging: enabled")
		protocol.Debug("gcm: %v workers", args.GcmWorkers)
		if gcm, err := gcm.NewGCMConnector(router, "/gcm/", args.GcmApiKey, args.GcmWorkers); err != nil {
			protocol.Err("Error loading GCM Connector: ", err)
		} else {
			modules = append(modules, gcm)
		}
	} else {
		protocol.Info("Google Cloud Messaging: disabled")
	}

	return modules
}

func Main() {
	defer func() {
		if p := recover(); p != nil {
			protocol.Err("%v", p)
			os.Exit(1)
		}
	}()

	args := loadArgs()
	if args.LogInfo {
		protocol.LogLevel = protocol.LEVEL_INFO
	}
	if args.LogDebug {
		protocol.LogLevel = protocol.LEVEL_DEBUG
	}

	if err := ValidateStoragePath(args); err != nil {
		os.Exit(1)
	}

	service := StartService(args)

	waitForTermination(func() {
		err := service.Stop()
		if err != nil {
			protocol.Err("service: error when stopping: ", err)
		}
	})
}

func StartService(args Args) *server.Service {
	accessManager := auth.NewAllowAllAccessManager(true)
	messageStore := CreateMessageStore(args)
	kvStore := CreateKVStore(args)

	router := server.NewRouter(accessManager, messageStore, kvStore)
	webserver := webserver.New(args.Listen)

	service := server.NewService(router, webserver).HealthEndpointPrefix(args.Health).MetricsEndpointPrefix(args.Metrics)

	service.RegisterModules(CreateModules(router, args)...)

	if err := service.Start(); err != nil {
		protocol.Err(err.Error())
		if err := service.Stop(); err != nil {
			protocol.Err(err.Error())
		}
		os.Exit(1)
	}
	expvar.Publish("guble.args", expvar.Func(func() interface{} {
		return args
	}))

	return service
}

func loadArgs() Args {
	args := Args{
		Listen:      ":8080",
		KVBackend:   "file",
		MSBackend:   "file",
		StoragePath: "/var/lib/guble",
		GcmWorkers:  runtime.GOMAXPROCS(0),
		Health:      healthEndpointPrefix,
	}

	env.Parse(&args)
	arg.MustParse(&args)
	return args
}

func waitForTermination(callback func()) {
	signalC := make(chan os.Signal)
	signal.Notify(signalC, syscall.SIGINT, syscall.SIGTERM)
	protocol.Info("Got signal '%v' .. trying to stop and exit", <-signalC)
	callback()
	metrics.LogOnDebugLevel()
	protocol.Info("Exiting...")
	os.Exit(0)
}
<|endoftext|>


<commit_before>package main

import (
	"fmt"
	"os"

	"github.com/acsellers/glex"
	"github.com/go-gl/gl"
	"github.com/go-gl/glfw"
)

var (
	Window  glex.ContextImplementation
	Ctx     *glex.Context
	Current glex.Activity
)

type TriActivity struct {
	ctx  *glex.Context
	buf  gl.Buffer
	gen  bool
	prog gl.Program
}

func (ta *TriActivity) SetContext(c *glex.Context) {
	ta.ctx = c
}

func (ta *TriActivity) Draw() {
	gl.Clear(gl.COLOR_BUFFER_BIT)
	ta.prog.Use()
	ta.DrawTriangle()
}

func (ta *TriActivity) DrawTriangle() {
	if !ta.gen {
		ta.GenBuffer()
		ta.GenShaders()
	}

	al := gl.AttribLocation(0)
	al.EnableArray()
	ta.buf.Bind(gl.ARRAY_BUFFER)
	al.AttribPointer(
		3,
		gl.FLOAT,
		false,
		0,
		nil,
	)
	gl.DrawArrays(gl.TRIANGLES, 0, 3)
	al.DisableArray()
}

func (ta *TriActivity) GenBuffer() {
	ta.buf = gl.GenBuffer()
	ta.buf.Bind(gl.ARRAY_BUFFER)
	gl.BufferData(
		gl.ARRAY_BUFFER,
		9*4,
		[]float32{
			-1.0, -1.0, 0.0,
			1.0, -1.0, 0.0,
			0.0, 1.0, 0.0,
		},
		gl.STATIC_DRAW,
	)
	ta.gen = true
}

func (ta *TriActivity) GenShaders() {
	vShader := gl.CreateShader(gl.VERTEX_SHADER)
	defer vShader.Delete()
	vShader.Source(`#version 140
#extension GL_ARB_explicit_attrib_location : enable
layout(location = 0) in vec3 vertexPosition_modelspace;

void main() {
  gl_Position.xyz = vertexPosition_modelspace;
  gl_Position.w = 1.0;
}`)
	vShader.Compile()
	fmt.Println("Vertex Shader")
	fmt.Println(vShader.Get(gl.COMPILE_STATUS))
	fmt.Println(vShader.GetInfoLog())

	fShader := gl.CreateShader(gl.FRAGMENT_SHADER)
	defer fShader.Delete()
	fShader.Source(`#version 140
out vec3 color;

void main() {
  color = vec3(1,0,0);
}`)
	fShader.Compile()
	fmt.Println("Fragment Shader")
	fmt.Println(fShader.Get(gl.COMPILE_STATUS))
	fmt.Println(fShader.GetInfoLog())

	prog := gl.CreateProgram()
	prog.AttachShader(vShader)
	prog.AttachShader(fShader)
	prog.Link()
	fmt.Println("Program")
	fmt.Println(prog.Get(gl.LINK_STATUS))
	fmt.Println(prog.GetInfoLog())

	ta.prog = prog
}

func init() {
	Ctx = &glex.Context{
		Width:       800,
		Height:      600,
		ColorDepth:  [4]int{8, 8, 8, 8},
		BufferDepth: [2]int{0, 0},
		Vsync:       true,
		WindowTitle: "Experiment: Three",
		Keyboard: func(key, state int) {
			if key == glfw.KeyEsc {
				Ctx.Active = false
			}
		},
	}

	Window = &glex.GlfwContext{
		Ctx: Ctx,
	}

	Current = &TriActivity{}
	Current.SetContext(Ctx)
}

func main() {
	err := Window.Start()
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	Window.Swap()
	gl.GenVertexArray().Bind()

	for Ctx.Active {
		Current.Draw()
		Window.Swap()
	}

}
<commit_msg>Don't need 140, drop to 130 for mesa 9.x<commit_after>package main

import (
	"fmt"
	"os"

	"github.com/acsellers/glex"
	"github.com/go-gl/gl"
	"github.com/go-gl/glfw"
)

var (
	Window  glex.ContextImplementation
	Ctx     *glex.Context
	Current glex.Activity
)

type TriActivity struct {
	ctx  *glex.Context
	buf  gl.Buffer
	gen  bool
	prog gl.Program
}

func (ta *TriActivity) SetContext(c *glex.Context) {
	ta.ctx = c
}

func (ta *TriActivity) Draw() {
	gl.Clear(gl.COLOR_BUFFER_BIT)
	ta.prog.Use()
	ta.DrawTriangle()
}

func (ta *TriActivity) DrawTriangle() {
	if !ta.gen {
		ta.GenBuffer()
		ta.GenShaders()
	}

	al := gl.AttribLocation(0)
	al.EnableArray()
	ta.buf.Bind(gl.ARRAY_BUFFER)
	al.AttribPointer(
		3,
		gl.FLOAT,
		false,
		0,
		nil,
	)
	gl.DrawArrays(gl.TRIANGLES, 0, 3)
	al.DisableArray()
}

func (ta *TriActivity) GenBuffer() {
	ta.buf = gl.GenBuffer()
	ta.buf.Bind(gl.ARRAY_BUFFER)
	gl.BufferData(
		gl.ARRAY_BUFFER,
		9*4,
		[]float32{
			-1.0, -1.0, 0.0,
			1.0, -1.0, 0.0,
			0.0, 1.0, 0.0,
		},
		gl.STATIC_DRAW,
	)
	ta.gen = true
}

func (ta *TriActivity) GenShaders() {
	vShader := gl.CreateShader(gl.VERTEX_SHADER)
	defer vShader.Delete()
	vShader.Source(`#version 130
#extension GL_ARB_explicit_attrib_location : enable
layout(location = 0) in vec3 vertexPosition_modelspace;

void main() {
  gl_Position.xyz = vertexPosition_modelspace;
  gl_Position.w = 1.0;
}`)
	vShader.Compile()
	fmt.Println("Vertex Shader")
	fmt.Println(vShader.Get(gl.COMPILE_STATUS))
	fmt.Println(vShader.GetInfoLog())

	fShader := gl.CreateShader(gl.FRAGMENT_SHADER)
	defer fShader.Delete()
	fShader.Source(`#version 130
out vec3 color;

void main() {
  color = vec3(1,0,0);
}`)
	fShader.Compile()
	fmt.Println("Fragment Shader")
	fmt.Println(fShader.Get(gl.COMPILE_STATUS))
	fmt.Println(fShader.GetInfoLog())

	prog := gl.CreateProgram()
	prog.AttachShader(vShader)
	prog.AttachShader(fShader)
	prog.Link()
	fmt.Println("Program")
	fmt.Println(prog.Get(gl.LINK_STATUS))
	fmt.Println(prog.GetInfoLog())

	ta.prog = prog
}

func init() {
	Ctx = &glex.Context{
		Width:       800,
		Height:      600,
		ColorDepth:  [4]int{8, 8, 8, 8},
		BufferDepth: [2]int{0, 0},
		Vsync:       true,
		WindowTitle: "Experiment: Three",
		Keyboard: func(key, state int) {
			if key == glfw.KeyEsc {
				Ctx.Active = false
			}
		},
	}

	Window = &glex.GlfwContext{
		Ctx: Ctx,
	}

	Current = &TriActivity{}
	Current.SetContext(Ctx)
}

func main() {
	err := Window.Start()
	if err != nil {
		fmt.Println(err)
		os.Exit(1)
	}
	Window.Swap()
	gl.GenVertexArray().Bind()

	for Ctx.Active {
		Current.Draw()
		Window.Swap()
	}

}
<|endoftext|>


<commit_before>/**
 * (C) Copyright 2013, Deft Labs
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package dlshared

import (
	"time"
	"syscall"
)

const (
	nanosecondsPerMillisecond float64 = 1000000.0
)

// Returns the time from the milliseconds since epoch. This returns the time in UTC.
func TimeFromMillis(timeInMillis int64) *time.Time {
	theTime := time.Unix(timeInMillis/1000, 0)
	location, _ := time.LoadLocation("UTC")
	theTime = theTime.In(location)
	return &theTime
}

// Convert a time struct to milliseconds since epoch.
func TimeToMillis(tv *time.Time) int64 { return tv.UnixNano() / 1e6 }

// Convert a duration to milliseconds.
func DurationToMillis(dur *time.Duration) int64 { return int64(float64(dur.Nanoseconds()) / nanosecondsPerMillisecond) }

// Get the current time in millis since epoch. Source from stackoverflow:
// http://stackoverflow.com/questions/6161839/go-time-milliseconds
func CurrentTimeInMillis() int64 {
	tv := new(syscall.Timeval)
	syscall.Gettimeofday(tv)
	return (int64(tv.Sec)*1e3 + int64(tv.Usec)/1e3)
}

// Returns the current time in seconds since epoch (i.e., a unix timestamp). Source from stackoverflow:
// http://stackoverflow.com/questions/9539108/obtaining-a-unix-timestamp-in-go-language-current-time-in-seconds-since-epoch
func CurrentTimeInSeconds() int32 { return int32(time.Now().Unix()) }

// NowTimeUnixStr returns the date in unix date string format e.g., Wed Dec 11 19:03:18 EST 2013
func NowTimeUnixStr() string { return time.Now().Format(time.UnixDate) }

<commit_msg>added now in utc method<commit_after>/**
 * (C) Copyright 2013, Deft Labs
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at:
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package dlshared

import (
	"time"
	"syscall"
)

const (
	nanosecondsPerMillisecond float64 = 1000000.0
)

// Returns the time from the milliseconds since epoch. This returns the time in UTC.
func TimeFromMillis(timeInMillis int64) *time.Time {
	theTime := time.Unix(timeInMillis/1000, 0)
	location, _ := time.LoadLocation("UTC")
	theTime = theTime.In(location)
	return &theTime
}

// Convert a time struct to milliseconds since epoch.
func TimeToMillis(tv *time.Time) int64 { return tv.UnixNano() / 1e6 }

func NowInUtc() *time.Time {
	location, _ := time.LoadLocation("UTC")
	time := time.Now().In(location)
	return &time
}

// Convert a duration to milliseconds.
func DurationToMillis(dur *time.Duration) int64 { return int64(float64(dur.Nanoseconds()) / nanosecondsPerMillisecond) }

// Get the current time in millis since epoch. Source from stackoverflow:
// http://stackoverflow.com/questions/6161839/go-time-milliseconds
func CurrentTimeInMillis() int64 {
	tv := new(syscall.Timeval)
	syscall.Gettimeofday(tv)
	return (int64(tv.Sec)*1e3 + int64(tv.Usec)/1e3)
}

// Returns the current time in seconds since epoch (i.e., a unix timestamp). Source from stackoverflow:
// http://stackoverflow.com/questions/9539108/obtaining-a-unix-timestamp-in-go-language-current-time-in-seconds-since-epoch
func CurrentTimeInSeconds() int32 { return int32(time.Now().Unix()) }

// NowTimeUnixStr returns the date in unix date string format e.g., Wed Dec 11 19:03:18 EST 2013
func NowTimeUnixStr() string { return time.Now().Format(time.UnixDate) }

<|endoftext|>


<commit_before>package hammer

import (
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"math/rand"
	"net/http"
	"os"
	"sort"
	"sync"
	"time"

	"github.com/bmizerany/perks/quantile"
)

type RequestCallback func(Request, *http.Response, Result)

type Request struct {
	HTTPRequest *http.Request
	Name        string
	ReadBody    bool
	Callback    RequestCallback
}

type RequestGenerator func(*Hammer)

type Hammer struct {
	RunFor           float64
	Threads          int
	Backlog          int
	QPS              float64
	LogErrors        bool
	GenerateFunction RequestGenerator
	exit             chan int
	requests         chan Request
	throttled        chan Request
	results          chan Result
	stats            chan StatsSummary
	requestWorkers   sync.WaitGroup
	finishedResults  sync.WaitGroup
}

type Result struct {
	Name       string
	Status     int
	Start      time.Time
	GotHeaders time.Time
	GotBody    time.Time
}

func (hammer *Hammer) warn(msg string) {
	log.Println(msg)
}

func (hammer *Hammer) warnf(fmt string, args ...interface{}) {
	log.Printf(fmt, args...)
}

func (hammer *Hammer) sendRequests() {
	defer hammer.requestWorkers.Done()

	client := &http.Client{}

	for req := range hammer.throttled {
		var result Result
		result.Name = req.Name
		result.Start = time.Now()
		res, err := client.Do(req.HTTPRequest)
		result.GotHeaders = time.Now()
		if err != nil {
			result.Status = 499
			result.GotBody = result.GotHeaders
			hammer.warn(err.Error())
		} else {
			result.Status = res.StatusCode
			if result.Status >= 400 {
				if hammer.LogErrors {
					// TODO: refactor this into a method
					logOut, err := ioutil.TempFile(".", "error.log.")
					if err == nil {
						res.Write(logOut)
						result.GotBody = time.Now()
					} else {
						hammer.warnf("%s writing error log\n", err.Error())
					}
				} else if req.ReadBody {
					io.Copy(ioutil.Discard, res.Body)
					result.GotBody = time.Now()
				}
				hammer.warnf("Got status %s for %s\n", res.Status, req.HTTPRequest.URL.String())
			} else if req.ReadBody {
				io.Copy(ioutil.Discard, res.Body)
				result.GotBody = time.Now()
			} else {
				res.Body.Close()
			}
		}
		if req.Callback != nil {
			go req.Callback(req, res, result)
		}
		hammer.results <- result
	}
}

type Stats struct {
	Name           string
	Quantiles      []float64
	Begin          time.Time
	End            time.Time
	Statuses       map[int]int
	HeaderStats    BasicStats
	HeaderQuantile quantile.Stream
	BodyStats      BasicStats
	BodyQuantile   quantile.Stream
}

type SingleStatSummary struct {
	BasicStats
	Quantiles map[float64]float64
}

type StatsSummary struct {
	Name     string
	Begin    time.Time
	End      time.Time
	Statuses map[int]int
	Headers  SingleStatSummary
	Body     SingleStatSummary
}

func newStats(name string, quantiles ...float64) *Stats {
	return &Stats{
		Name:           name,
		Quantiles:      quantiles,
		Statuses:       make(map[int]int),
		HeaderStats:    BasicStats{},
		HeaderQuantile: *(quantile.NewTargeted(quantiles...)),
		BodyStats:      BasicStats{},
		BodyQuantile:   *(quantile.NewTargeted(quantiles...)),
	}
}

func (stats *Stats) Summarize() (summary StatsSummary) {
	summary.Name = stats.Name
	summary.Begin = stats.Begin
	summary.End = stats.End
	summary.Statuses = stats.Statuses
	summary.Headers.BasicStats = stats.HeaderStats
	summary.Headers.Quantiles = make(map[float64]float64, len(stats.Quantiles))
	for _, quantile := range stats.Quantiles {
		summary.Headers.Quantiles[quantile] = stats.HeaderQuantile.Query(quantile)
	}
	summary.Body.BasicStats = stats.BodyStats
	if stats.BodyStats.Count > 0 {
		summary.Body.Quantiles = make(map[float64]float64, len(stats.Quantiles))
		for _, quantile := range stats.Quantiles {
			summary.Body.Quantiles[quantile] = stats.BodyQuantile.Query(quantile)
		}
	}
	return
}

func (hammer *Hammer) ReportPrinter(format string) func(StatsSummary) {
	return func(stats StatsSummary) {
		file, err := os.Create(fmt.Sprintf(format, stats.Name))
		if err != nil {
			hammer.warn(err.Error())
			return
		}
		runTime := stats.End.Sub(stats.Begin).Seconds()
		count := stats.Headers.Count
		fmt.Fprintf(
			file,
			`Hammer REPORT FOR %s:

Run time: %.3f
Total hits: %.0f
Hits/sec: %.3f

Status totals:
`,
			stats.Name,
			runTime,
			count,
			count/runTime,
		)
		statusCodes := []int{}
		for code, _ := range stats.Statuses {
			statusCodes = append(statusCodes, code)
		}
		sort.Ints(statusCodes)
		for _, code := range statusCodes {
			fmt.Fprintf(file, "%d\t%d\t%.3f\n", code, stats.Statuses[code], 100*float64(stats.Statuses[code])/count)
		}
		if count > 0 {
			fmt.Fprintf(
				file,
				"\nFirst byte mean +/- SD: %.2f +/- %.2f ms\n",
				1000*stats.Headers.Mean(),
				1000*stats.Headers.StdDev(),
			)
			fmt.Fprintf(
				file,
				"First byte 5-95 pct: (%.2f, %.2f) ms\n",
				1000*stats.Headers.Quantiles[0.05],
				1000*stats.Headers.Quantiles[0.95],
			)
			if stats.Body.Count > 0 {
				fmt.Fprintf(
					file,
					"\nFull response mean +/- SD: %.2f +/- %.2f ms\n",
					1000*stats.Body.Mean(),
					1000*stats.Body.StdDev(),
				)
				fmt.Fprintf(
					file,
					"First byte 5-95 pct: (%.2f, %.2f) ms\n",
					1000*stats.Body.Quantiles[0.05],
					1000*stats.Body.Quantiles[0.95],
				)
			}
		}
		file.Close()
	}
}

func (hammer *Hammer) StatsPrinter(filename string) func(StatsSummary) {
	return func(stats StatsSummary) {
		statsFile, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
		if err != nil {
			hammer.warn(err.Error())
			return
		}
		runTime := stats.End.Sub(stats.Begin).Seconds()
		count := stats.Headers.Count
		fmt.Fprintf(
			statsFile,
			"%s\t%d\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f",
			stats.Name,
			hammer.Threads,
			hammer.QPS,
			runTime,
			count,
			count/runTime,
			1000*stats.Headers.Mean(),
			1000*stats.Headers.StdDev(),
			1000*stats.Headers.Quantiles[0.05],
			1000*stats.Headers.Quantiles[0.95],
		)
		if stats.Body.Count > 0 {
			fmt.Fprintf(
				statsFile,
				"%f\t%f\t%f\t%f\n",
				1000*stats.Body.Mean(),
				1000*stats.Body.StdDev(),
				1000*stats.Body.Quantiles[0.05],
				1000*stats.Body.Quantiles[0.95],
			)
		} else {
			fmt.Fprintf(statsFile, "\n")
		}
		statsFile.Close()
	}
}

func (hammer *Hammer) collectResults() {
	defer hammer.finishedResults.Done()

	statsMap := map[string]*Stats{}

	ticker := time.NewTicker(1 * time.Second)
	defer ticker.Stop()

	defer func() {
		for _, stats := range statsMap {
			hammer.stats <- stats.Summarize()
		}
		close(hammer.stats)
	}()

	for {
		select {
		case res, ok := <-hammer.results:
			if !ok {
				return
			}

			stats, statsExisted := statsMap[res.Name]
			if !statsExisted {
				stats = newStats(res.Name, 0.05, 0.95)
				statsMap[res.Name] = stats
			}

			stats.Statuses[res.Status]++

			start := res.Start
			end := res.GotHeaders
			dur := end.Sub(start).Seconds()
			stats.HeaderStats.Add(dur)
			stats.HeaderQuantile.Insert(dur)
			if res.GotBody != (time.Time{}) {
				end = res.GotBody
				dur := end.Sub(start).Seconds()
				stats.BodyStats.Add(dur)
				stats.BodyQuantile.Insert(dur)
			}
			if !statsExisted {
				stats.Begin = start
				stats.End = end
			} else {
				if start.Before(stats.Begin) {
					stats.Begin = start
				}
				if start.After(stats.End) {
					stats.End = start
				}
			}
		case <-ticker.C:
			for _, stats := range statsMap {
				hammer.stats <- stats.Summarize()
			}
		}
	}
}

func (hammer *Hammer) throttle() {
	ticker := time.NewTicker(time.Duration(float64(time.Second) / hammer.QPS))
	defer ticker.Stop()
	defer close(hammer.throttled)

	for {
		select {
		case <-hammer.exit:
			return
		case <-ticker.C:
			req := <-hammer.requests
			hammer.throttled <- req
		}
	}
}

func RandomURLGenerator(name string, readBody bool, URLs []string, Headers map[string][]string) RequestGenerator {
	readiedRequests := make([]Request, len(URLs))
	for i, url := range URLs {
		req, err := http.NewRequest("GET", url, nil)
		if err != nil {
			panic(err)
		}
		req.Header = Headers
		readiedRequests[i] = Request{
			ReadBody:    readBody,
			HTTPRequest: req,
			Name:        name,
		}
	}
	num := len(readiedRequests)

	return func(hammer *Hammer) {
		defer func() { close(hammer.requests) }()

		for {
			select {
			case <-hammer.exit:
				return
			default:
				var idx int
				if num == 1 {
					idx = 0
				} else {
					idx = rand.Intn(len(readiedRequests))
				}
				hammer.requests <- readiedRequests[idx]
			}
		}
	}
}

func (hammer *Hammer) Run(statschan chan StatsSummary) {
	hammer.exit = make(chan int)
	hammer.requests = make(chan Request)
	hammer.throttled = make(chan Request, hammer.Backlog)
	hammer.results = make(chan Result, hammer.Threads*2)
	hammer.stats = statschan

	for i := 0; i < hammer.Threads; i++ {
		hammer.requestWorkers.Add(1)
		go hammer.sendRequests()
	}
	hammer.finishedResults.Add(1)
	go hammer.collectResults()
	go hammer.throttle()
	go hammer.GenerateFunction(hammer)
	go func() {
		hammer.requestWorkers.Wait()
		close(hammer.results)
	}()

	// Give it time to run...
	time.Sleep(time.Duration(hammer.RunFor * float64(time.Second)))
	// And then signal GenerateRequests to stop.
	close(hammer.exit)
	hammer.finishedResults.Wait()
}
<commit_msg>Don't pretend that a 499 has a body anymore.<commit_after>package hammer

import (
	"fmt"
	"io"
	"io/ioutil"
	"log"
	"math/rand"
	"net/http"
	"os"
	"sort"
	"sync"
	"time"

	"github.com/bmizerany/perks/quantile"
)

type RequestCallback func(Request, *http.Response, Result)

type Request struct {
	HTTPRequest *http.Request
	Name        string
	ReadBody    bool
	Callback    RequestCallback
}

type RequestGenerator func(*Hammer)

type Hammer struct {
	RunFor           float64
	Threads          int
	Backlog          int
	QPS              float64
	LogErrors        bool
	GenerateFunction RequestGenerator
	exit             chan int
	requests         chan Request
	throttled        chan Request
	results          chan Result
	stats            chan StatsSummary
	requestWorkers   sync.WaitGroup
	finishedResults  sync.WaitGroup
}

type Result struct {
	Name       string
	Status     int
	Start      time.Time
	GotHeaders time.Time
	GotBody    time.Time
}

func (hammer *Hammer) warn(msg string) {
	log.Println(msg)
}

func (hammer *Hammer) warnf(fmt string, args ...interface{}) {
	log.Printf(fmt, args...)
}

func (hammer *Hammer) sendRequests() {
	defer hammer.requestWorkers.Done()

	client := &http.Client{}

	for req := range hammer.throttled {
		var result Result
		result.Name = req.Name
		result.Start = time.Now()
		res, err := client.Do(req.HTTPRequest)
		result.GotHeaders = time.Now()
		if err != nil {
			result.Status = 499
			hammer.warn(err.Error())
		} else {
			result.Status = res.StatusCode
			if result.Status >= 400 {
				if hammer.LogErrors {
					// TODO: refactor this into a method
					logOut, err := ioutil.TempFile(".", "error.log.")
					if err == nil {
						res.Write(logOut)
						result.GotBody = time.Now()
					} else {
						hammer.warnf("%s writing error log\n", err.Error())
					}
				} else if req.ReadBody {
					io.Copy(ioutil.Discard, res.Body)
					result.GotBody = time.Now()
				}
				hammer.warnf("Got status %s for %s\n", res.Status, req.HTTPRequest.URL.String())
			} else if req.ReadBody {
				io.Copy(ioutil.Discard, res.Body)
				result.GotBody = time.Now()
			} else {
				res.Body.Close()
			}
		}
		if req.Callback != nil {
			go req.Callback(req, res, result)
		}
		hammer.results <- result
	}
}

type Stats struct {
	Name           string
	Quantiles      []float64
	Begin          time.Time
	End            time.Time
	Statuses       map[int]int
	HeaderStats    BasicStats
	HeaderQuantile quantile.Stream
	BodyStats      BasicStats
	BodyQuantile   quantile.Stream
}

type SingleStatSummary struct {
	BasicStats
	Quantiles map[float64]float64
}

type StatsSummary struct {
	Name     string
	Begin    time.Time
	End      time.Time
	Statuses map[int]int
	Headers  SingleStatSummary
	Body     SingleStatSummary
}

func newStats(name string, quantiles ...float64) *Stats {
	return &Stats{
		Name:           name,
		Quantiles:      quantiles,
		Statuses:       make(map[int]int),
		HeaderStats:    BasicStats{},
		HeaderQuantile: *(quantile.NewTargeted(quantiles...)),
		BodyStats:      BasicStats{},
		BodyQuantile:   *(quantile.NewTargeted(quantiles...)),
	}
}

func (stats *Stats) Summarize() (summary StatsSummary) {
	summary.Name = stats.Name
	summary.Begin = stats.Begin
	summary.End = stats.End
	summary.Statuses = stats.Statuses
	summary.Headers.BasicStats = stats.HeaderStats
	summary.Headers.Quantiles = make(map[float64]float64, len(stats.Quantiles))
	for _, quantile := range stats.Quantiles {
		summary.Headers.Quantiles[quantile] = stats.HeaderQuantile.Query(quantile)
	}
	summary.Body.BasicStats = stats.BodyStats
	if stats.BodyStats.Count > 0 {
		summary.Body.Quantiles = make(map[float64]float64, len(stats.Quantiles))
		for _, quantile := range stats.Quantiles {
			summary.Body.Quantiles[quantile] = stats.BodyQuantile.Query(quantile)
		}
	}
	return
}

func (hammer *Hammer) ReportPrinter(format string) func(StatsSummary) {
	return func(stats StatsSummary) {
		file, err := os.Create(fmt.Sprintf(format, stats.Name))
		if err != nil {
			hammer.warn(err.Error())
			return
		}
		runTime := stats.End.Sub(stats.Begin).Seconds()
		count := stats.Headers.Count
		fmt.Fprintf(
			file,
			`Hammer REPORT FOR %s:

Run time: %.3f
Total hits: %.0f
Hits/sec: %.3f

Status totals:
`,
			stats.Name,
			runTime,
			count,
			count/runTime,
		)
		statusCodes := []int{}
		for code, _ := range stats.Statuses {
			statusCodes = append(statusCodes, code)
		}
		sort.Ints(statusCodes)
		for _, code := range statusCodes {
			fmt.Fprintf(file, "%d\t%d\t%.3f\n", code, stats.Statuses[code], 100*float64(stats.Statuses[code])/count)
		}
		if count > 0 {
			fmt.Fprintf(
				file,
				"\nFirst byte mean +/- SD: %.2f +/- %.2f ms\n",
				1000*stats.Headers.Mean(),
				1000*stats.Headers.StdDev(),
			)
			fmt.Fprintf(
				file,
				"First byte 5-95 pct: (%.2f, %.2f) ms\n",
				1000*stats.Headers.Quantiles[0.05],
				1000*stats.Headers.Quantiles[0.95],
			)
			if stats.Body.Count > 0 {
				fmt.Fprintf(
					file,
					"\nFull response mean +/- SD: %.2f +/- %.2f ms\n",
					1000*stats.Body.Mean(),
					1000*stats.Body.StdDev(),
				)
				fmt.Fprintf(
					file,
					"First byte 5-95 pct: (%.2f, %.2f) ms\n",
					1000*stats.Body.Quantiles[0.05],
					1000*stats.Body.Quantiles[0.95],
				)
			}
		}
		file.Close()
	}
}

func (hammer *Hammer) StatsPrinter(filename string) func(StatsSummary) {
	return func(stats StatsSummary) {
		statsFile, err := os.OpenFile(filename, os.O_WRONLY|os.O_CREATE|os.O_APPEND, 0666)
		if err != nil {
			hammer.warn(err.Error())
			return
		}
		runTime := stats.End.Sub(stats.Begin).Seconds()
		count := stats.Headers.Count
		fmt.Fprintf(
			statsFile,
			"%s\t%d\t%f\t%f\t%f\t%f\t%f\t%f\t%f\t%f",
			stats.Name,
			hammer.Threads,
			hammer.QPS,
			runTime,
			count,
			count/runTime,
			1000*stats.Headers.Mean(),
			1000*stats.Headers.StdDev(),
			1000*stats.Headers.Quantiles[0.05],
			1000*stats.Headers.Quantiles[0.95],
		)
		if stats.Body.Count > 0 {
			fmt.Fprintf(
				statsFile,
				"%f\t%f\t%f\t%f\n",
				1000*stats.Body.Mean(),
				1000*stats.Body.StdDev(),
				1000*stats.Body.Quantiles[0.05],
				1000*stats.Body.Quantiles[0.95],
			)
		} else {
			fmt.Fprintf(statsFile, "\n")
		}
		statsFile.Close()
	}
}

func (hammer *Hammer) collectResults() {
	defer hammer.finishedResults.Done()

	statsMap := map[string]*Stats{}

	ticker := time.NewTicker(1 * time.Second)
	defer ticker.Stop()

	defer func() {
		for _, stats := range statsMap {
			hammer.stats <- stats.Summarize()
		}
		close(hammer.stats)
	}()

	for {
		select {
		case res, ok := <-hammer.results:
			if !ok {
				return
			}

			stats, statsExisted := statsMap[res.Name]
			if !statsExisted {
				stats = newStats(res.Name, 0.05, 0.95)
				statsMap[res.Name] = stats
			}

			stats.Statuses[res.Status]++

			start := res.Start
			end := res.GotHeaders
			dur := end.Sub(start).Seconds()
			stats.HeaderStats.Add(dur)
			stats.HeaderQuantile.Insert(dur)
			if res.GotBody != (time.Time{}) {
				end = res.GotBody
				dur := end.Sub(start).Seconds()
				stats.BodyStats.Add(dur)
				stats.BodyQuantile.Insert(dur)
			}
			if !statsExisted {
				stats.Begin = start
				stats.End = end
			} else {
				if start.Before(stats.Begin) {
					stats.Begin = start
				}
				if start.After(stats.End) {
					stats.End = start
				}
			}
		case <-ticker.C:
			for _, stats := range statsMap {
				hammer.stats <- stats.Summarize()
			}
		}
	}
}

func (hammer *Hammer) throttle() {
	ticker := time.NewTicker(time.Duration(float64(time.Second) / hammer.QPS))
	defer ticker.Stop()
	defer close(hammer.throttled)

	for {
		select {
		case <-hammer.exit:
			return
		case <-ticker.C:
			req := <-hammer.requests
			hammer.throttled <- req
		}
	}
}

func RandomURLGenerator(name string, readBody bool, URLs []string, Headers map[string][]string) RequestGenerator {
	readiedRequests := make([]Request, len(URLs))
	for i, url := range URLs {
		req, err := http.NewRequest("GET", url, nil)
		if err != nil {
			panic(err)
		}
		req.Header = Headers
		readiedRequests[i] = Request{
			ReadBody:    readBody,
			HTTPRequest: req,
			Name:        name,
		}
	}
	num := len(readiedRequests)

	return func(hammer *Hammer) {
		defer func() { close(hammer.requests) }()

		for {
			select {
			case <-hammer.exit:
				return
			default:
				var idx int
				if num == 1 {
					idx = 0
				} else {
					idx = rand.Intn(len(readiedRequests))
				}
				hammer.requests <- readiedRequests[idx]
			}
		}
	}
}

func (hammer *Hammer) Run(statschan chan StatsSummary) {
	hammer.exit = make(chan int)
	hammer.requests = make(chan Request)
	hammer.throttled = make(chan Request, hammer.Backlog)
	hammer.results = make(chan Result, hammer.Threads*2)
	hammer.stats = statschan

	for i := 0; i < hammer.Threads; i++ {
		hammer.requestWorkers.Add(1)
		go hammer.sendRequests()
	}
	hammer.finishedResults.Add(1)
	go hammer.collectResults()
	go hammer.throttle()
	go hammer.GenerateFunction(hammer)
	go func() {
		hammer.requestWorkers.Wait()
		close(hammer.results)
	}()

	// Give it time to run...
	time.Sleep(time.Duration(hammer.RunFor * float64(time.Second)))
	// And then signal GenerateRequests to stop.
	close(hammer.exit)
	hammer.finishedResults.Wait()
}
<|endoftext|>


<commit_before>	package geo_skeleton

import "github.com/sjsafranek/DiffDB/diff_store"
import "github.com/sjsafranek/SkeletonDB"
// import "github.com/sjsafranek/DiffDB/diff_db"

var GeoTsDB GeoTimeseriesDB

func init() {
	GeoTsDB = GeoTimeseriesDB{}
	GeoTsDB.Init()
}

type GeoTimeseriesDB struct {
	File string
	Table    string
	DB       skeleton.Database
}

func (self GeoTimeseriesDB) Init() {

	self.DB = skeleton.Database{File: self.getFile()}
	self.DB.Init()

	conn := self.DB.Connect()
	defer conn.Close()

	err := self.DB.CreateTable(conn, self.getTable())
	if nil != err {
		panic(err)
	}
}

func (self GeoTimeseriesDB) getFile() {
	if "" == self.File {
		return = "geo_ts.db"
	}
	return self.File
}

func (self GeoTimeseriesDB) getTable() {
	if "" == self.Table {
		return = "GeoTimeseriesData"
	}
	return self.Table
}

func (self GeoTimeseriesDB) Select(datasource_id) ([]byte, error) {
	data, err := self.DB.Select(self.getTable, datasource_id)
	return data, err
}

func update_timeseries_datasource(datasource_id string, value []byte) {

	update_value := string(value)
	var ddata diff_store.DiffStore
	data, err := GeoTsDB.Select(datasource_id)
	if nil != err {
		if err.Error() == "Not found" {
			// create new diffstore if key not found in database
			ddata = diff_store.NewDiffStore(datasource_id)
		} else {
			panic(err)
		}
	} else {
		ddata.Decode(data)
	}

	// update diffstore
	ddata.Update(update_value)

	// save to database
	enc, err := ddata.Encode()
	if nil != err {
		panic(err)
	}

	ddata.Name = datasource_id
	err = GeoTsDB.Save(string(ddata.Name), enc)

}
<commit_msg>fixed geots<commit_after>	package geo_skeleton

import "github.com/sjsafranek/DiffDB/diff_store"
import "github.com/sjsafranek/SkeletonDB"
// import "github.com/sjsafranek/DiffDB/diff_db"

var GeoTsDB GeoTimeseriesDB

func init() {
	GeoTsDB = GeoTimeseriesDB{}
	GeoTsDB.Init()
}

type GeoTimeseriesDB struct {
	File string
	Table    string
	DB       skeleton.Database
}

func (self GeoTimeseriesDB) Init() {

	self.DB = skeleton.Database{File: self.getFile()}
	self.DB.Init()

	conn := self.DB.Connect()
	defer conn.Close()

	err := self.DB.CreateTable(conn, self.getTable())
	if nil != err {
		panic(err)
	}
}

func (self GeoTimeseriesDB) getFile() {
	if "" == self.File {
		return "geo_ts.db"
	}
	return self.File
}

func (self GeoTimeseriesDB) getTable() {
	if "" == self.Table {
		return "GeoTimeseriesData"
	}
	return self.Table
}

func (self GeoTimeseriesDB) Select(datasource_id) ([]byte, error) {
	data, err := self.DB.Select(self.getTable, datasource_id)
	return data, err
}

func update_timeseries_datasource(datasource_id string, value []byte) {

	update_value := string(value)
	var ddata diff_store.DiffStore
	data, err := GeoTsDB.Select(datasource_id)
	if nil != err {
		if err.Error() == "Not found" {
			// create new diffstore if key not found in database
			ddata = diff_store.NewDiffStore(datasource_id)
		} else {
			panic(err)
		}
	} else {
		ddata.Decode(data)
	}

	// update diffstore
	ddata.Update(update_value)

	// save to database
	enc, err := ddata.Encode()
	if nil != err {
		panic(err)
	}

	ddata.Name = datasource_id
	err = GeoTsDB.Save(string(ddata.Name), enc)

}
<|endoftext|>


<commit_before>package hostess_test

import (
	"github.com/cbednarski/hostess"
	"testing"
)

func TestHostname(t *testing.T) {

	h := hostess.Hostname{}
	h.Domain = domain
	h.Ip = ip
	h.Enabled = enabled

	if h.Domain != domain {
		t.Errorf("Domain should be %s", domain)
	}
	if !h.Ip.Equal(ip) {
		t.Errorf("Ip should be %s", ip)
	}
	if h.Enabled != enabled {
		t.Errorf("Enabled should be %s", enabled)
	}
}

func TestFormatHostname(t *testing.T) {
	hostname := &hostess.Hostname{domain, ip, enabled, false}

	const exp_enabled = "127.0.0.1 localhost"
	if hostname.Format() != exp_enabled {
		t.Errorf(asserts, hostname.Format(), exp_enabled)
	}

	hostname.Enabled = false
	const exp_disabled = "# 127.0.0.1 localhost"
	if hostname.Format() != exp_disabled {
		t.Errorf(asserts, hostname.Format(), exp_disabled)
	}
}
<commit_msg>Added tests for Equal() EqualIp() and IsValid()<commit_after>package hostess_test

import (
	"github.com/cbednarski/hostess"
	"net"
	"testing"
)

func TestHostname(t *testing.T) {
	h := hostess.Hostname{}
	h.Domain = domain
	h.Ip = ip
	h.Enabled = enabled

	if h.Domain != domain {
		t.Errorf("Domain should be %s", domain)
	}
	if !h.Ip.Equal(ip) {
		t.Errorf("Ip should be %s", ip)
	}
	if h.Enabled != enabled {
		t.Errorf("Enabled should be %s", enabled)
	}
}

func TestEqual(t *testing.T) {
	a := hostess.NewHostname("localhost", "127.0.0.1", true)
	b := hostess.NewHostname("localhost", "127.0.0.1", false)
	c := hostess.NewHostname("localhost", "127.0.1.1", false)

	if !a.Equal(b) {
		t.Errorf("%s and %s should be equal", a, b)
	}
	if a.Equal(c) {
		t.Errorf("%s and %s should not be equal", a, c)
	}
}

func TestEqualIp(t *testing.T) {
	a := hostess.NewHostname("localhost", "127.0.0.1", true)
	c := hostess.NewHostname("localhost", "127.0.1.1", false)
	ip := net.ParseIP("127.0.0.1")

	if !a.EqualIp(ip) {
		t.Errorf("%s and %s should be equal", a.Ip, ip)
	}
	if a.EqualIp(c.Ip) {
		t.Errorf("%s and %s should not be equal", a.Ip, c.Ip)
	}
}

func TestIsValid(t *testing.T) {
	a := hostess.NewHostname("localhost", "127.0.0.1", true)
	d := hostess.NewHostname("", "127.0.0.1", true)
	e := hostess.NewHostname("localhost", "localhost", true)

	if !a.IsValid() {
		t.Errorf("%s should be a valid hostname", a)
	}
	if d.IsValid() {
		t.Errorf("%s should be invalid because the name is blank", d)
	}
	if e.IsValid() {
		t.Errorf("%s should be invalid because the ip is malformed", e)
	}
}

func TestFormatHostname(t *testing.T) {
	hostname := &hostess.Hostname{domain, ip, enabled, false}

	const exp_enabled = "127.0.0.1 localhost"
	if hostname.Format() != exp_enabled {
		t.Errorf(asserts, hostname.Format(), exp_enabled)
	}

	hostname.Enabled = false
	const exp_disabled = "# 127.0.0.1 localhost"
	if hostname.Format() != exp_disabled {
		t.Errorf(asserts, hostname.Format(), exp_disabled)
	}
}
<|endoftext|>