Fix multiple definition errors for cColor and cPixel#25
Open
Fix multiple definition errors for cColor and cPixel#25
Conversation
The global variables cColor and cPixel were declared in color.h without the extern keyword, causing multiple definition linker errors when the header was included in multiple translation units. Changes: - Add extern to declarations in color.h - Define the variables once in color.c This resolves the linker errors: multiple definition of `cColor` multiple definition of `cPixel`
This commit addresses several critical issues and modernizes the codebase: ## Bug Fixes - Remove duplicate method definitions for scale_x/scale_y in sprite.c (lines 353-356) These were redundant with lines 336-339 and could cause confusion ## Type Safety Improvements - Add type checking to all unwrap functions using mrb_data_get_ptr() - Replace unsafe DATA_PTR() casts with type-safe unwrapping - Add proper error messages with expected vs actual type information - Handle both owned and contained data types in V2 and SinCos unwrap Files updated: - vector.c, color.c, sincos.c, circle.c, aabb.c: Type-safe unwrap functions - All unwrap functions now properly validate type and provide clear error messages ## Global Variable Management - Make all class variables externally accessible via extern declarations - Add extern declarations to all headers: vector.h, sprite.h, transform.h, sincos.h, circle.h, aabb.h - Define class variables once in .c files (remove static keyword) - Consistent with existing pattern in color.h/color.c This allows other modules to reference class objects for type checking and enables better cross-module integration. Impact: - Prevents type confusion bugs at runtime - Provides clearer error messages for debugging - Enables future cross-module functionality - Follows modern mruby best practices
This commit significantly improves the developer experience by adding
Ruby-idiomatic methods and mathematical operators.
## New Ruby Methods (mrblib/)
### V2 class enhancements:
- #to_s, #inspect for debugging
- #to_a, #to_h for conversions
- #hash, #eql? for use as Hash keys
- Math operators: +, -, *, /, unary -
### New Ruby wrapper files:
- color.rb: #to_s, #inspect, #==, #hash, #eql?, #to_a, #to_h for Color & Pixel
- sprite.rb: #to_s added (inspect already existed)
- circle.rb: #to_s, #inspect
- aabb.rb: #to_s, #inspect
## C Implementation (src/vector.c)
### Math operators for V2:
- mrb_cf_v2_add: Vector addition (v1 + v2)
- mrb_cf_v2_sub: Vector subtraction (v1 - v2)
- mrb_cf_v2_mul: Scalar multiplication (v * scalar)
- mrb_cf_v2_div: Scalar division (v / scalar)
- mrb_cf_v2_neg: Unary negation (-v)
All use MRB_OPSYM for proper operator symbol definitions.
## Usage Examples
```ruby
v1 = Cute::V2.new(10, 20)
v2 = Cute::V2.new(5, 3)
# Math operations
v3 = v1 + v2 # V2(15, 23)
v4 = v1 - v2 # V2(5, 17)
v5 = v1 * 2.0 # V2(20, 40)
v6 = v1 / 2.0 # V2(5, 10)
v7 = -v1 # V2(-10, -20)
# Debugging
puts v1 # V2(10, 20)
p v1 # #<Cute::V2:0x... x=10 y=20>
# Conversions
v1.to_a # [10, 20]
v1.to_h # {x: 10, y: 20}
# Hash keys
positions = {}
positions[v1] = "player"
positions[v2] = "enemy"
# Colors
color = Cute::Color.new(1.0, 0.5, 0.0, 1.0)
puts color # Color(r=1.0, g=0.5, b=0.0, a=1.0)
color.to_a # [1.0, 0.5, 0.0, 1.0]
```
Impact:
- More intuitive API for game developers
- Better debugging with meaningful inspect/to_s
- Enables use of value types in hashes
- Natural mathematical expressions for vectors
- Consistent with Ruby conventions
Introduces a comprehensive Ruby API layer on top of existing C bindings: Drawing API: - Unified polymorphic methods (draw_circle accepts Circle or V2+radius) - Block-based transforms (with_transform) for automatic cleanup - Convenience wrappers (draw_sprite, draw_line, draw_text) Color API: - Class factory methods (Color.rgb, Color.rgba_f) - Predefined color constants (Color.red, Color.blue, etc.) - Hex color support (Color.hex) Sprite API: - Factory class methods (Sprite.demo, Sprite.defaults) - Convenience position accessors (sprite.x, sprite.y) - Fluent/chainable methods (with_position, with_scale, with_opacity) Type Safety: - Added type validation in cf_draw_sprite before DATA_PTR access Documentation: - Created API.md migration guide with examples - Updated example.rb to showcase new idiomatic API All existing C-style functions remain fully functional for backward compatibility. The Ruby layer provides a more natural, idiomatic API while maintaining complete interoperability with the C bindings.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
The global variables cColor and cPixel were declared in color.h without
the extern keyword, causing multiple definition linker errors when the
header was included in multiple translation units.
Changes:
This resolves the linker errors:
multiple definition of
cColormultiple definition of
cPixel